经典图像二值分割的SSE加速实现

对于图像处理稍微理解的同学来说,二值分割时入门时最简单的算法。

g(x,y)=\left\{\begin{matrix} 255 & minThr<f(xy)<maxThr \\ 0& else \end{matrix}\right.

opencv 实现的很简单:

灰度处理后就可以二值化了,这是方便图像处理的重要步骤,但貌似不适合对颜色有要求的图像处理,对轮廓有要求的比较有效。

函数是这个:CVAPI(double)  cvThreshold( const CvArr*  src, CvArr*  dst,
                            double  threshold, double  max_value,
                            int threshold_type );

threshold是阀值,max_value取值255最大值

threshold_type:就是显示的轮廓会有不同

/* Types of thresholding */
#define CV_THRESH_BINARY      0  /* value = value > threshold ? max_value : 0       */
#define CV_THRESH_BINARY_INV  1  /* value = value > threshold ? 0 : max_value       */
#define CV_THRESH_TRUNC       2  /* value = value > threshold ? threshold : value   */
#define CV_THRESH_TOZERO      3  /* value = value > threshold ? value : 0           */
#define CV_THRESH_TOZERO_INV  4  /* value = value > threshold ? 0 : value           */
#define CV_THRESH_MASK        7

 

在halcon中阈值分割之后,生成了一个region,这个是和opencv有区别的。

threshold(Image : Region : MinGray, MaxGray : )

这些都不是重要的,重要在下边,通过sse的指令化操作可以很快的实现上面的原理:

void threshold_imageSSE(unsigned char *Src, unsigned char *Dest, int Width, int Height, int Stride, int minThr, int maxThr)
{
	int channles = Stride / Width;
	int blocksize = 16;
	int block = Height*Width*channles / 16;
	for (int i = 0; i < blocksize*block; i+= blocksize)
	{
		__m128i inputImage1 = _mm_cvtepu8_epi16( _mm_loadu_si128((__m128i*)(Src + i)));
		__m128i inputImage2 = _mm_cvtepu8_epi16(_mm_loadu_si128((__m128i*)(Src + i+8)));

		__m128i minthr = _mm_set1_epi16(minThr);
		__m128i maxthr = _mm_set1_epi16(maxThr);
		
		__m128i temp1 = _mm_cmpgt_epi16(inputImage1, minthr);
		__m128i temp2 = _mm_cmpgt_epi16(inputImage2, minthr);

		__m128i temp3 = _mm_cmplt_epi16(inputImage1, maxthr);
		__m128i temp4 = _mm_cmplt_epi16(inputImage2, maxthr);

		__m128i temp5 = _mm_cmpeq_epi16(temp1, temp3);
		__m128i temp6 = _mm_cmpeq_epi16(temp2, temp4);

		__m128i dst = _mm_packs_epi16(temp5, temp6);

		_mm_storeu_si128((__m128i*)(Dest + i), dst);

	}
	for (int j = blocksize*block; j < Height*Width*channles; j++)
	{
		if (Src[j] > minThr && Src[j] < maxThr)
		{
			Dest[j] = 255;
		}
		else
		{
			Dest[j] = 0;
		}
	}
}

 在上面没有怎么注释,总的思路就是  f(x,y) >minThr ?  0xffff :0x0     f(x,y) <maxThr ?  0xffff :0x0         a = b?  0xffff :0x0

核心的思路就是上面所说。

最后的实际效果,两千万像素单通道的图片,1000次的计算,平均速度为4.3ms左右。如果没有用sse的话,速度测试是30ms左右。

 

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值