最近组长让写一组技术分享,要求和嵌入式有所关联。
所以一些很基本的操作,不能仅仅说调用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];
}
}
}
}
}