Sobel算子原理及其C/C++代码实现

Sobel算子,也叫Sobel-Feldman算子或Sobel滤波,常用于图像处理领域中的边缘检测。用学术的语言来说,它是一种离散的微分算子,用于计算图像亮度的梯度近似值。简单来说,Sobel算子可看作为一种固定的滤波核,对整幅图进行滤波操作。

Sobel算子分为水平方向和垂直方向,两者不一样,分别记为Gx和Gy,则Gx和Gy的值如下所示:

Gx =\begin{bmatrix} -1 & 0 & +1 \\ -2 & 0 &+2\\ -1& 0& +1 \end{bmatrix} \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Gy = \begin{bmatrix} +1 & +2 & +1\\ 0 & 0 & 0\\ -1& -2& -1 \end{bmatrix}

假设输入图像A,A图像如下所示:

Sobel算子原理及其C/C++代码实现_第1张图片

以图像A中的像素值为12的点为例,则该点水平方向和垂直方向的Sobel运算结果分别记为Px和Py,则运算过程如下所示:

Px = \begin{bmatrix} 21 &125 &250 \\ 33 &12 &202 \\ 124& 55 &231 \end{bmatrix} \otimes Gx = \begin{bmatrix} 21 &125 &250 \\ 33 &12 &202 \\ 124& 55 &231 \end{bmatrix} \otimes \begin{bmatrix} -1&0&+1\\ -2&0&+2\\ -1& -&+1\end{bmatrix}

Py = \begin{bmatrix} 21 &125 &250 \\ 33 &12 &202 \\ 124& 55 &231 \end{bmatrix} \otimes Gy = \begin{bmatrix} 21 &125 &250 \\ 33 &12 &202 \\ 124& 55 &231 \end{bmatrix} \otimes \begin{bmatrix} +1&+2&+1\\ 0&0&0\\ -1& -2&-1\end{bmatrix}

OpenCV中代码实现及其调用格式如下:

    Mat src = imread("../ORB_DBoW2/lenna.jpg", 0);
    imshow("src", src);
    cvWaitKey(0);

    Mat gx, gy;
    Sobel(src, gx, CV_16S, 1, 0);
    Sobel(src, gy, CV_16S, 0, 1);

    convertScaleAbs(gx, gx);
    imshow("gx", gx);
    cvWaitKey(0);

    convertScaleAbs(gy, gy);
    imshow("gy", gy);
    cvWaitKey(0);

OpenCV的效果如下图所示:

Sobel算子原理及其C/C++代码实现_第2张图片

C语言实现的代码如下:

int ComputerSobel(unsigned char *pSrc, int nWidth, int nHeight, int nChannel, short *pSobelX, short *pSobelY)
{
    int nRow, nCol, nVer, nHor, nSumX, nSumY, nIndex;
    const int nKernelSize = 3;
    int nHalfKernel = nKernelSize / 2;
    int nCentKernel = nKernelSize * nKernelSize / 2;
    /*水平方向和垂直方向的核*/
    int pKernelX[nKernelSize * nKernelSize] = { -1, 0, 1, -2, 0, 2, -1, 0, 1};
    int pKernelY[nKernelSize * nKernelSize] = { -1, -2, -1, 0, 0, 0, 1, 2, 1};
    if (NULL == pSrc || 1 != nChannel)
    {
        return -1;
    }
    if (NULL != pSobelX)
    {
        memset(pSobelX, 0, sizeof(short) * nHeight * nWidth);
    }
    if (NULL != pSobelY)
    {
        memset(pSobelY, 0, sizeof(short) * nHeight * nWidth);
    }
    /*计算sobel算子结果*/
    for (nRow = 1; nRow < nHeight - 1; nRow++)
    {
        for (nCol = 1; nCol < nWidth - 1; nCol++)
        {
            nSumX = 0;
            nSumY = 0;
            for (nVer = -nHalfKernel; nVer < nHalfKernel + 1; nVer++)
            {
                for (nHor = -nHalfKernel; nHor < nHalfKernel + 1; nHor++)
                {
                    nIndex = (nRow + nVer) * nWidth + nCol + nHor;
                    nSumX += pSrc[nIndex] * pKernelX[nVer * nKernelSize + nCentKernel + nHor];
                    nSumY += pSrc[nIndex] * pKernelY[nVer * nKernelSize + nCentKernel + nHor];
                }
            }
            nIndex = nRow * nWidth + nCol;
            if (NULL != pSobelX)
            {
                pSobelX[nIndex] = nSumX;
            }
            if (NULL != pSobelY)
            {
                pSobelY[nIndex] = nSumY;
            }
        }
    }
    return 0;
}

Sobel算子原理及其C/C++代码实现_第3张图片

 

 

你可能感兴趣的:(图像处理,编程语言,C/C++)