【opencv2】生成图像的梯度图

先看代码:

<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就是代表对应位相加。

下面给出原图和效果图:

原图:

效果图:

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

时间: 2024-09-20 17:55:06

【opencv2】生成图像的梯度图的相关文章

图像切割—基于图的图像切割(Graph-Based Image Segmentation)

 图像切割-基于图的图像切割(Graph-Based Image Segmentation) Reference: Efficient Graph-Based Image Segmentation,IJCV 2004,MIT Code 图像切割-基于图的图像切割(OpenCV源代码注解) 最后一个暑假了,不打算开疆辟土了.战略中心转移到品味经典.计划把图像切割和目标追踪的经典算法都看一看.再记些笔记. Graph-Based Segmentation 是经典的图像切割算法,作者Felzens

MySQL WorkBench6.1生成各表关系图

MySQL WorkBench生成各表关系图网上教程很多,但我下的6.1版就死活找不到,不过最终还是找到了.首页的这里 MySQL WorkBench6.1生成各表关系图

PHP使用HighChart生成股票K线图详解

本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加). QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29LoD19)    QQ:1542385235 HighChart是集合了各种常见的web图表的开源合集,其中产生股票K线图的部分叫做“HighStock”.大家如果需要可以到我的资源页下载,是最新版: http://download.csdn.net/detail/wangyuchun_799/9353525

Highstock生成股票K线图

在线演示 本地下载 使用HightStock生成股票K线图例子.

Linux下PHP自动生成文章预览图,html转换成各种格式图片、PDF-----转自phpboy的文章

原文地址:http://www.phpboy.net/linux/575.html 用WordPress建立博客站点,选择了一套可以显示文章缩略图的模板,几经折腾将原有模板改得面目全非,最后还是直接上线吧,不想折腾了. 站点上线没几天,在公司做项目时,对图片做了一个放大的JS,自己博客也加上点击缩略图查看原图的功能,然后迅速的加了. 过了几天,突发奇想,想做文章预览图,即点击缩略图查看文章预览图,也就是你们现在首页和文章列表页看到的那个功能. 不费话了,不知道什么时候又要折腾... Linux下

Java导出Highcharts生成的图表为图片源码

本文转载自:http://blog.csdn.net/dengsilinming/article/details/7352054 需要的jar包: 需要的js文件:(可以通过http://www.highcharts.com/download下载highcharts对应的js文件) 下面是一些主要部分 web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5&

算法生成卐和卍字图

前面讲了算法生成道教的太极八卦图,这一节发个与佛教有关的卍字图.卍梵文Svastika,武则天定音为万字:意译为吉祥海云,吉祥喜旋,为佛三十二相之一,也是八十种好之一:此为显现于佛及十地菩萨胸臆等处之德相.长阿含经卷一大本经.大萨遮尼乾子所说经卷六.大般若经卷三八一等均记载佛之胸前.手足.腰间等处有卍字.于今印度阿摩罗婆提(Ama-ravati)出土之佛足石,亦刻有数个卍字.纳粹德国的纳粹党标志为希特勒借用的标致,但纳粹党标志的方向是斜的和黑色,而传统信仰中代表吉祥美好的卍字符多是明亮的色彩.

图像特征提取——局部图结构(LGS)及matlab代码实现

一.概述与原理 局部图结构(Local Graph Structure)是由Abusham E A提出的,该算子能将图像的局部特征信息很好的表示,其对于纹理的分辨能力很强,对灰度的单调变化不敏感. 关注一个3*4的区域,LGS与6个领域像素有关.如下图[1]所示: 算子的基本原理:从灰色点出发,沿着左上方走一个“8”字路径.(例如:图中路径即为7-9-5-7-6-7-7-6-7)在行进过程中,如果下一个节点比当前节点要更大,则为0,否则取1.(例如从起点7出发,到下一个节点9,因为9>7,则取0

opencv2学习- - - 图像的基本操作

1.图像的读取和显示 #include<iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; int main(int argc, int* argv[]) { Mat image = imread("lena.bmp"); namedWindow("