sponsored links

实现图像的膨胀与腐蚀算法


用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;
}
Tags: