C++实现sobel

**c++实现sobe**l
我准备用c++将常用的图像处理算法都写一遍,加深理解,并且训练自己写代码的思路。今天就从最简单的图像处理算法开始写起!
sobel 是一种边缘检测算子,有x和y方向的3*3的模板。sobel原理还是很简单的,但是写代码的时候要注意几个细节问题。

#include
#include
#include
using namespace cv;
using namespace std;

int xGradient(Mat img, int x, int y);
int yGradient(Mat img, int x, int y);

int main()
{
    int Gx, Gy, sum;
    Mat img = imread("1.jpg", 0);
    Mat dst = img.clone();
    if(!img.data)
        return -1;

    for ( int y = 0; y < img.rows; y++)
    {
        for( int x = 0; x < img.cols; x++)
        {
            dst.at(y,x) = 0.0;
        }
    }

    for ( int y = 1; y < img.rows - 1; y++ )
    {
        for ( int x = 1; x < img.cols - 1 ; x++ )//错误原因,-1忘了,所以维数不匹配
        {
            Gx = xGradient(img, x, y);
            Gy = yGradient(img, x, y);
            sum = abs(Gx) + abs(Gy);
            sum = sum > 255 ? 255 : sum;
            sum = sum < 0 ? 0 : sum;
            dst.at(y,x) = sum;
        }
    }

    imshow("final",dst);
    waitKey(0);
    return 0;

}

int xGradient(Mat image, int x, int y)
{
    int gx;
    gx = image.at(y-1,x+1) + 2*image.at(y,x+1) + image.at(y+1,x+1)
         - image.at(y-1,x-1) - 2*image.at(y,x-1) -image.at(y-1,x-1);
    return gx;
}
int yGradient(Mat image, int x, int y)
{
    int gy;
    gy = image.at(y-1,x+1) + 2*image.at(y-1,x) + image.at(y+1,x+1)
         - image.at(y-1,x-1) - 2*image.at(y+1,x) -image.at(y-1,x-1);
    return gy;
}

在这里用到了opencv里的常用函数。
1. 在opencv里,图像的坐标系是以左上角为原点,水平向右为x轴,竖直向下为y轴,也就是说img.rows其实是Y轴方向,img.cols是x轴方向。在使用img.at(y,x)应该这样表达。
2. 在进行卷积的时候,要记得将边缘像素空出,不然会出现维数不合的错误。

sobel的算法思路还是很简单的,要注意的就是细致!

你可能感兴趣的:(图像处理)