图像梯度的概念
- 图像梯度
思考,清晰图像和模糊图像之间的差别是什么?
从逻辑上考虑,图像模糊是因为图像中物体的轮廓不明显,轮廓边缘灰度变化不强烈,层次感不强造成的,那么反过来考虑,轮廓边缘灰度变化明显些,层次感强些是不是图像就更清晰些呢。
那么,这种灰度变化明显不明显怎样去定义呢?
我们学过微积分,知道微分就是求函数的变化率,即导数(梯度),那么对于图像来说,可不可以用微分来表示图像灰度的变化率呢,当然是可以的,图像就是函数嘛。
常见梯度算子
- Sobel算子:
API:Sobel
CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,
int dx, int dy, int ksize = 3,
double scale = 1, double delta = 0,
int borderType = BORDER_DEFAULT );
- Scharr算子:(可以看做Sobel增强)
API:Scharr
CV_EXPORTS_W void Scharr( InputArray src, OutputArray dst, int ddepth,
int dx, int dy, double scale = 1, double delta = 0,
int borderType = BORDER_DEFAULT );
- Robot算子:
- 图像梯度:(L2和L1)
- 各种算子的应用,选择方法:
(1)Robot算子是轻量级的,当我们需要提取的图像边缘质量较好,而且主要是想提取主要边缘的时候适用;
(2)Sobel算子是比Robot稍好的算子;
(3)Scharr算子是更强烈的算子,当我们需要提取的图像边缘质量不佳的时候适用
Mat src = imread("F:/code/images/ttt.png");
if (src.empty()) {
printf("fail to read");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src);
// robot gradient 计算
Mat robot_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);
Mat robot_y = (Mat_<int>(2, 2) << 0, 1, -1, 0);
Mat grad_x, grad_y;
filter2D(src, grad_x, CV_32F, robot_x, Point(-1, -1), 0, BORDER_DEFAULT);
filter2D(src, grad_y, CV_32F, robot_y, Point(-1, -1), 0, BORDER_DEFAULT);
convertScaleAbs(grad_x, grad_x);
convertScaleAbs(grad_y, grad_y);
Mat result;
add(grad_x, grad_y, result);//L1梯度
imshow("robot gradient", result);
// sobel and scharr
Sobel(src, grad_x, CV_32F, 1, 0);
Sobel(src, grad_y, CV_32F, 0, 1);
convertScaleAbs(grad_x, grad_x);
convertScaleAbs(grad_y, grad_y);
Mat result2;
addWeighted(grad_x, 0.5, grad_y, 0.5, 0, result2);
imshow("sobel gradient", result2);
Scharr(src, grad_x, CV_32F, 1, 0);
Scharr(src, grad_y, CV_32F, 0, 1);
convertScaleAbs(grad_x, grad_x);
convertScaleAbs(grad_y, grad_y);
Mat result3;
addWeighted(grad_x, 0.5, grad_y, 0.5, 0, result3);
imshow("scharr gradient", result3);
PS:addWeighted
该函数是将两张相同大小,相同类型的图片融合的函数。
CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
double beta, double gamma, OutputArray dst, int dtype = -1);
//参数1:src1,第一个原数组.
//参数2:alpha,第一个数组元素权重
//参数3:src2第二个原数组
//参数4:beta,第二个数组元素权重
//参数5:gamma,图1与图2作和后添加的数值。不要太大,不然图片一片白。总和等于255以上就是纯白色了。
//参数6:dst,输出图片