opencv感兴趣通道COI的使用

opencv中设置和获取感兴趣通道COI的函数如下:

SetImageCOI 设置感兴趣通道

void cvSetImageCOI( IplImage* image, int coi );

image 图像头.  

coi 感兴趣通道.

函数 cvSetImageCOI 基于给定的值设置感兴趣的通道。值 0 意味着所有的通道都被选定, 1 意味着第一个通道被选定等等。如果 ROI 是 NULL 并且COI!= 0, COI 被分配.


GetImageCOI 返回感兴趣通道号

int cvGetImageCOI( const IplImage* image );

函数cvGetImageCOI 返回图像的感兴趣通道(当所有的通道都被选中返回值是0).


要注意的是,大多数的opencv函数并不支持COI。

以下面代码为例:

IplImage* imgCOI1=cvLoadImage("lena.bmp");

cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE); 

cvSetImageCOI( imgCOI1 ,1 );

cvShowImage("mainWin", imgCOI1 ); 

以上代码读入一张图像,设置感兴趣区域为1(即Blue通道),然后显示出来。显示结果仍为彩色图像,也就是说cvShowImage函数并不支持COI的设定。


对于上面问题的解决方案:在opencv中 cvCopy cvSplit是支持感兴趣通道COI的

cvCopy():

cvCopy的原型是:void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
cvCopy函数将设置过感兴趣通道COI的源图像复制到匹配大小的目标图像中。只复制COI通道
注意:在使用cvCopy这个函数之前,你必须用cvCreateImage()一类的函数先开一段内存。后面的cvSplit也是同样的要求

 cvSplit():
有些时候处理多通道图像时不是很方便,在这种情况下,可以利用cvSplit()分别复制每个通道到多个单通道图像。函数原型:void cvSplit(const CvArr* src,CvArr *dst0,CvArr *dst1, CvArr *dst2, CvArr *dst3)  
如果需要,cvSplit()函数将复制src(即源多通道图像)的各个通道到图像dst0、dst1、dst2、dst3中。
目标图像必须与源图像在大小和数据类型上匹配,当然也应该是单通道的图像。
如果源图像少于4个通道(这种情况经常出现),那么传递给cvSplit()的不必要的目标参数可设置为NULL。
使用cvSplit函数前源图像不能设置过感兴趣通道COI,否则会报错


下面是我总结的一个获取指定感兴趣通道COI的模板demo,以备以后使用

#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>

int main()
{ 
	// 导入一张彩色图像(设置感兴趣通道),一张灰度图像(设置感兴趣区域)
	IplImage* imgCOI1=cvLoadImage("lena.bmp");
	IplImage* imgCOI2=cvLoadImage("lena.bmp");
	/*
	OpenCV默认将读入的图像强制转换为一幅三通道彩色图像. 
	可以按这种方法修改读入方式:img=cvLoadImage(fileName,flag);
	flag: >0 将读入的图像强制转换为一幅三通道彩色图像
	=0 将读入的图像强制转换为一幅单通道灰度图像
	<0 读入的图像通道数与所读入的文件相同.
	*/
	if(!imgCOI1 || !imgCOI2)
		printf("Could not load image file: %s\n","lena.bmp");
	else
		printf("load image successful\n");

	cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE); 
	cvMoveWindow("mainWin", 700, 100);
	cvShowImage("mainWin", imgCOI1 ); 
	printf("have a look at the color image first\nwait any key...\n");
	cvWaitKey(0); 

	//设置感兴趣通道为b  彩色图像的通道顺序是 BGR,所以参数指定1
	cvSetImageCOI( imgCOI1 ,1 );
	cvShowImage("mainWin", imgCOI1 ); 
	printf("have a look at the first channel(b)of image.我们发现当使用cvShowImage时cvSetImageCOI对于感兴趣通道的设置并不起作用\nwait any key...\n");
	cvWaitKey(0); 

	#pragma region cvCopy方法获取某一通道
	IplImage* BlueImage=cvCreateImage(cvGetSize(imgCOI1),IPL_DEPTH_8U,1);  
	cvSetImageCOI( imgCOI1 ,3 );
	cvCopy(imgCOI1,BlueImage);
	cvShowImage("mainWin", BlueImage ); 
	printf("have a look at the third channel(r)of image which we use cvCopy to get.\n我们发现cvCopy是支持COI的,我们抽出了红色对应的通道\nwait any key...\n");
	cvWaitKey(0); 
	#pragma endregion

	#pragma region cvSplit方法获取各个通道
	IplImage* R_Image=cvCreateImage(cvGetSize(imgCOI2),IPL_DEPTH_8U,1);  
	IplImage* G_Image=cvCreateImage(cvGetSize(imgCOI2),IPL_DEPTH_8U,1);  
	IplImage* B_Image=cvCreateImage(cvGetSize(imgCOI2),IPL_DEPTH_8U,1);  
	cvSplit(imgCOI2,B_Image,G_Image,R_Image,0);  //接收各通道的子图像要注意与源图像的通道顺序匹配,彩色即BGR。注意使用前不能设置COI
	printf("have a look at the b,g,r channel in sequence which we use the cvSplit to get.\nwait any key three times...\n");
	cvShowImage("mainWin", B_Image ); 
	cvWaitKey(0); 
	cvShowImage("mainWin", G_Image ); 
	cvWaitKey(0); 
	cvShowImage("mainWin", R_Image ); 
	cvWaitKey(0); 
	#pragma endregion

	cvDestroyWindow("mainWin");
	cvReleaseImage(&imgCOI1 );
	cvReleaseImage(&imgCOI2);

	return 0;
}



你可能感兴趣的:(opencv,感兴趣通道,COI)