#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