一、如何实现单窗口显示多个图片
1、在开始可以先创建一张空白的图片。
2、imread读入一张图片
3、创建一个临时的Mat对象用来设定裁剪的区域,这个临时的对象使用第一步骤创建的Mat对象进行初始化。设定图片放置的区域使用rect函数设定初始化的坐标长宽。
4、再使用resize调整2步骤中的图片放缩大学输出到3步骤中的temp中。
代码如下:
Mat scrImage(700,700,CV_8UC3,Scalar(0,0,0));
Mat img=imread("../test.png");
Mat tempImage=scrImage(Rect(30,30,200,200)),
rempImage2=scrImage(Rect(250,30,200,200));
resize(img,tempImage,Size(200,200));
resize(img,rempImage2,Size(200,200));
namedWindow("image",(700,700));
imshow("image",scrImage);
以下为复杂的单窗口显示多张图片:
#include <iostream>
#include <vector>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
void ShowMangImages(const vector<Mat>& scrImages,Size ImageSize)
{
int nNumImages= scrImages.size();
Size nSizeWindows;
if(nNumImages>12)
{
cout<<"no more than 12 iamges"<<endl;
return;
}
switch (nNumImages)
{
case 1:
nSizeWindows=Size(1,1);
break;
case 2:
nSizeWindows=Size(2,1);
break;
case 3:
case 4:
nSizeWindows=Size(2,2);
break;
case 5:
case 6:
nSizeWindows=Size(3,2);
break;
case 7:
case 8:
nSizeWindows=Size(4,2);
break;
case 9:
nSizeWindows=Size(3,3);
break;
default:
nSizeWindows=Size(4,3);
break;
}
//设置大小尺寸、间隙、边界
int nShowImageSize =200;
int nSplitLineSize=15;
int nAroundLineSize =50;
const int imagesHeight=nShowImageSize*nSizeWindows.width+nAroundLineSize
+(nSizeWindows.width-1)*nSplitLineSize;
const int imagesWidth=nShowImageSize*nSizeWindows.height+nAroundLineSize
+(nSizeWindows.height-1)*nSplitLineSize;
cout<<imagesWidth<<" "<<imagesWidth<<endl;
Mat showWindowsImages(imagesWidth,imagesWidth,CV_8UC3,Scalar(0,0,0));
int posX=(showWindowsImages.cols-(nShowImageSize*nSizeWindows.width
+(nSizeWindows.width -1)*nSplitLineSize))/2;
int posY=(showWindowsImages.rows-(nShowImageSize*nSizeWindows.height
+(nSizeWindows.height -1)*nSplitLineSize))/2;
cout<<posX<< " "<<posY<<endl;
int tempPosX =posX;
int tempPoxY =posY;
for(int i=0;i<nNumImages;i++)
{
//如果出现换行则就将X坐标归位,Y坐标加上一个图的大小
if((i%nSizeWindows.width ==0)&&(tempPosX!=posX))
{
tempPosX=posX;
tempPoxY=posY+nSplitLineSize+nShowImageSize;
}
//利用Rect区域将小图位置至于大图当之中。
Mat tempImage =showWindowsImages
(Rect(tempPosX,tempPoxY,nShowImageSize,nShowImageSize));
//通过resize实现对图片的缩放
resize(scrImages[i],tempImage,Size(nShowImageSize,nShowImageSize));
/* resize(scrImages[i],tempImage,Size(),0.1,0.1); */
tempPosX+=nShowImageSize+nSplitLineSize;
}
imshow("mang Image show",showWindowsImages);
}
int main(int argc, char *argv[])
{
vector<Mat> srcImage(9);
srcImage[0]=imread("../lambo.png");
srcImage[1]=imread("../lambo.png");
srcImage[2]=imread("../lambo.png");
srcImage[3]=imread("../test.png");
srcImage[4]=imread("../test.png");
srcImage[5]=imread("../test.png");
srcImage[6]=imread("../test.png");
srcImage[7]=imread("../test.png");
srcImage[8]=imread("../test.png");
ShowMangImages(srcImage,Size(147,118));
waitKey(0);
return 0;
}
二、如何晒选图像中的颜色
灰度图像大多通过算子寻找边缘和区域生长融合来分割图像。
彩色图像增加了色彩信息,可以通过不同的色彩值来分割图像,常用彩色空间HSV/HSI, RGB, LAB等都可以用于分割!
笔者主要介绍inrange() 来划分颜色区域。先看看OpenCV的文档:
C++: void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)
C: void cvInRangeS(const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst)
- src – first input array.
- lowerb – inclusive lower boundary array or a scalar.
- upperb – inclusive upper boundary array or a scalar.
- dst – output array of the same size as src and CV_8U type
-
For two-channel arrays:
-
and so forth.
意思主要是:
src:输入图像,CV2常用Mat类型;
lowerb:lower boundary下限,scalar类型的像素值,单通道scalar取一个值就行,彩图3通道scalar三个值;
upperb:上限,类型与lowerb同理;
dst:输出图像,尺寸与src一致,类型是CV_8U,但没有指定通道数。
Scalar lower(hmin,smin,vmin);
Scalar upper(hmax,smax,vmax);
inRange(imgHSV,lower,upper,mask);
imshow("image ",img);
imshow ("image HSV",imgHSV);
imshow("image mask",mask);
waitKey(1);