opencv学习笔记十二:梯度算子
程序员文章站
2022-06-01 18:14:42
...
【1】Robert算子:
|| =
由于平方和不便于计算,故近似为绝对值形式:
|| =| |
实际应用中,经常采用的是另一种近似梯度:
|| =|
故Robert梯度模板为:
W1 -1 0 0 1
W2 0 -1 1 0
【2】sobel算子:由于一般经常使用奇数模板,所以引入了sobel模板,考虑权重
Wx -1 0 1 -2 0 2 -1 0 1
Wy -1 -2 -1 0 0 0 1 2 1
【3】prewitt算子:和sobel算子类似,只不过不考虑权重
Wx -1 0 1 -1 0 1 -1 0 1
Wy -1 -1 -1 0 0 0 1 1 1
【4】laplace算子:
= f(i+1,j) + f(i-1,j) - 2f(i,j);
= f(i,j+1) + f(i,j-1) - 2f(i,j);
= + = f(i+1,j) +f(i-1,j) + f(i,j+1) +f(i,j-1) -4f(i,j);
故laplace模板为:
W 0 1 0 1 -4 1 0 1 0 考虑对角线:
W 1 1 1 1 -8 1 1 1 1 考虑权重:
W 1 4 1 4 -20 4 1 4 1
#include<opencv2/opencv.hpp>
using namespace cv;
Mat src,dst1,dst2;
int main(int arc, char** argv)
{
src = imread("2.jpg");
namedWindow("input",CV_WINDOW_AUTOSIZE);
imshow("input", src);
/*Robert算子
Mat kernel_1 = (Mat_<int>(2, 2)<<1,0,0,-1);
Mat kernel_2 = (Mat_<int>(2, 2)<< 0,-1,1,0);
*/
/*sobel算子
Mat kernel_x = (Mat_<int>(3, 3) << -1,0,1,-2,0,2,-1,0,1);
Mat kernel_y = (Mat_<int>(3, 3) << -1,-2,-1,0,0,0,1,2,1);
*/
//laplace算子
//Mat kernel = (Mat_<int>(3, 3) << 0,1,0,1,-4,1,0,1,0);
//filter2D(src, dst1, -1,kernel_x, Point(-1, -1),0.0);
//filter2D(src, dst2, -1, kernel_y, Point(-1, -1), 0.0);
//imshow("output1", dst1);
//imshow("output2", dst2);
//循环模糊,27是ESC的ASCLL码,当按下ESC时,程序退出
int index = 0;
int ksize = 3;
while (true){
int c = waitKey(40);
if (c == 27) {
break;
}
ksize = 1 + (index % 20) * 2 ;
Mat kernel = Mat::ones(Size(ksize, ksize), CV_32F);
kernel = kernel/float(ksize* ksize);
filter2D(src, dst1, -1, kernel, Point(-1, -1));
index++;
imshow("output", dst1);
}
waitKey(0);
return 0;
}
laplace运行结果如下:
循环模糊某一时刻运行结果如下:
opencv中对应API函数:
sobel算子:Sobel(src, dst, ine deepth,dx,dy,int ksize);
参数解释:灰度原图像,目标图像,位深度(一般设置比原图像深,防止截断),x方向导数阶数,y方向导数阶数,模板尺寸。
sobel改进算子:Scharr(src, dst, ine deepth,dx,dy,int ksize);
参数和sobel一样,只不过Scharr的模板是:
Wx -3 0 3 -10 0 10 -3 0 3
Wy -3 -10 -3 0 0 0 3 10 3
laplace算子:Laplacian(src, dst, int deepth, int ksize);
参数解释:灰度原图像,位深度,模板尺寸。
#include<opencv2/opencv.hpp>
using namespace cv;
int main(int arc, char** argv)
{
Mat src, gray,dst;
src= imread("1.jpg");
namedWindow("input",CV_WINDOW_AUTOSIZE);
imshow("input", src);
GaussianBlur(src, src, Size(3, 3), 0, 0);
cvtColor(src, gray, CV_BGR2GRAY);
imshow("gray", gray);
//【1】sobel算子
//Mat gradient_x, gradient_y;
//Sobel(gray, gradient_x, CV_16S,1,0,3);
//Sobel(gray, gradient_y, CV_16S,0,1,3);
//【2】Scharr算子
//Scharr(gray, gradient_x, CV_16S, 1, 0, 1, 0);
//Scharr(gray, gradient_y, CV_16S, 1, 0, 1, 0);*/
//计算绝对值
/*convertScaleAbs(gradient_x, gradient_x);
convertScaleAbs(gradient_y, gradient_y);
imshow("gradient_x", gradient_x);
imshow("gradient_y", gradient_y);
addWeighted(gradient_x, 1, gradient_y, 1, 0, dst);*/
//【3】laplace算子
//Laplacian(gray, dst, CV_16S, 3);
//convertScaleAbs(dst, dst);*/
//通过访问像素进行操作
/*int rows = gradient_x.rows;
int cols = gradient_x.cols;
Mat dst1 = Mat::zeros(gradient_x.size(), gradient_x.type());
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
dst1.at<uchar>(i,j) = saturate_cast<uchar>( gradient_x.at<uchar>(i, j) + gradient_y.at<uchar>(i, j));
}
}*/
imshow("FinalResult", dst);
waitKey(0);
return 0;
}
sobel 算子分别在x方向,y方向,x和y综合方向梯度图像如下:
Scharr 算子分别在x方向,y方向,x和y综合方向梯度图像如下:
laplace算子运行结果如下:
推荐阅读
-
荐 opencv进阶学习笔记3:像素运算和图像亮度对比度调节
-
python OpenCV学习笔记直方图反向投影的实现
-
荐 opencv进阶学习笔记2:numpy操作图像,色彩空间,查找指定颜色范围,通道分离与合并
-
ASP.NET Core 2 学习笔记(十二)REST-Like API
-
python OpenCV学习笔记实现二维直方图
-
机器学习个人笔记——(二)线性回归,最小二乘法和梯度下降
-
OpenCV学习笔记(一):使用opencv读取摄像头并实时显示
-
Python 学习笔记(十二)Python文件和迭代(一)
-
Python 学习笔记(十二)Python文件和迭代(二)
-
第十二周LINUX学习笔记