sobel求取图像梯度

#include "opencv2/imgproc/imgproc.hpp"  
#include "opencv2/highgui/highgui.hpp"  
#include <iostream>  
#include <cmath>
using namespace cv;
using namespace std;

void SobelGradDirction(Mat &imageSource, Mat &imageSobelX, Mat &imageSobelY);

int main()
{
	Mat grayImage;
	const Mat srcImage = imread("D:/2015project/picture/jimu.jpg");
	if (!srcImage.data)
	{
		printf("could not load image...\n");
		return -1;
	}
	imshow("srcImage", srcImage);
	cvtColor(srcImage, grayImage, CV_BGR2GRAY);
	Mat imageSobelX;
	Mat imageSobelY;
	SobelGradDirction(grayImage, imageSobelX, imageSobelY);
	imshow("imageSobelX", imageSobelX);
	imshow("imageSobelY", imageSobelY);
	waitKey(0);
	return 0;
}
void SobelGradDirction(Mat &imageSource, Mat &imageSobelX, Mat &imageSobelY)
{
	imageSobelX = Mat::zeros(imageSource.size(), CV_32SC1);
	imageSobelY = Mat::zeros(imageSource.size(), CV_32SC1);
	//取出原图和X和Y梯度图的数组的首地址
	uchar *P = imageSource.data;
	uchar *PX = imageSobelX.data;
	uchar *PY = imageSobelY.data;

	//取出每行所占据的字节数
	int step = imageSource.step[0];//二维图像,step[0]代表是行
	int stepXY = imageSobelX.step;

	int index = 0;//梯度方向角的索引
	for (int i = 1; i < imageSource.rows - 1; ++i)
	{
		for (int j = 1; j < imageSource.cols - 1; ++j)
		{
			//通过指针遍历图像上每一个像素   
			double gradY = P[(i + 1)*step + j - 1] + P[(i + 1)*step + j] * 2 + P[(i + 1)*step + j + 1] - P[(i - 1)*step + j - 1] - P[(i - 1)*step + j] * 2 - P[(i - 1)*step + j + 1];
			PY[i*stepXY + j*(stepXY / step)] = abs(gradY);

			double gradX = P[(i - 1)*step + j + 1] + P[i*step + j + 1] * 2 + P[(i + 1)*step + j + 1] - P[(i - 1)*step + j - 1] - P[i*step + j - 1] * 2 - P[(i + 1)*step + j - 1];
			PX[i*stepXY + j*(stepXY / step)] = abs(gradX);
		}
	}
	//将梯度数组转换成8位无符号整型
	convertScaleAbs(imageSobelX, imageSobelX);
	convertScaleAbs(imageSobelY, imageSobelY);
}

元素数据寻址

step这里指出的是图像在各个梯级上的字节数大小,而这里的梯级指的是构成图像的名层次。

  上图三维图像由一个一个平面(第一级)构成,每一个平面由一行一行(第二级)构成,每行由一个一个点(第三级)构成。

 同理:二维图像由一行一行(第一级)构成,而每一行又由一个一个点(第二级)构成。

3通道例子(上述代码sobel用的是灰度图,单通道)

例如:创建一个3维的矩阵,尺寸为 3 * 4 * 6

step[i]表示第i维的总大小,单位为字节

我们定义的矩阵每个面有4*6=24个点,每个点定义为CV_32FC3类型,即3通道的32位float型,一个元素包含3个float,即 3 *4=12字节

那么整个面的大小step[0]=24 *12 =288 字节

step[1] = 6 *12 =72 字节

step[2] = 12字节

step1[i]表示第i维的包含的通道数 
第一维,包含4 * 6个点, 每个点都是3通道的,因此,第一维包含4 * 6 * 3 =72个通道 
同理,第二维包含 18个通道,第三维包含3个通道

size表示每个维度的大小
第一维大小为3,size(0) = 3 
第二维为4,size(1) = 4 
第三维为6,size(2) = 6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值