图像梯度可以把图像看成二维离散函数,图像梯度其实就是这个二维离散函数的求导:
图像梯度: G(x,y) = dx(i,j) + dy(i,j)
dx(i,j) = I(i+1,j) - I(i,j)
dy(i,j) = I(i,j+1) - I(i,j)
其中,I是图像像素的值(如:RGB值),(i,j)为像素的坐标。
图像梯度: G(x,y) = dx(i,j) + dy(i,j)
dx(i,j) = [I(i+1,j) - I(i-1,j)]/2
dy(i,j) = [I(i,j+1) - I(i,j-1)]/2
其中,I是图像像素的值(如:RGB值),(i,j)为像素的坐标。
用膨胀后的图像减去腐蚀后的图像得到差值图像,称为基本梯度图像。
基本梯度图像是OpenCV中支持的计算形态学梯度的方法,而此方法得到梯度有被称为基本梯度。
用原图像减去腐蚀之后的图像得到差值图像,称为图像的内部梯度。
图像膨胀之后再减去原来的图像得到的差值图像,称为图像的外部梯度。
方向梯度是使用X方向与Y方向的直线作为结构元素之后得到图像梯度。
用X方向直线的结构元素分别进行膨胀与腐蚀操作,得到图像之后求差值得到称为X方向梯度。
用Y方向直线的结构元素分别进行膨胀与腐蚀操作,得到图像之后求差值之后称为Y方向梯度。
腐蚀操作函数
膨胀操作函数
减法操作函数
构造卷积核函数
#include
#include
#include
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
Mat src, gray_src, dst;
src = imread("D:/image.png");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char input_title[] = "input image";
char output_title[] = "Basic Gradient Image";
namedWindow(input_title, CV_WINDOW_AUTOSIZE);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(input_title, src);
cvtColor(src, gray_src, CV_BGR2GRAY);
// calculate basic gradient same as morphologyEx() in opencv
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
Mat erode_ouput, dilate_output;
erode(gray_src, erode_ouput, kernel, Point(-1, -1));
dilate(gray_src, dilate_output, kernel, Point(-1, -1));
// calculate basic gradient
subtract(dilate_output, erode_ouput, dst, Mat());
imshow(output_title, dst);
// calculate internal gradient
Mat internalGradientImg;
subtract(gray_src, erode_ouput, internalGradientImg, Mat());
imshow("Internal Gradient", internalGradientImg);
// calculate external gradient
Mat externalGradientImg;
subtract(dilate_output, gray_src, externalGradientImg, Mat());
imshow("External Gradient", externalGradientImg);
// directional gradient
Mat hse = getStructuringElement(MORPH_RECT, Size(src.cols/16, 1), Point(-1, -1));
Mat vse = getStructuringElement(MORPH_RECT, Size(1, src.rows/16), Point(-1, -1));
Mat erode_direct, dilate_direct;
Mat binImg, xdirectImg, ydirectImg;
// 二值化方法
threshold(gray_src, binImg, 0, 255, CV_THRESH_OTSU | CV_THRESH_BINARY);
// X direction
erode(binImg, erode_direct, hse, Point(-1, -1));
dilate(binImg, dilate_direct, hse, Point(-1, -1));
subtract(dilate_direct, erode_direct, xdirectImg, Mat());
imshow("X directional gradient", xdirectImg);
// Y direction
erode(binImg, erode_direct, vse, Point(-1, -1));
dilate(binImg, dilate_direct, vse, Point(-1, -1));
subtract(dilate_direct, erode_direct, ydirectImg, Mat());
imshow("Y directional gradient", ydirectImg);
waitKey(0);
return 0;
}
参考网站:
https://blog.csdn.net/jia20003/article/details/52903385
https://blog.csdn.net/qq_18815817/article/details/78625845