用C语言实现图像的膨胀与腐蚀算法
经过几次学习opencv源代码,我决定自己动手写一下膨胀与腐蚀算法,如果具体算法原理不明确的话,可以看看前几篇我总结的膨胀腐蚀算法原理:
腐蚀算法
/*****************************************************
function: achieve the erode algorithm of the binary image,using 3*3 structural elements
parameter:
1 IplImage* img : original image
2 int *elementArray : 3*3 structural elements
return: Run code 0: right -1: error
*****************************************************/
//在画图中 理解有中心点的位置,并将结果赋给结构元素中心点所对应的位置,但是在实际的编程中是遍历每一个点(i,j),可以理解为对应结构元素的中心点
int ErodeYang01(IplImage* srcImg, IplImage* dstImg, int *elementArray)
{
int ret = 0;
int imgHeight, imgWidth;
int i, j, k, l;
int rowPosi, colPosi; //为结构元素在计算图像中的位置 rowPosi:行 colPosi:列
bool isMatch;
if (srcImg == NULL || elementArray == NULL)
return ret = -1;
imgHeight = srcImg->height;
imgWidth = srcImg->width;
memset((void*)dstImg->imageData, 0, dstImg->imageSize); // memset((void*)dstImg->imageData, 255, dstImg->imageSize);
for (i = 1; i < imgHeight; i++) //i,j 都从1开始 是防止逐行扫描时,访问越界,四周留出一个像素的宽度
{
for (j = 1; j < imgWidth; j++)
{
isMatch = true;
for (k = 0; k < 3; k++) //k,l 为结构元素的遍历
{
for (l = 0; l < 3; l++)
{
rowPosi = (i - 1 + k)*srcImg->widthStep;
colPosi = j - 1 + l;
if (elementArray[3 * k + l] == -1) //此点不关心
continue;
if (elementArray[3 * k + l] == 1) //前景
{
if (srcImg->imageData[rowPosi + colPosi] != -1) //opencv中 二值化图结果只是存放了 0 与 -1 但正常理解二值化值应该 0与1 或是 0与255
{
isMatch = false;
break;
}
}
else
{
printf("structural elements exist illegal values");
return ret = -1;
}
}
}
if (isMatch)
dstImg->imageData[i*dstImg->widthStep + j] = 255; //赋值为图像中位置点
}
}
return ret;
}
膨胀算法
/*****************************************************
function: achieve the dilate algorithm of the binary image,using 3*3 structural elements
parameter:
1 IplImage* img : original image
2 int *elementArray : 3*3 structural elements
return: Run code 0: right -1: error
*****************************************************/
int DilateYang(IplImage* img, IplImage* dstImg, int *elementArray /* elementArray[3][3] */)
{
int ret = 0;
int imgHeight, imgWidth;
int i, j; //图像循环变量
int i_, j_; //结构元素的对称集循环变量
int k, l; //结构元素循环变量
uchar temp;
bool isMatch;
if (img == NULL || elementArray == NULL)
return ret = -1;
imgHeight = img->height;
imgWidth = img->width;
memset((void*)dstImg->imageData,0,dstImg->imageSize); //这是模仿程序写的 没确定是否正确 初始化整幅图都是白色
//计算结构元素的对称集 --算法中是利用结构元素的对称集进行后续处理的
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3 - i; j++)
{
temp = elementArray[i * 3 + j];
elementArray[i * 3 + j] = elementArray[(2 - i) * 3 + (2 - j)];
elementArray[(2 - i) * 3 + (2 - j)] = temp;
}
}
for (i = 1; i < imgHeight; i++)
{
for (j = 1; j < imgWidth; j++)
{
for (k = 0; k < 3; k++)
{
for (l = 0; l < 3; l++)
{
int rowImg = (i - 1 + k)*img->widthStep;
int colImg = j - l + 1;
if (elementArray[k * 3 + l] == -1)
continue;
if (elementArray[k * 3 + l] == 1)
{
//if(img->imageData[rowImg + colImg] != 0)
// printf("%d", img->imageData[rowImg + colImg]);
if (img->imageData[rowImg + colImg] == -1) //opencv中 二值化图结果只是存放了 0 与 -1
{
dstImg->imageData[i*dstImg->widthStep + j] = 255;
break;
}
}
else
{
printf("structural elements exist illegal values");
return ret = -1;
}
}
}
}
}
return ret;
}