前言
这是我《OpenCV:从零到一》专栏的第十四篇博客,想看跟多请戳这。
本文概要
Scharr
Sobel
Laplacian
Canny
threshold
convertScaleAbs
Scharr滤波器、Sobel算子、Laplacian算子、Canny算子的区别
算子、滤波器、卷积核三者的区别
案例代码
大概内容:Scharr滤波器、Sobel算子、Laplacian算子、Canny算子 。
#include
#include
#include
using namespace cv;
Mat src, gray_src, dst;
int t1_value = 50;
int max_value = 255;
void Canny_Demo(int, void*);
int main(int argc, char** argv) {
src = imread("D://86186//Documents//opencv//lena.jpg");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
imshow("src", src);
//-----------------Sobel和Schar------------------------//
GaussianBlur(src, dst, Size(3, 3), 0, 0);
cvtColor(dst, gray_src, COLOR_BGR2GRAY);
imshow("gray image", gray_src);
Mat xgrad, ygrad;
Scharr(gray_src, xgrad, CV_16S, 1, 0);
Scharr(gray_src, ygrad, CV_16S, 0, 1);
// Sobel(gray_src, xgrad, CV_16S, 1, 0, 3);
// Sobel(gray_src, ygrad, CV_16S, 0, 1, 3);
convertScaleAbs(xgrad, xgrad);
convertScaleAbs(ygrad, ygrad);
imshow("Soble xgrad", xgrad);
imshow("Soble ygrad", ygrad);
Mat xygrad = Mat(xgrad.size(), xgrad.type());
printf("type : %d\n", xgrad.type());
int width = xgrad.cols;
int height = ygrad.rows;
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
int xg = xgrad.at<uchar>(row, col);
int yg = ygrad.at<uchar>(row, col);
int xy = xg + yg;
xygrad.at<uchar>(row, col) = saturate_cast<uchar>(xy);
}
}
//addWeighted(xgrad, 0.5, ygrad, 0.5, 0, xygrad);
imshow("Soble xygrad", xygrad);
//-----------------Laplancce---------------------//
Mat edge_image;
GaussianBlur(src, dst, Size(3, 3), 0, 0);
cvtColor(dst, gray_src, COLOR_BGR2GRAY);
Laplacian(gray_src, edge_image, CV_16S, 3);
convertScaleAbs(edge_image, edge_image);
threshold(edge_image, edge_image, 0, 255, THRESH_OTSU | THRESH_BINARY);
imshow("edge_image", edge_image);
//-----------------Canny---------------------//
cvtColor(src, gray_src, COLOR_BGR2GRAY);
createTrackbar("Threshold Value:", "Canny", &t1_value, max_value, Canny_Demo);
Canny_Demo(0, 0);
waitKey(0);
return 0;
}
void Canny_Demo(int, void*) {
Mat edge_output;
blur(gray_src, gray_src, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
Canny(gray_src, edge_output, t1_value, t1_value * 2, 3, false);
//bitwise_not(edge_output, edge_output);
imshow("Canny", ~edge_output);//波浪号的作用是整个图像取反,相当于bitwise_not()
}
运行效果:
解析及注意事项
全注释代码
#include
#include
#include
using namespace cv;
Mat src, gray_src, dst;
int t1_value = 50 ;
int max_value = 255;
void Canny_Demo(int, void*);
int main(int argc, char** argv) {
src = imread("D://86186//Documents//opencv//lena.jpg");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
//imshow("src", src);
//-------------------Schar------------------------//
cvtColor(src, gray_src, COLOR_BGR2GRAY);
GaussianBlur(gray_src, dst, Size(3, 3), 0, 0);
//imshow("gray image", gray_src);
Mat xgrad, ygrad, xgrad2, ygrad2;
Scharr(dst, xgrad, CV_16S, 1, 0);//S->signed
//Scharr(src,dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT)
Scharr(dst, ygrad, CV_16S, 0, 1);//dx 和 dy 分别是x方向和y方向上的阶数
convertScaleAbs(xgrad, xgrad);//convertScaleAbs (InputArray src, OutputArray dst, double alpha=1, double beta=0)
convertScaleAbs(ygrad, ygrad);//On each element of the input array conversion to an unsigned 8-bit type:
//imshow("Scharr Xgrad", xgrad);
//imshow("Scharr Ygrad", ygrad);
//合并两个方向
Mat xygrad = Mat(xgrad.size(), xgrad.type());
//printf("type : %d\n", xgrad.type());
int width = xgrad.cols;
int height = ygrad.rows;
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
int xg = xgrad.at<uchar>(row, col);
int yg = ygrad.at<uchar>(row, col);
int xy = xg + yg;
xygrad.at<uchar>(row, col) = saturate_cast<uchar>(xy);
}
}
imshow("Scharr XYgrad", xygrad);
//-------------------Sobel------------------------//
Sobel(gray_src, xgrad2, CV_16S, 1, 0,3);
// Sobel(InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT)
Sobel(gray_src, ygrad2, CV_16S, 0, 1,3);
convertScaleAbs(xgrad2, xgrad2);
convertScaleAbs(ygrad2, ygrad2);
//imshow("Soble Xgrad2", xgrad2);
//imshow("Soble Ygrad2", ygrad2);
Mat xygrad2 = Mat(xgrad2.size(), xgrad2.type());
addWeighted(xgrad2, 0.5, ygrad2, 0.5, 0, xygrad2);
imshow("Sobel XYgrad", xygrad2);
//-----------------Laplancce---------------------//
Mat edge_image;
GaussianBlur(src, dst, Size(3, 3), 0, 0);
cvtColor(dst, gray_src, COLOR_BGR2GRAY);
Laplacian(gray_src, edge_image, CV_16S, 3);
//Laplacian (InputArray src, OutputArray dst, int ddepth, int ksize=1, double scale=1, double delta=0, int borderType=BORDER_DEFAULT)
convertScaleAbs(edge_image, edge_image);
/*
在梯度运算中,很可能会出现负的灰度值,我们不能再采用uint8类型作为像素的数据类型,
而是采用了CV_64F这种有负数范围的类型,运算结果里的负数我们也不能不处理,否则在显示的时候就会被截断为0,
这样就会丢失边界信息。convertScaleAbs函数就是把梯度运算后的图像给正值化,也就是取绝对值
*/
threshold(edge_image, edge_image, 0, 255, THRESH_OTSU | THRESH_BINARY);
imshow("edge_image", edge_image);
//-----------------Canny---------------------//
cvtColor(src, gray_src, COLOR_BGR2GRAY);
GaussianBlur(gray_src, gray_src, Size(3, 3), 0, 0);
namedWindow("Canny");
createTrackbar("Threshold Value:", "Canny", &t1_value, max_value, Canny_Demo);
Canny_Demo(0, 0);
waitKey(0);
return 0;
}
void Canny_Demo(int, void*) {
Mat edge_output;
blur(gray_src, gray_src, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
Canny(gray_src, edge_output, t1_value, t1_value * 2, 3, false);
/*
Canny有两个重载
Canny (InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false)
Canny (InputArray dx, InputArray dy, OutputArray edges, double threshold1, double threshold2, bool L2gradient=false)
threshold1 first threshold for the hysteresis procedure.
threshold2 second threshold for the hysteresis procedure.
apertureSize aperture size for the Sobel operator.
L2gradient a flag,
dx 16-bit x derivative of input image (CV_16SC1 or CV_16SC3).
dy 16-bit y derivative of input image (same type as dx).
*/
//bitwise_not(edge_output, edge_output);
imshow("Canny", ~edge_output);//波浪号的作用是整个图像取反,相当于bitwise_not()
}
翻译笔记
magnitude n.震级;巨大;重大;重要性;大小;数量;星等
hysteresis n.【物】磁滞;【物】滞后现象[作用];迟滞性;平衡阻碍
accurate adj.正确无误的;精确的;准确的;准确的(掷、射、击等)
gradient n.倾斜度;梯度变化曲线
aperture n.缝隙;小孔;(尤指摄影机等的光圈)孔径