C++ 實現 語義分割 deeplab_v3

https://github.com/tensorflow/models/blob/master/research/deeplab/g3doc/model_zoo.md

中有許多個模型。

先下一個試試效果如何:
http://download.tensorflow.org/models/deeplabv3_mnv2_dm05_pascal_trainaug_2018_10_01.tar.gz

由於
我的Tensoflow是1.0版。不能直接運行,先把模型編輯一下,去掉

     “Conv2D”的屬性“dilations”和“data_format”

     以及“Cast”的屬性“Truncate”

     “ArgMax”的屬性“output_type”,然後就可以運行了。


模型中的空洞卷積是用SpaceToBatchND 和 BatchToSpaceND,先要用C++實現這兩個函數

1。SpaceToBatchND 函數:

//四維 pad1(左、上補邊),pad2(右、下補邊)
張量 * SpaceToBatchND(張量 &in,int block_shape,int pad1,int pad2)
{

	張量* out= new張量(in.num);
	out->value=new int[out->num];
//	//批,高,寬,通道 N,H,W,C
	//輸入四維[b, h, w, c], padding後[b, new_h, new_w, c]
	//x = np.pad(out_in, ((0,0), (4,7),(4,7), (0,0)), 'constant') // from shape (1, 2, 2, 1) to (1, 6, 6, 1)
	//x_shape=x.shape
	//b     = x_shape[0]
	//new_h = x_shape[1]
	//new_w = x_shape[2]
	//c     = x_shape[3]

	//批,通道,高,寬 N,C,H,W
	//補邊
	for(int i=0;i<in.num;i++)
	{
		out->value[i]=in.value[i];
	}
	int in_w=in.value[3];
	int new_w=in_w+pad1+pad2;
	int new_h=in.value[2]+pad1+pad2;
	out->value[3]=new_w;
	out->value[2]=new_h;
	out->data=new float[out->size()];
	//複製內容
	張量清零(*out);
	float *s=in.data;
	float *d=out->data+pad1;//跳過左邊
	for(int i=0;i<in.value[0];++i)//N
	{
		for(int j=0;j<in.value[1];++j)//C
		{
			d += pad1*new_w;//跳過上面
			for(int j=0;j<in.value[2];++j)//H
			{
					cblas_scopy(in_w, s, 1, d, 1);
					s+=in_w;
					d+=new_w;
			}
			d+=pad2*new_w;//跳過下邊
		}
	}

	int b=out->value[0];
	int c=out->value[1];
	int dilation=block_shape;
	//h_dilation=int(new_h / dilation)
	int h_dilation=new_h / dilation;
	//w_dilation=int(new_w / dilation)
	int w_dilation=new_w / dilation;

		//reshape維度爲[b, new_h / dilation_h, dilation_h, new_w / dilation_w, dilation_w, c].
	//y = np.reshape(x, (b, h_dilation, dilation, w_dilation, dilation, c))
	//B, C, h_dilation, dilation, w_dilation, dilation
	view(*out,b,c,h_dilation, dilation, w_dilation, dilation);

	//轉置爲[dilation_h, dilation_w, b, new_h / dilation_h, new_w / dilation_w, c].
	//z = np.transpose(y, (2, 4, 0, 1, 3, 5))

	//B, C, h_dilation, dilation, w_dilation, dilation
	//dilation_h, dilation_w, B, C, new_h / dilation_h, new_w / dilation_w
	張量 * z= permute(*out,3, 5, 0, 1, 2, 4);

	//reshape, 維度爲[b x dilation_h x dilation_w, new_h / dilation_h, new_w / dilation_w, c] 
	//r = np.reshape(z, (b * dilation * dilation, h_dilation, w_dilation, c))
	//B * dilation * dilation, C, h_dilation, w_dilation
	view(*z,b * dilation * dilation, c, h_dilation, w_dilation);//block_shape);

	return z;
}

2。BatchToSpaceND 函數:

//四維 crop1(左、上裁剪),crop2(右、下裁剪)
張量 * BatchToSpaceND(張量 &in,int block_shape,int crop1,int crop2)
{
	int dilation=block_shape;
//	b     = int(x_shape[0]/(dilation * dilation))
	int b=in.value[0]/(dilation * dilation);
//	c     = x_shape[3]
	int c=in.value[1];
	int h=in.value[2];
	int w=in.value[3];

//#	重塑 input 爲 reshaped 
//	r = np.reshape(out_in, (dilation, dilation, b, h, w, c))
	view(in,dilation, dilation, b, c, h, w);

//#	重塑 permuted 以產生 reshaped_permuted 的形狀 
//	#(dilation, dilation, b, h, w, c)
//	#(b, h_dilation, dilation, w_dilation, dilation, c)
//	z = np.transpose(r, (2, 3, 0, 4, 1, 5))
	//(b, c, h, dilation, w, dilation)
	張量 * z = permute(in,2, 3, 4, 0, 5, 1);
//#	h_dilation=int(new_h / dilation)
//	new_h=h*dilation
	int new_h=h*dilation;
//#	w_dilation=int(new_w / dilation)
//	new_w=w*dilation
	int new_w=w*dilation;

//	#b, h_dilation, dilation, w_dilation, dilation, c
//	#b,h,w,c
//	y = np.reshape(z, (b, new_h, new_w, c))
	view(*z,b, c, new_h, new_w);

//#	裁剪尺寸的開始和結束
//	x = y[:, 0:new_h-3,0:new_w-3,:]
	張量 * out=裁剪(z,crop1,crop2);


	return out;
}

就差不多了。

看一下效果如何:

輸入圖5.jpg

運行截圖

5_背景_自行車_人.jpg

5-分割疊加.jpg

這個可以識別21類物體

再看幾張

下載:

win圖像語義分割deeplab-v3程序

win圖像語義分割實用程序,由《model_zoo.md》中的模型《mobilenetv2_dm05_coco_voc_trainaug》改編而成。

https://download.csdn.net/download/juebai123/12160594

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章