话不多收,注释写的很详细,直接上代码
待提取边缘原图如下
//sobel算子
{
Mat image = imread("D:/IInclude/opencv/images/hist_01.jpg");
Mat resx, resy, rest;
int dx1 = 2, dy1=0, dsize1=1;
int dx2 = 0, dy2=1, dsize2=3;
//这三者的关系是任意一个方向的差分阶数都需要小于滤波器的尺寸,特殊情况是dsize=1时,任意一个方向的阶数都要小于3
// 一般情况下,查分阶数的最大值为1时,滤波尺寸选3,查分阶数为2时,滤波尺寸选5,查分阶数为3时,滤波尺寸选7
//当dsize=1时,程序尺寸不再为方形,为1*3或3*1的矩形
Sobel(image, resx, CV_16S, 2, 0, 1);//x方向一阶边缘
Sobel(image, resy, CV_16S, 0, 1, 3);//y方向的一阶边缘
convertScaleAbs(resx, resx);
convertScaleAbs(resy, resy);
rest = resx + resy;
imshow("sobel", rest);
}
提取结果
//prewitt算子
void getPrewitt_oper(Mat& getPrewitt_horizontal, Mat& getPrewitt_vertical, Mat& getPrewitt_Diagonal1, Mat& getPrewitt_Diagonal2) {
//水平方向
getPrewitt_horizontal = (Mat_<float>(3, 3) << -1, -1, -1, 0, 0, 0, 1, 1, 1);
//垂直方向
getPrewitt_vertical = (Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
//对角135°
getPrewitt_Diagonal1 = (Mat_<float>(3, 3) << 0, 1, 1, -1, 0, 1, -1, -1, 0);
//对角45°
getPrewitt_Diagonal2 = (Mat_<float>(3, 3) << -1, -1, 0, -1, 0, 1, 0, 1, 1);
//逆时针反转180°得到卷积核
flip(getPrewitt_horizontal, getPrewitt_horizontal, -1);
flip(getPrewitt_vertical, getPrewitt_vertical, -1);
flip(getPrewitt_Diagonal1, getPrewitt_Diagonal1, -1);
flip(getPrewitt_Diagonal2, getPrewitt_Diagonal2, -1);
}
void edge_Prewitt(Mat& src, Mat& dst1, Mat& dst2, Mat& dst3, Mat& dst4, Mat& dst, int ddepth, double delta = 0, int borderType = BORDER_DEFAULT) {
//获取Prewitt算子
Mat getPrewitt_horizontal;
Mat getPrewitt_vertical;
Mat getPrewitt_Diagonal1;
Mat getPrewitt_Diagonal2;
getPrewitt_oper(getPrewitt_horizontal, getPrewitt_vertical, getPrewitt_Diagonal1, getPrewitt_Diagonal2);
//卷积得到水平方向边缘
filter2D(src, dst1, ddepth, getPrewitt_horizontal, cv::Point(-1, -1), delta, borderType);
//卷积得到4垂直方向边缘
filter2D(src, dst2, ddepth, getPrewitt_vertical, cv::Point(-1, -1), delta, borderType);
//卷积得到45°方向边缘
filter2D(src, dst3, ddepth, getPrewitt_Diagonal1, cv::Point(-1, -1), delta, borderType);
//卷积得到135°方向边缘
filter2D(src, dst4, ddepth, getPrewitt_Diagonal2, cv::Point(-1, -1), delta, borderType);
//边缘强度(近似)
convertScaleAbs(dst1, dst1); //求绝对值并转为无符号8位图
convertScaleAbs(dst2, dst2);
convertScaleAbs(dst3, dst3); //求绝对值并转为无符号8位图
convertScaleAbs(dst4, dst4);
dst = dst1 + dst2;
}
int mian(){
Mat image = imread("D:/IInclude/opencv/images/hist_01.jpg");
Mat dst, dst1, dst2, dst3, dst4;
edge_Prewitt(image, dst1, dst2, dst3, dst4, dst, CV_32F);
imshow("边缘强度prewitt", dst);
waitKey(0);
}
提取结果
//loG算子
{
if (image.channels() > 1)
cvtColor(image, image, COLOR_RGB2GRAY);
Mat dst;
Mat gaussian_dst1, gaussian_dst2;
//高斯滤波
double sigma = 2, k = 1.6;
GaussianBlur(image, gaussian_dst1, Size(7, 7) ,k * sigma);
GaussianBlur(image, gaussian_dst2, Size(7, 7), sigma);
dst = gaussian_dst1 - gaussian_dst2;
threshold(dst, dst, 0, 255, THRESH_BINARY);
imshow("loG算子", dst);
}
提取结果