canny算子的灰度化

灰度化

注释写的很清楚。这里就不一一详细介绍

但是灰度化这里要注意一下就是

data1 = (uchar)(ColorImage->imageData[i *ColorImage->widthStep+j* 3 + 0]);//blue

这行代码里头,一开始不太理解为什么有widthStep

找了一些大家写的代码发现,只要是灰度化就一定会有这个代码的

现在大概理解了,这句话的意思就是

opencv iplimage格式直接访问内存读取像素

一定要高*widthStep

从网上找了一段话,虽然目前不太理解但是记录一下、

看了一些博客,总结一下就是

width表示图像的每行像素数,

widthStep表示存储一行像素需要的字节数,widthStep必须是4的倍数,从而实现字节对齐,有利于提高运算速度。

如果8U单通道图像宽度为3,那么widthStep是4,加一个字节补齐。

这个图像的一行需要4个字节,只使用前3个,最后一个空着。

也就是一个宽3高3的图像的imageData数据大小为4*3=12字节。

【注】:不同数据类型长度的图像,widthStep也不相同;

widthStep的值的计算有两种情况:

①当(width*3)%4=0,这时width*3=widthStep;

②当(width*3)%4 !=0,此时widthStep=(width/4+1)*3。

Mat的数据并不是字节对齐的;

关于图像失真的原因分析:

当width为偶数时,widthstep与width*nchannels相等,但当width为奇数时,就会填充一个单位像素的长度使widthstep成为偶数。看了帖子,我也找到了出错的原因,我就马上修改程序。呵呵,结果正常显示了。只要把读取数据的i*width+j改为i*widthstep+j就可以了。

width是图像宽度,可为任意值;widthstep是行字节数,应该是4的倍数,不一定等于width,nchannels为图像通道数。 #define WIDTHBYTES(bits) (((bits)+31)/32*4) 看看这个公式你就明白

width表示图像的每行像素数,widthStep表示存储一行像素需要的字节数。
在OpenCV里边,widthStep必须是4的倍数,从而实现字节对齐,有利于提高运算速度。
如果8U单通道图像宽度为3,那么widthStep是4,加一个字节补齐。这个图像的一行需要4个字节,只使用前3个,最后一个空着。也就是一个宽3高3的图像的imageData数据大小为4*3=12字节。

好多都是要调用  图像->widthstep,那这个什么意思那就是调用了一个API。

根据头文件里头可以发现:

image->widthStep = (((image->width * image->nChannels *(image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1));                                             (1)

其中IPL_DEPTH_SIGN的定义可以在cxtypes.h中找到,定义为:#define IPL_DEPTH_SIGN 0x80000000, align的大小为CV_DEFAULT_IMAGE_ROW_ALIGN,其大小在cxmisc.h中定义为:#define  CV_DEFAULT_IMAGE_ROW_ALIGN 4,depth取8位深度。

根据(1)式,已知IPL_DEPTH_SIGN、align、depth 的大小,分别手动计算如下图像的widthStep:

图像宽度     图像通道数              计算得到的widthStep

3                    3                             12

3                    1                             4

5                    3                            16

5                    1                             8

7                    3                             24

7                    1                             8

4                    3                             12

4                    1                             4

为了进一步验证手算的正确性,我们编程实现输出widthStep的大小,程序如下:

 IplImage *image_33 = cvCreateImage(cvSize(3, 3), 8, 3);
 IplImage *image_31 = cvCreateImage(cvSize(3, 3), 8, 1);
 IplImage *image_53 = cvCreateImage(cvSize(5, 3), 8, 3);
 IplImage *image_51= cvCreateImage(cvSize(5, 3), 8, 1);
 IplImage *image_73 = cvCreateImage(cvSize(7, 3), 8, 3);
 IplImage *image_71 = cvCreateImage(cvSize(7, 3), 8, 1);

 printf("%d, %d, %d, %d, %d, %d", image_33->widthStep,image_31->widthStep,
     image_53->widthStep,image_51->widthStep,image_73->widthStep,image_71->widthStep);

运行结果为:12, 4, 16, 8, 24, 8, 与手动计算结果相同。

灰度化的代码如下,下一步高斯滤波

#include<opencv2\opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<iostream>
#include<opencv2\core\core.hpp>
#include<stdio.h>
#include<cv.h>

using namespace cv;

int main()
{   //读图像
	IplImage * ColorImage = cvLoadImage("D:\\anzhuang\\vsworkspace\\canny2\\2.png", 1);

	//判断是否读图成功
	if (ColorImage == NULL)
	{
		printf("image read error");
		return 0;
	}
    //命名窗口,显示窗口
	cvNamedWindow("Sourceing",0);
	cvShowImage("Sourceing", ColorImage);
	//定义一个数组
	IplImage * OpenCvGrayImage;
	//用CreateImage函数创建图像首地址,并分配存储空间,将首地址赋给刚刚定义的数组 
	OpenCvGrayImage = cvCreateImage(cvGetSize(ColorImage), ColorImage->depth, 1);
	//灰度化,通过指针方式进行读取,显示彩色图像三个通道的图片,并根据RGB转换为灰度图像
	//因为图像是矩阵,所以有两个for
	float data1, data2, data3;
	for (int i = 0; i < ColorImage->height; i++)
	{
		for (int j = 0; j < ColorImage->width; j++)
		{
			data1 = (uchar)(ColorImage->imageData[i *ColorImage->widthStep+j* 3 + 0]);//blue
			data2 = (uchar)(ColorImage->imageData[i *ColorImage->widthStep+j * 3 + 1]);//green
			data3 = (uchar)(ColorImage->imageData[i *ColorImage->widthStep+j * 3 + 2]);//red
			OpenCvGrayImage->imageData[i*OpenCvGrayImage->widthStep + j] = (uchar)(0.114*data1 + 0.587*data2 + 0.299*data3);
		}
	}
	//命名窗口,并显示处理
	cvNamedWindow("GrayImage",0);
	cvShowImage("GrayImage", OpenCvGrayImage);
	cvWaitKey(0);
	cvDestroyWindow("GrayImage");

猜你喜欢

转载自blog.csdn.net/tudoufanqietudou/article/details/82427497