图像处理(四):边缘检测(一):

边缘:图像梯度在其梯度方向上的极大值。

轮廓:将边缘按照领域连接关系序列的连接在一起。

利用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; 

}

代码效果如下:


好好的一妹子就这样被我毁了!!!罪过罪过!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值