sobel
原理比较简单,参照这个博客
流程上就是一张灰度图片分别进行两次卷积,然后将两次卷积后的图片合在一起
#include <iostream>
#include<opencv2/opencv.hpp>
#include <string>
using namespace std;
using namespace cv;
void conv(char *G, Mat pic, Mat &res)
{
int i, j, i1, j1;
int tmp;
for (i = 1; i < pic.rows-1; i++)
{
for (j = 1; j < pic.cols - 1; j++)
{
tmp = 0;
for (i1 = -1; i1 <= 1; i1++)
{
for (j1 = -1; j1 <= 1; j1++)
{
tmp += pic.at<uchar>(i + i1, j + j1)*G[(j1 + 1) * 3 + i1 + 1];
}
}
res.at<short>(i, j) = tmp;
}
}
}
void merge1(Mat resX, Mat resY, Mat &res)
{
int tmp;
for (int i = 0; i < res.rows; i++)
{
for (int j = 0; j < res.cols; j++)
{
tmp = abs(resX.at<short>(i, j)) + abs(resY.at<short>(i, j));
//tmp = sqrt(resX.at<short>(i, j)*resX.at<short>(i, j) + resY.at<short>(i, j)*resY.at<short>(i, j));
if (tmp > 255)
tmp = 255;
res.at<uchar>(i,j) = tmp;
}
}
}
int main()
{
char Gx[3 * 3] = { -1, 0, 1,
-2, 0, 2,
-1, 0, 1 };
char Gy[3 * 3] = { 1, 2, 1,
0, 0, 0,
-1, -2, -1 };
Mat pic = imread("C:\\Users\\Thinkpad\\Desktop\\c++work\\pic\\lena.jpg", 0);
Mat resX = Mat::zeros(pic.rows, pic.cols, CV_16SC1);
Mat resY = Mat::zeros(pic.rows, pic.cols, CV_16SC1);
conv(Gx, pic, resX);
conv(Gy, pic, resY);
Mat res = Mat::zeros(pic.rows, pic.cols, CV_8UC1);
merge1(resX, resY, res);
//imwrite("C:\\Users\\Thinkpad\\Desktop\\c++work\\pic\\lena1.jpg", res);
imshow("1", res);
waitKey();
return 0;
}