我的SSE图像优化算法1.图像取反

SSE指令一次性能同时处理128位即16个字节型数据,8个short类型的,或者4个int类型数据(128=16×8=8×2×8=4×4×8)
一个字节=8位=255。
取反是对灰度图像取反,所以默认一个像素是一个字节,(如果是彩色24位的图像,24位=3个字节,(5×3+1)×8=128,128位包含5+1/3个像素信息,具体处理办法下篇文章再谈)。SSE代码部分能同时处理16个像素,从上到下,从左到右依次处理,每行余下的不能被16整除的像素则由C++代码进行处理。
以下分别是SSE代码和C++代码:

void IM_Invert_SSE(cv::Mat InImg, cv::Mat& OutImg)
{
	unsigned char *Src= InImg.data;
	unsigned char *Dst = OutImg.data;
	int Width = InImg.cols;
	int Height = InImg.rows;
	const int BlockSize = 16;
	int Block = Width / BlockSize;
	for (int Y = 0; Y < Height; Y++)
	{
		unsigned char *LinePS = Src + Y * Width;
		unsigned char *LinePD = Dst + Y * Width;
		for (int X = 0; X < Block * BlockSize; X += BlockSize, LinePS += BlockSize, LinePD += BlockSize)
		{
			__m128i Src, Result;
			Src = _mm_loadu_si128((__m128i *)(LinePS + 0));
			Result = _mm_andnot_si128(Src, _mm_set1_epi8(255));
			_mm_storeu_si128((__m128i*)(LinePD), Result);
		}
		for (int X = Block * BlockSize; X < Width; X++, LinePS ++, LinePD++)
		{
			LinePD[0] = 255- LinePS[0];
		}
	}
}
void IM_Invert(cv::Mat InImg, cv::Mat& OutImg)
{
	unsigned char *Src = InImg.data;
	unsigned char *Dst = OutImg.data;
	int Width = InImg.cols;
	int Height = InImg.rows;
	const int BlockSize = 16;
	int Block = Width / BlockSize;
	for (int Y = 0; Y < Height; Y++)
	{
		unsigned char *LinePS = Src + Y * Width;
		unsigned char *LinePD = Dst + Y * Width;
		for (int X = 0; X < Width; X++, LinePS++, LinePD++)
		{
			LinePD[0] = 255 - LinePS[0];
		}
	}
}

这里选用犬子2160×2160的照片作为实验图像
原图:
在这里插入图片描述
灰度图这里就不放了(无意打开,有怪莫怪,但愿人没事,奠奠奠)。
灰度图二值化后:
在这里插入图片描述
取反后的图:
在这里插入图片描述
实验结果:在这里插入图片描述
如图可见在64位debug模式下,SSE优化后,对于2160×2160的图,取反的速度比纯C++代码快了5倍多。

猜你喜欢

转载自blog.csdn.net/weixin_44302212/article/details/107560104
今日推荐