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
#include
#include
#include
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;
}