腐蚀膨胀的理解和底层实现(有GPU实现代码)

问题提出

最近组长让写一组技术分享,要求和嵌入式有所关联。
所以一些很基本的操作,不能仅仅说调用Opencv即可,要知道,底层没有Opencv,有的只是加减乘除或与非
简单分享腐蚀和膨胀的理解……

直观印象

一般调用时,
腐蚀多用于消除孤立点或者孤立区域;
而膨胀用于连接一些临近区域。

Opencv调用固然简单:

erode(src,dst, element_small);				
dilate(src,dst, element_big);

原理

今天偶然看到一篇文章,形态学操作:膨胀与腐蚀

其间,对这两种操作的解释是:
腐蚀是求取局部最大值的操作;
而膨胀就是求取局部最小值的操作。

仔细想了其间原理,觉得灌顶醍醐的感觉。

具体实现

局部最小、局部最大操作,在底层代码设计时,应该不是太难;
咨询了FPGA的同事,他那边的实现更加简洁:
腐蚀就是结构覆盖内元素相与操作;
膨胀则是结构覆盖内元素相或操作。

在分享一段先前用GPU写的腐蚀膨胀,(以前智商真是爆棚)

//GPU端腐蚀
__global__ void erodeInCuda(uchar *dataIn, uchar *dataOut, Size erodeElement, int imgWidth, int imgHeight)
{
	//Grid中x方向上的索引
	int xIndex = threadIdx.x + blockIdx.x * blockDim.x;
	//Grid中y方向上的索引
	int yIndex = threadIdx.y + blockIdx.y * blockDim.y;

	int elementWidth = erodeElement.width;
	int elementHeight = erodeElement.height;
	int halfEW = elementWidth / 2;
	int halfEH = elementHeight / 2;
	//初始化输出图
	dataOut[yIndex * imgWidth + xIndex] = dataIn[yIndex * imgWidth + xIndex];;
	//防止越界
	if (xIndex + elementWidth  > halfEW  && xIndex - elementWidth < imgWidth - halfEW + halfEH  && yIndex + elementHeight > halfEH && yIndex - elementHeight < imgHeight - halfEH)
	{

		for (int i = -halfEH; i < halfEH + 1; i++)
		{
			for (int j = -halfEW; j < halfEW + 1; j++)
			{
				if (dataIn[(i + yIndex) * imgWidth + xIndex + j] < dataOut[yIndex * imgWidth + xIndex])
				{
					dataOut[yIndex * imgWidth + xIndex] = dataIn[(i + yIndex) * imgWidth + xIndex + j];
				}
			}
		}
	}
}


//GPU端膨胀
__global__ void dilateInCuda(uchar *dataIn, uchar *dataOut, Size dilateElement, int imgWidth, int imgHeight)
{
	//Grid中x方向上的索引
	int xIndex = threadIdx.x + blockIdx.x * blockDim.x;
	//Grid中y方向上的索引
	int yIndex = threadIdx.y + blockIdx.y * blockDim.y;

	int elementWidth = dilateElement.width;
	int elementHeight = dilateElement.height;
	int halfEW = elementWidth / 2;
	int halfEH = elementHeight / 2;
	//初始化输出图
	dataOut[yIndex * imgWidth + xIndex] = dataIn[yIndex * imgWidth + xIndex];;
	//防止越界
	if (xIndex + elementWidth  > halfEW  && xIndex - elementWidth < imgWidth - halfEW + halfEH  && yIndex + elementHeight > halfEH && yIndex - elementHeight < imgHeight - halfEH)
	{
		for (int i = -halfEH; i < halfEH + 1; i++)
		{
			for (int j = -halfEW; j < halfEW + 1; j++)
			{
				if (dataIn[(i + yIndex) * imgWidth + xIndex + j] > dataOut[yIndex * imgWidth + xIndex])
				{
					dataOut[yIndex * imgWidth + xIndex] = dataIn[(i + yIndex) * imgWidth + xIndex + j];
				}
			}
		}
	}
}

你可能感兴趣的:(C++,Opencv)