码迷,mamicode.com
首页 > 其他好文 > 详细

【opencv2】生成图像的梯度图

时间:2015-01-27 13:23:07      阅读:342      评论:0      收藏:0      [点我收藏+]

标签:opencv   梯度图   

先看代码:

<span style="font-size:24px;">#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\opencv.hpp>
#include <iostream>


using namespace cv;
using namespace std;

typedef unsigned char byte;
void gradientGray(Mat &src, Mat &mag);
int main(){

	Mat src = imread("1.jpg", 0);//以灰度形式读取图片
	Mat dst;	
	gradientGray(src, dst);
	imwrite("2.jpg",dst); //保存文件,梯度图
	imshow("src", src);
	imshow("dst", dst);
	waitKey(0);

}

void gradientGray(Mat &src, Mat &mag)
{
	const int H = src.rows, W = src.cols;
	Mat Ix(H, W, CV_32S), Iy(H, W, CV_32S);
	//因为计算出的梯度值可能有正有负,且值也可能会很大,故数据类型为整形

	// 求水平方向梯度,处理左右边缘像素
	for (int y = 0; y < H; y++){
		Ix.at<int>(y, 0) = abs(src.at<byte>(y, 1) - src.at<byte>(y, 0)) * 2;
		for (int x = 1; x < W - 1; x++)
			Ix.at<int>(y, x) = abs(src.at<byte>(y, x + 1) - src.at<byte>(y, x - 1));
		Ix.at<int>(y, W - 1) = abs(src.at<byte>(y, W - 1) - src.at<byte>(y, W - 2))*2;
	}
	// 求垂直方向梯度,处理左右边缘像素
	for (int x = 0; x < W; x++)	{
		Iy.at<int>(0, x) = abs(src.at<byte>(1, x) - src.at<byte>(0, x)) * 2;
		for (int y = 1; y < H - 1; y++)
			Iy.at<int>(y, x) = abs(src.at<byte>(y + 1, x) - src.at<byte>(y - 1, x));
		Iy.at<int>(H - 1, x) = abs(src.at<byte>(H - 1, x) - src.at<byte>(H - 2, x)) * 2;
	}
	/*for (int j = 0; j < H; j++) 
		for (int k = 0; k < W; k++)
		{
			mag.at<byte>(j, k) = min(Ix.at<int>(j,k) + Iy.at<int>(j, k), 255);
		}*/
	convertScaleAbs(min(Ix + Iy, 255), mag); //这句话和上面的for循环是同样的功能
}
</span>
求解梯度图,首先要注意数据的转换。因为本身读取的图像是8位的,其灰度值范围为0~255,而在求梯度的过程中,会出现梯度值大于255或者小于0的情况,因此在梯度图所存储的数据应该是以有符号整型的形式,即CV_32S。

另外,我采用的梯度求解方法为,当前像素的后一个像素减前一个像素的差值,作为当前像素的当前方向的梯度值。因为梯度本质上是求微分,因此对与图像,其存在两个方向上的梯度,即水平和垂直方向。这也是程序中求了两次灰度的原因。

在求了两个方向的梯度之后,再如何求出当前像素的梯度值,其方法也是很多的。我采用的是将水平和垂直梯度的绝对值相加,也可以采用平方和再开根号的方法,或者直接取二者最大值都行。

另外,解释一下,最后的那个类型转换函数,其作用是将当前数据类型的图像转换为unsigned char型,另外,在opencv中,其重载了很多算术运算符,比如这个函数里面的Ix+Iy就是代表对应位相加。


下面给出原图和效果图:

原图:

技术分享

效果图:

技术分享

是不是比较像素描~~~~

【opencv2】生成图像的梯度图

标签:opencv   梯度图   

原文地址:http://blog.csdn.net/autocyz/article/details/43193123

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!