1. 程式人生 > >OpenCV一個窗口顯示多張圖片

OpenCV一個窗口顯示多張圖片

star ace history 得到 tps word 灰度 教程 ++

這個以前的時候,采取的是把要顯示的圖片copy到一張大圖片上去~ 這個也忒麻煩了點

然後 在 http://download.csdn.net/detail/zhazhiqiang2010/3614993#comment 這裏發現一個好用的代碼。。。。

感謝上傳者,記錄在這裏只為了以後方便使用~~~

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

#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <iostream>


#pragma
comment(lib, "cv.lib")
#pragma comment(lib, "cxcore.lib") #pragma comment(lib, "highgui.lib") void cvShowManyImages(char* title, int nArgs, ...) { // img - Used for getting the arguments IplImage *img; // DispImage - the image in which input images are to be copied IplImage *DispImage; int size; int
i; int m, n; int x, y; // w - Maximum number of images in a row // h - Maximum number of images in a column int w, h; // scale - How much we have to resize the image float scale; int max; // If the number of arguments is lesser than 0 or greater than 12 // return without displaying if(nArgs <= 0
) { printf("Number of arguments too small....\n"); return; } else if(nArgs > 12) { printf("Number of arguments too large....\n"); return; } // Determine the size of the image, and the number of rows/cols from number of arguments else if (nArgs == 1) { w = h = 1; size = 300; } else if (nArgs == 2) { w = 2; h = 1; size = 300; } else if (nArgs == 3 || nArgs == 4) { w = 2; h = 2; size = 300; } else if (nArgs == 5 || nArgs == 6) { w = 3; h = 2; size = 200; } else if (nArgs == 7 || nArgs == 8) { w = 4; h = 2; size = 200; } else { w = 4; h = 3; size = 150; } // Create a new 3 channel image0 DispImage = cvCreateImage( cvSize( 100+ size*w, 60 + size*h), 8, 3 ); // Used to get the arguments passed va_list args; va_start(args, nArgs); // Loop for nArgs number of arguments for (i = 0, m = 20, n = 20; i < nArgs; i++, m += (20 + size)) { // Get the Pointer to the IplImage img = va_arg(args, IplImage*); // Check whether it is NULL or not // If it is NULL, release the image, and return if(img == 0) { printf("Invalid arguments"); cvReleaseImage(&DispImage); return; } // Find the width and height of the image x = img->width; y = img->height; // Find whether height or width is greater in order to resize the image max = (x > y)? x: y; // Find the scaling factor to resize the image scale = (float) ( (float) max / size ); // Used to Align the images if( i % w == 0 && m!= 20) { m = 20; n+= 0 + size; } // Set the image ROI to display the current image //cvSetImageROI(DispImage, cvRect(m, n, (int)( x/scale ), (int)( y/scale ))); cvSetImageROI(DispImage, cvRect(m, n, (int)( x/scale ), (int)( y/scale ))); // cout<<"x="<<m<<"y="<<n<<endl; // Resize the input image and copy the it to the Single Big Image cvResize(img, DispImage); // Reset the ROI in order to display the next image cvResetImageROI(DispImage); } // Create a new window, and show the Single Big Image //cvNamedWindow( title, 1 ); cvShowImage( title, DispImage); /*cvWaitKey(0);*/ //cvDestroyWindow(title); // End the number of arguments va_end(args); // Release the Image Memory cvReleaseImage(&DispImage); } int main(int argc,char **argv) { /* CvCapture *capture;*/ int i=0; IplImage *frame=cvLoadImage(".\\test.png"); cvNamedWindow("video",1); cvResizeWindow("video",700,660); IplImage *frame_not=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels); cvNot(frame,frame_not); IplImage *frame_gray=cvCreateImage(cvGetSize(frame),frame->depth,1); IplImage *frame1=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels); IplImage *frame_canny=cvCreateImage(cvGetSize(frame),frame->depth,1); IplImage *frame2=cvCreateImage(cvGetSize(frame),frame->depth,frame->nChannels); cvCvtColor(frame,frame_gray,CV_RGB2GRAY); cvCvtColor(frame_gray,frame1,CV_GRAY2BGR); cvCanny(frame_gray,frame_canny,20,75,3); cvCvtColor(frame_canny,frame2,CV_GRAY2BGR); cvShowManyImages("video",4,frame,frame_not,frame1,frame2); cvWaitKey(); cvReleaseImage(&frame_not); cvReleaseImage(&frame1); cvReleaseImage(&frame_gray); cvReleaseImage(&frame2); cvReleaseImage(&frame_canny); cvDestroyWindow("video"); return 0; }

技術分享圖片

【Note:】

註意 這個函數顯示的圖像是 nChannels = 3 的。

你看見 cvShowManyImages 函數中的

  1. // Create a new 3 channel image0
  2. DispImage = cvCreateImage( cvSize( 100+ size*w, 60 + size*h), 8, 3 );


了麽~~~吼吼, 如果想要 顯示 單通道 的,把 3 改為 1 就OK了~~

==============================================================================

【起初我 cvLoadImage( "tutu"); 讀入了之前

【cvLoadImage( ,0) 讀入了一張圖像,然後用 cvSaveImage(); 保存圖像】

得到的一張圖像

】 這樣是可以顯示的。 然後就誤導了我以為 可以顯示灰度圖。。。。。。

後來,發現 cvLoadImage( ,0) 讀入的 灰度圖 老是 出錯。。。。。。

後來發現 【cvLoadImage( ,0) 讀入了一張圖像,然後用 cvSaveImage(); 保存圖像】 之後的圖像 nChanels = 3 !

才發現:

cvSaveImage()保存的 圖像只能為深度為8U的1通道或者3通道(RGB)的圖像。

也就是說 nChanels = 3 , R=G=B 的 3 通道的 灰度圖

總之,函數只顯示 通道為3 的 圖像!

=========================================================================================================================================

從文件中讀入一幅圖像可以使用imread函數來讀取圖像,

Mat img=imread(filename);

該語句將filename所指定路徑的指定文件讀取到img數組中,該函數讀取的是默認的三通道圖像,讀取的順序默認情況下是BGR順序,如果想得到單通道(灰度級的)圖像,則可以使用下面的方式:

Mat img=imread(filename,0);

另一個版本:

來自: CSDN yang_xian521 ‘S blog

http://blog.csdn.net/yang_xian521/article/details/7915396

希望作者不要介意,拿來方便使用哈

/************************************************************************
* Copyright(c) 2012  Yang Xian
* All rights reserved.
*
* File:	showManyImage.cpp
* Brief: 
* Version: 1.0
* Author: Yang Xian
* Email: [email protected]
* Date:	2012/08/28
* History:
************************************************************************/
#include"cv.h"
#include "highgui.h"

using namespace cv;
using namespace std;

void imshowMany(const std::string& _winName, const vector<Mat>& _imgs);

int main(void)
{
	vector<Mat> imgs(6);
	imgs[0] = imread("cm.png");
	imgs[1] = imread("wr.png");
	imgs[2] = imread("lina.png");
	imgs[3] = imread("dr.png");
	imgs[4] = imread("pom.png");
	imgs[5] = imread("qop.png");

	imshowMany("DOTA2_Hero", imgs);
	waitKey();
	return 0;
}

void imshowMany(const std::string& _winName, const vector<Mat>& _imgs)
{
	int nImg = (int)_imgs.size();
	
	Mat dispImg;

	int size;
	int x, y;

	// w - Maximum number of images in a row 
	// h - Maximum number of images in a column 
	int w, h;
	// scale - How much we have to resize the image
	float scale;
	int max;

	if (nImg <= 0) 
	{
		printf("Number of arguments too small....\n");
		return;
	}
	else if (nImg > 12)
	{
		printf("Number of arguments too large....\n");
		return;
	}
	
	else if (nImg == 1)
	{
		w = h = 1;
		size = 300;
	}
	else if (nImg == 2)
	{
		w = 2; h = 1;
		size = 300;
	}
	else if (nImg == 3 || nImg == 4)
	{
		w = 2; h = 2;
		size = 300;
	}
	else if (nImg == 5 || nImg == 6)
	{
		w = 3; h = 2;
		size = 200;
	}
	else if (nImg == 7 || nImg == 8)
	{
		w = 4; h = 2;
		size = 200;
	}
	else
	{
		w = 4; h = 3;
		size = 150;
	}

	dispImg.create(Size(100 + size*w, 60 + size*h), CV_8UC3);

	for (int i= 0, m=20, n=20; i<nImg; i++, m+=(20+size))
	{
		x = _imgs[i].cols;
		y = _imgs[i].rows;

		max = (x > y)? x: y;
		scale = (float) ( (float) max / size );

		if (i%w==0 && m!=20)
		{
			m = 20;
			n += 20+size;
		}

		Mat imgROI = dispImg(Rect(m, n, (int)(x/scale), (int)(y/scale)));
		resize(_imgs[i], imgROI, Size((int)(x/scale), (int)(y/scale)));
	}

	namedWindow(_winName);
	imshow(_winName, dispImg);
}

以下是整理成OpenCV 1,0後的代碼版本:

/************************************************************************
* Copyright(c) 2012  Yang Xian
* All rights reserved.
*
* File:	showManyImage.cpp
* Brief: 
* Version: 1.0
* Author: Yang Xian
* Email: [email protected]
* Date:	2012/08/28
* History:
************************************************************************/
#include <cv.h>
#include <highgui.h>
#include <vector>

using namespace std;

#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cxcore.lib")
#pragma comment(lib, "highgui.lib")

void imshowMany(const std::string& _winName, const vector<IplImage*>& _imgs);

int main(void)
{
	std::vector<IplImage*> imgs(6);
	imgs[0] = cvLoadImage("test.png");
	imgs[1] = cvLoadImage("test.png");
	imgs[2] = cvLoadImage("test.png");
	imgs[3] = cvLoadImage("test.png");
	imgs[4] = cvLoadImage("test.png");
	imgs[5] = cvLoadImage("test.png");

	imshowMany("DOTA2_Hero", imgs);
	cvWaitKey();

	return 0;
}

void imshowMany(const std::string& _winName, const vector<IplImage*>& _imgs)
{
	int nImg = (int)_imgs.size();

	IplImage* dispImg;

	int size;
	int x, y;

	// w - Maximum number of images in a row 
	// h - Maximum number of images in a column 
	int w, h;
	// scale - How much we have to resize the image
	float scale;
	int max;

	if (nImg <= 0) 
	{
		printf("Number of arguments too small....\n");
		return;
	}
	else if (nImg > 12)
	{
		printf("Number of arguments too large....\n");
		return;
	}

	else if (nImg == 1)
	{
		w = h = 1;
		size = 300;
	}
	else if (nImg == 2)
	{
		w = 2; h = 1;
		size = 300;
	}
	else if (nImg == 3 || nImg == 4)
	{
		w = 2; h = 2;
		size = 300;
	}
	else if (nImg == 5 || nImg == 6)
	{
		w = 3; h = 2;
		size = 200;
	}
	else if (nImg == 7 || nImg == 8)
	{
		w = 4; h = 2;
		size = 200;
	}
	else
	{
		w = 4; h = 3;
		size = 150;
	}

	dispImg = cvCreateImage(cvSize(100 + size*w, 60 + size*h), IPL_DEPTH_8U, 3);

	for (int i= 0, m=20, n=20; i<nImg; i++, m+=(20+size))
	{
		x = _imgs[i]->height;
		y = _imgs[i]->width;

		max = (x > y)? x: y;
		scale = (float) ( (float) max / size );

		if (i%w==0 && m!=20)
		{
			m = 20;
			n += 20+size;
		}
		cvSetImageROI(dispImg,cvRect(m, n, (int)(x/scale), (int)(y/scale)));
		cvResize(_imgs[i], dispImg);
		cvResetImageROI(dispImg);
	}

	cvNamedWindow(_winName.c_str());
	cvShowImage(_winName.c_str(), dispImg);
}

技術分享圖片

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

OpenCV一個窗口顯示多張圖片