边缘:图像梯度在其梯度方向上的极大值。
轮廓:将边缘按照领域连接关系序列的连接在一起。
利用0、45、90、135度模板,求图像梯度,然后计算最大值:
四个模板分别如下:
具体代码如下:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
// 8领域
const int directions[9][2] = { { -1, -1 }, { -1, 0 }, { -1, 1 },
{ 0, -1 }, { 0, 0 }, { 0, 1 },
{ 1, -1 }, { 1, 0 }, { 1, 1 } };
// 0 degree template
const int degree0[9] = { -1, 0, 1, -1, 0, 1, -1, 0, 1 };
// 45 degree template
const int degree45[9] = { 0, 1, 1, -1, 0, 1, -1, -1, 0 };
// 90 degree template
const int degree90[9] = { 1, 1, 1, 0, 0, 0, -1, -1, 1 };
// 135 degree template
const int degree135[9] = { 1, 1, 0, 1, 0, -1, 0, -1, -1 };
int main()
{
Mat src = imread("1.jpg");
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
// 计算4个方向上的梯度
Mat Mag = Mat::zeros(gray.rows, gray.cols, CV_8UC1);
Mat Mag_0 = Mat::zeros(gray.rows, gray.cols, CV_8UC1);
Mat Mag_45 = Mat::zeros(gray.rows, gray.cols, CV_8UC1);
Mat Mag_90 = Mat::zeros(gray.rows, gray.cols, CV_8UC1);
Mat Mag_135 = Mat::zeros(gray.rows, gray.cols, CV_8UC1);
int * degrees = new int[gray.rows * gray.cols];
int i, j, k;
int temp_0 = 0;
int temp_45 = 0;
int temp_90 = 0;
int temp_135 = 0;
// 计算各个方向上的梯度
for (i = 1; i < gray.rows - 1; i++)
for (j = 1; j < gray.cols - 1; j++)
{
for (k = 0; k < 9; k++)
{
temp_0 += degree0[k] * gray.at<uchar>(i + directions[k][0], j + directions[k][1]);
temp_45 += degree45[k] * gray.at<uchar>(i + directions[k][0], j + directions[k][1]);
temp_90 += degree90[k] * gray.at<uchar>(i + directions[k][0], j + directions[k][1]);
temp_135 += degree135[k] * gray.at<uchar>(i + directions[k][0], j + directions[k][1]);
}
Mag_0.at<uchar>(i, j) = temp_0;
Mag_45.at<uchar>(i, j) = temp_45;
Mag_90.at<uchar>(i, j) = temp_90;
Mag_135.at<uchar>(i, j) = temp_135;
// 清零
temp_0 = 0;
temp_45 = 0;
temp_90 = 0;
temp_135 = 0;
}
vector<int>Mag_temps;
// 计算对应各个位置的梯度最大值
for (i = 1; i < gray.rows - 1; i++)
for (j = 1; j < gray.cols - 1; j++)
{
Mag_temps.push_back(Mag_0.at<uchar>(i, j));
Mag_temps.push_back(Mag_45.at<uchar>(i, j));
Mag_temps.push_back(Mag_90.at<uchar>(i, j));
Mag_temps.push_back(Mag_135.at<uchar>(i, j));
int temp = 0;
int index = 0;
// 比较获得最大值
for (k = 0; k < 4; k++)
{
if (temp < Mag_temps[k])
{
temp = Mag_temps[k];
index = k;
}
}
// 获取最终的Mag及对应梯度方向
Mag.at<uchar>(i, j) = temp;
degrees[i * gray.cols + j] = index;
Mag_temps.clear();
}
// 设置显示窗口大小
namedWindow("src", 0);
resizeWindow("src", 300, 300);
namedWindow("0", 0);
resizeWindow("0", 300, 300);
namedWindow("45", 0);
resizeWindow("45", 300, 300);
namedWindow("90", 0);
resizeWindow("90", 300, 300);
namedWindow("135", 0);
resizeWindow("135", 300, 300);
namedWindow("Mag", 0);
resizeWindow("Mag", 300, 300);
imshow("src", src);
imshow("0", Mag_0);
imshow("45", Mag_45);
imshow("90", Mag_90);
imshow("135", Mag_135);
imshow("Mag", Mag);
waitKey();
delete[] degrees;
return 0;
}
代码效果如下:
好好的一妹子就这样被我毁了!!!罪过罪过!!!!