如果我们想分离出每个通道的具体值,并且可以演示看出分离的是“红”“绿”“蓝”的效果。可以用如下函数:
1、C接口程序:
IplImage* img = cvLoadImage("baboon.jpg");
IplImage* rImg=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
IplImage* gImg=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
IplImage* bImg=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
cvSplit( img,bImg, gImg,rImg,0);
IplImage* rImg3=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
IplImage* gImg3=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
IplImage* bImg3=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
cvMerge(bImg,gImg,0,0,rImg3);
cvMerge(bImg,0,rImg,0,gImg3);
cvMerge(0,gImg,rImg,0,bImg3);
cvMerge源程序:
CV_IMPL void cvMerge(const void* srcarr0, const void* srcarr1, const void* srcarr2,
const void* srcarr3, void* dstarr )
{
const void* sptrs[] = { srcarr0, srcarr1,srcarr2, srcarr3 };
cv::Mat dst = cv::cvarrToMat(dstarr);
int i, j, nz = 0;
for( i = 0; i < 4; i++ )
nz += sptrs[i] != 0;
CV_Assert( nz > 0 );
cv::vector<cv::Mat> svec(nz);
cv::vector<int> pairs(nz*2);
for( i = j = 0; i < 4; i++ )
{
if( sptrs[i] != 0 )
{
svec[j] = cv::cvarrToMat(sptrs[i]);
CV_Assert( svec[j].size == dst.size&&
svec[j].depth() == dst.depth()&&
svec[j].channels() == 1&& i < dst.channels() );
pairs[j*2] = j;
pairs[j*2+1] = i;
j++;
}
}
if( nz == dst.channels() )
cv::merge( svec, dst );
else
{
cv::mixChannels( &svec[0], nz,&dst, 1, &pairs[0], nz );
}
}
说明:cvMerge函数中cv::Mat dst = cv::cvarrToMat(dstarr);这句会使得dst中元素全为205,具体为什么不清楚。
2、C++接口程序
//单窗口显示多幅图像
int showManyImages( const std::vector<cv::Mat> &srcImages, cv::Size imgSize,cv::Mat& dstImage )
{
int nNumImages = srcImages.size();
cv::Size nSizeWindows;
if(nNumImages > 12)
{
std::cout << " Not more than 12 images!" << std::endl;
return -1;
}
// 根据图片序列数量来确定分割小窗口形态
switch(nNumImages)
{
case 1: nSizeWindows = cv::Size(1,1);break;
case 2: nSizeWindows = cv::Size(2,1);break;
case 3:
case 4: nSizeWindows = cv::Size(2,2);break;
case 5:
case 6: nSizeWindows = cv::Size(3,2);break;
case 7:
case 8: nSizeWindows = cv::Size(4,2);break;
case 9: nSizeWindows = cv::Size(3,3);break;
default:nSizeWindows = cv::Size(4,3);break;
}
// 设置小图像尺寸,间隙,边界
cv::Size nShowImageSize = cv::Size(300,200);//每张图显示在画布上的尺寸
int nSplitLineSize = 30;
int nAroundLineSize = 50;
// 创建输出图像,图像大小根据输入源确定
const int imagesHeight = nShowImageSize.height * nSizeWindows.height+
nAroundLineSize + (nSizeWindows.width - 1) *
nSplitLineSize;
const int imagesWidth = nShowImageSize.width*nSizeWindows.height +
nAroundLineSize + (nSizeWindows.height - 1) *
nSplitLineSize;
//std::cout << imagesWidth << " " << imagesHeight << std::endl;
cv::Mat resultImage(imagesHeight, imagesWidth,
CV_8UC3,cv::Scalar(0,0,0));
// 提取对应小图像的左上角坐标X,Y
int posX = (resultImage.cols-(nShowImageSize.width*
nSizeWindows.width+(nSizeWindows.width-1)*
nSplitLineSize))/2;
int posY = (resultImage.rows-(nShowImageSize.height*
nSizeWindows.height+(nSizeWindows.height-1)*
nSplitLineSize))/2;
//std::cout << posX << " " << posY << std::endl;
int tempPosX = posX;
int tempPosY = posY;
//write text on image
std::vector<cv::string> msg;
msg.push_back("original image");
msg.push_back("blue image");
msg.push_back("green image");
msg.push_back("red image");
int baseLine = 0;
// 将每一小幅图像整合大图像
for(int i = 0; i < nNumImages; i++)
{
// 小图像坐标转换
if(( i % nSizeWindows.width == 0) && ( tempPosX != posX ))
{
tempPosX = posX;
tempPosY += (nSplitLineSize + nShowImageSize.height);
}
// 利用Rect区域将小图像置于大图像相应区域
cv::Mat tempImage = resultImage(cv::Rect(tempPosX,
tempPosY , nShowImageSize.width, nShowImageSize.height));
// 利用resize函数实现图像缩放
resize(srcImages[i], tempImage,
cv::Size( nShowImageSize.width , nShowImageSize.height));
cv::Size textSize = cv::getTextSize(msg[i], 1, 1, 1, &baseLine);//returns bounding box of the text string
int textPosX = tempPosX + nShowImageSize.width/2 - textSize.width/2;
int textPosY = tempPosY - 10;
cv::Point textOrigin(textPosX,textPosY);
cv::putText(resultImage,msg[i],textOrigin,1,1,cv::Scalar(255,255,255),1,8);
tempPosX += (nSplitLineSize + nShowImageSize.width);
}
dstImage = resultImage.clone();
}
int main()
{
cv::Mat srcImage = cv::imread("baboon.jpg");
if(!srcImage.data) return -1;
std::vector<cv::Mat> vecImage(3),bgrImage(3);
cv::split(srcImage,vecImage);// B/G/R
for (int i = 0;i<3;i++)
{
cv::split(srcImage,vecImage);// B/G/R
for (int j = 0;j<3;j++)
{
if (i != j )
vecImage[i] = cv::Mat::ones(srcImage.size(), vecImage[0].type())*205;//为了保持与cvMerge结果一致
}
cv::merge(vecImage,bgrImage[i]);
}
cv::Mat showImage;
bgrImage.insert(bgrImage.begin(),srcImage);
showManyImages(bgrImage,cv::Size(2,2),showImage);
cv::imwrite("showImage.jpg",showImage);
cv::waitKey(0);
return 0;
}
结果: