Roberts边缘检测

函数的梯度为df = af/ax * ix + af/ay * iy

图像梯度即为梯度的模, df = sqrt((af/ax) ^ 2 + (af/ay) ^ 2)

为简化计算过程,可表示为 df = | af/ax | + | af/ay 

Roberts算子是Roberts1963年提出的,他利用对角方向相邻的两个像素之差来近似差分。该算子边缘定位准,但对噪声敏感。

Roberts算子表达式如下:

G[i,j] = | f[i , j ] - f[ i + 1, j + 1 ] | + | f[ i + 1, j ] - f[ i, j + 1 ]|

#include"cv.h"
#include "highgui.h"

void Roberts(CvMat* gray, CvMat* edge);
int main()
{
	IplImage *src = cvLoadImage("flower.jpg",1);

	const int width = src->width;
	const int height = src->height;

	CvMat *gray = cvCreateMat(height, width, CV_8UC1);
	cvCvtColor(src, gray, CV_BGR2GRAY);

	CvMat *edge = cvCreateMat(height, width, CV_8UC1);
	Roberts(gray, edge);

 

	cvShowImage("SRC", src);
	cvShowImage("GRAY", gray);
	cvShowImage("ROBERTS", edge);
	cvWaitKey(0);

	cvCvtColor(gray, src, CV_GRAY2BGR);
	cvSaveImage("GRAY.bmp", src);

	cvCvtColor(edge, src, CV_GRAY2BGR);
	cvSaveImage("EDGE.bmp", src);

	cvReleaseMat(&gray);
	cvReleaseMat(&edge);
	return 0;
}
void Roberts(CvMat* gray, CvMat* edge)
{
	const int width = gray->width;
	const int height = gray->height;

	memset(edge->data.ptr, 0, sizeof(uchar) * width * height);

	for (int j = 0; j < height - 1; j ++)
	{
		uchar* edgeData = (uchar*)(edge->data.ptr + j * edge->step);
		uchar* dataCur = (uchar*)(gray->data.ptr + j * gray->step);
		uchar* dataDown =  (uchar*)(gray->data.ptr + (j + 1) * gray->step);
		for (int i = 0; i < width - 1; i ++)
		{
			edgeData[i] = abs(dataCur[i] - dataDown[i + 1]) + abs(dataCur[i + 1] - dataDown[i]);
		}
	}

}
源图、灰度图和边缘图如下所示



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值