使用openCV查看png图片的各通道值

        png格式的图片除了能展示出各类各样的色彩外,还能表现出“透明”的特色,这是由于这种格式的图片除了含有咱们常见的RGB三个颜色通道外,还有一个A通道来控制图片的透明效果。使用openCV能够方便的查看各类格式图片各个通道的值,思路以下:布局

  1. 首先,咱们须要加载一幅图片;
  2. 为了可以查看这个图片上每一个像素点各个通道的数值,咱们能够经过鼠标点击的方式来选择像素点,而后读取这个像素点各通道的数值,并显示出来;
  3. 为了判断显示是否正确,还能够新建一幅图片,用所选择像素点的颜色填充,判断这幅图片的颜色是不是咱们选择的颜色。
        代码以下:
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

IplImage *src;
IplImage *show;

void mouseHandler(int event, int x, int y, int flags, void *param);

int main()
{
	char *picture = "D:\\test\\2\\2.png";

	if((src = cvLoadImage(picture,CV_LOAD_IMAGE_UNCHANGED)) == 0)
	{
		cout<<"read Picture error"<<endl;
		return -1;
	}

	cvNamedWindow("picture", CV_WINDOW_AUTOSIZE);
	cvSetMouseCallback("picture",mouseHandler,NULL);
	cvShowImage("picture",src);


	show = cvCreateImage(cvSize(200,200),src->depth,src->nChannels);
	cvZero(show);

	cvNamedWindow("show", CV_WINDOW_AUTOSIZE);
	cvWaitKey();
}

void mouseHandler(int event, int x, int y, int flags, void *param)
{
	int R = 0,G = 0,B = 0,A = 0;
	uchar *c_src;
	ushort *s_src;

	uchar *c_dst;
	ushort *s_dst;

	switch(event)
	{
	case CV_EVENT_LBUTTONDOWN:
		cout<<"x = "<<x<<",y = "<<y<<endl;
		//获得选择像素点的值
		if(src->depth == IPL_DEPTH_8U)
		{
			c_src = (uchar *)(src->imageData + y*src->widthStep + x*src->nChannels);
			B = c_src[0];
			G = c_src[1];
			R = c_src[2];
			A = c_src[3];
		}
		else if(src->depth == IPL_DEPTH_16U)
		{
			s_src = (ushort *)(src->imageData + y*src->widthStep + x*src->nChannels);
			B = s_src[0];
			G = s_src[1];
			R = s_src[2];
			A = s_src[3];
		}
		cout<<"B = "<<B<<",G = "<<G<<",R = "<<R<<",A = "<<A<<endl<<endl;

		//复制
		if(show->depth = IPL_DEPTH_8U)
		{
			for(int i = 0; i < show->height;i++)
			{
				for(int j = 0;j < show->width;j++)
				{
					c_dst = (uchar *)(show->imageData + i * show->widthStep + j * show->nChannels);
					memcpy(c_dst,c_src,sizeof(uchar)*src->nChannels);
				}
			}
		}
		else if(show->depth = IPL_DEPTH_16U)
		{
			for(int i = 0; i<show->height;i++)
			{
				for(int j = 0;j<show->width;j++)
				{
					s_dst = (ushort *)(show->imageData + i * show->widthStep + j * show->nChannels);
					memcpy(s_dst,s_src,sizeof(ushort)*src->nChannels);
				}
			}
		}
		cvShowImage("show",show);
		//cvSaveImage("E:\\1.png",show);
		break;
	default:
		break;
	}
}

        要的到选择像素点的值,首先须要了解openCV中图片的数据布局。一幅5*5的png图片的数据布局如图,水平方向为Width,垂直方向为Height。


        若是要选择(2,3)处的像素点,首先须要将指针直到第2行:ptr = (uchar *)(src->imageData + 2*src->widthStep);而后将指针指到第2行第3列:ptr += 3*src->nChannels;这时ptr就指向了(2,3)这个像素点。ptr[0]、ptr[1]、ptr[2]、ptr[3]分别是四个通道的数值。要注意,openCV中三原色的顺序是B、G、R。

        若是要选择(x,y)处的像素点(坐标原点在左上角),ptr = (uchar *)(src->imageData + y*src->widthStep + x*src->nChannels)。