C/C++图像处理4 边缘检测

内容

使用梯度、Robert、sobel、laplace算子对图像进行边缘检测

原理

share_noel/图像处理/数字图像处理-夏良正.pdf
https://blog.csdn.net/qq_41102371/article/details/125646840
数字图像处理-夏良正P194
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

基于前面的博客C/C++图像处理1 灰度图修正添加处理代码

#define ARRAY_SIZE 3
const short average[3][3] = { { 1, 2, 1 },
							  { 2, 4, 2 },
							  { 1, 2, 1 } };
const short sharpen[3][3] = { { -1, -1, -1 },
							  { -1, 8, -1 },
							  { -1, -1, -1 } };
const short laplace2[3][3] = { { -1, -1, -1 },
							   { -1, 8, -1 },
							   { -1, -1, -1 } };
const short laplace[3][3] = { { 0, -1, 0 },
							  { -1, 4, -1 },
							  { 0, -1, 0 } };
const short soble1[3][3] = { { -1, -2, -1 },
							 { 0, 0, 0 },
							 { 1, 2, 1 } };
const short soble2[3][3] = { { -1, 0, 1 },
							 { -2, 0, 2 },
							 { -1, 0, 1 } };

梯度算子

void gradient(short** in_array, short** out_array, long height, long width, int delta, int La, int Lb)//梯度算子
{

	int gradient=0;//梯度
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			out_array[i][j] = 0;//初始化行列,必要,不然会导致gramf1x[out_array[i][j]]++这里崩掉;
		}
	}

	for (int i = 0; i < height - 1; i++)//height - 1去除窗口到不了的边缘行
	{
		for (int j = 0; j < width - 1; j++)//width - 1去除窗口到不了的边缘行
		{
			/*原始gradient*/
			//out_array[i][j] = abs(in_array[i][j] - in_array[i + 1][j]) + abs(in_array[i][j] - in_array[i][j + 1]);
			
			/*加阈值判定,提取边缘*/
				gradient = abs(in_array[i][j] - in_array[i + 1][j]) + abs(in_array[i][j] - in_array[i][j + 1]);			
				if (gradient >= delta)
				{
					if (La==-1)
					{
						out_array[i][j] = gradient;
					}
					else
					{
						out_array[i][j] = La;
					}										
				}
				else
				{
					if (Lb==-1)
					out_array[i][j] = in_array[i][j];
					//out_array[i][j] = 100;
					else
						out_array[i][j] = Lb;
				}
		}
	}
}

Robert算子

/*ROBERT*/
void robert(short** in_array, short** out_array, long height, long width, int delta, int La, int Lb)//梯度算子robert
{

	int gradient = 0;//梯度
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			out_array[i][j] = 0;//初始化行列,必要,不然会导致gramf1x[out_array[i][j]]++这里崩掉;
		}
	}

	for (int i = 0; i < height - 1; i++)//height - 1去除窗口到不了的边缘行
	{
		for (int j = 0; j < width - 1; j++)//width - 1去除窗口到不了的边缘行
		{
			/*原始gradient*/
			//out_array[i][j] = abs(in_array[i][j] - in_array[i + 1][j + 1]) + abs(in_array[i][j + 1] - in_array[i + 1][j]);


				/*加阈值判定*/
				gradient = abs(in_array[i][j] - in_array[i + 1][j + 1]) + abs(in_array[i][j + 1] - in_array[i + 1][j]);
				if (gradient >= delta)
				{
					if (La == -1)
					{
						out_array[i][j] = gradient;
					}
					else
					{
						out_array[i][j] = La;
					}
				}
				else
				{
					if (Lb == -1)
						out_array[i][j] = in_array[i][j];
					//out_array[i][j] = 100;
					else
						out_array[i][j] = Lb;
				}			
		}
	}
}

Sobel算子

void sobel_algorithm(short** in_array, short** out_array, long height, long width)
{
	short value[9];
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			out_array[i][j] = 0;//初始化行列,必要,不然会导致gramf1x[out_array[i][j]]++这里崩掉;
		}
	}
	/*判定元素是否在图像内*/
	for (int i = 0; i < height; i++){
		for (int j = 0; j < width; j++){
			value[0] = is_in_array(j - 1, i - 1, height, width) ? in_array[i - 1][j - 1] : 0;
			value[1] = is_in_array(j, i - 1, height, width) ? in_array[i - 1][j] : 0;
			value[2] = is_in_array(j + 1, i - 1, height, width) ? in_array[i - 1][j + 1] : 0;
			value[3] = is_in_array(j - 1, i, height, width) ? in_array[i][j - 1] : 0;
			value[4] = in_array[i][j];
			value[5] = is_in_array(j + 1, i, height, width) ? in_array[i][j + 1] : 0;
			value[6] = is_in_array(j - 1, i + 1, height, width) ? in_array[i + 1][j - 1] : 0;
			value[7] = is_in_array(j, i + 1, height, width) ? in_array[i + 1][j] : 0;
			value[8] = is_in_array(j + 1, i + 1, height, width) ? in_array[i + 1][j + 1] : 0;
			/* sobel */
			out_array[i][j] = (short)abs(value[0] * soble1[0][0] + value[1] * soble1[0][1] + value[2] * soble1[0][2] +
			                             value[3] * soble1[1][0] + value[4] * soble1[1][1] + value[5] * soble1[1][2] +
			                             value[6] * soble1[2][0] + value[7] * soble1[2][1] + value[8] * soble1[2][2]) + 
			                  (short)abs(value[0] * soble2[0][0] + value[1] * soble2[0][1] + value[2] * soble2[0][2] +
			                             value[3] * soble2[1][0] + value[4] * soble2[1][1] + value[5] * soble2[1][2] +
			                             value[6] * soble2[2][0] + value[7] * soble2[2][1] + value[8] * soble2[2][2]);

		}
	}
}

Laplace算子

void laplace_algorithm(short** in_array, short** out_array, long height, long width)
{
	short value[9];
	int temp = 0;
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			out_array[i][j] = 0;//初始化行列,必要,不然会导致gramf1x[out_array[i][j]]++这里崩掉;
		}
	}
	for (int i = 0; i < height; i++){
		for (int j = 0; j < width; j++){
			value[0] = is_in_array(j - 1, i - 1, height, width) ? in_array[i - 1][j - 1] : 0;
			value[1] = is_in_array(j, i - 1, height, width) ? in_array[i - 1][j] : 0;
			value[2] = is_in_array(j + 1, i - 1, height, width) ? in_array[i - 1][j + 1] : 0;
			value[3] = is_in_array(j - 1, i, height, width) ? in_array[i][j - 1] : 0;
			value[4] = in_array[i][j];
			value[5] = is_in_array(j + 1, i, height, width) ? in_array[i][j + 1] : 0;
			value[6] = is_in_array(j - 1, i + 1, height, width) ? in_array[i + 1][j - 1] : 0;
			value[7] = is_in_array(j, i + 1, height, width) ? in_array[i + 1][j] : 0;
			value[8] = is_in_array(j + 1, i + 1, height, width) ? in_array[i + 1][j + 1] : 0;

				/*考虑了45、135方向后的laplace变形算子*/
				temp = abs(value[0] * laplace2[0][0] + value[1] * laplace2[0][1] + value[2] * laplace2[0][2] +
					value[3] * laplace2[1][0] + value[4] * laplace2[1][1] + value[5] * laplace2[1][2] +
					value[6] * laplace2[2][0] + value[7] * laplace2[2][1] + value[8] * laplace2[2][2]);
				if (temp >= 255)
				{
					out_array[i][j] = 255;
				}
				else
					out_array[i][j] = temp;			 
		}
	}
}

结果

在这里插入图片描述

学习笔记,如有错漏,敬请指正
--------------------------------------------------------------------------------------------诺有缸的高飞鸟202007

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诺有缸的高飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值