访问Ximea相机并使用OpenCV设置预定义分辨率显示困惑的输出,因为相机的默认分辨率大小Mat

时间:2014-12-19 11:28:26

标签: c++ opencv camera resolution ximea

问题描述:

使用简单的代码,我可以访问我的内部摄像头网络摄像头,也可以更改分辨率。因此,以默认分辨率和预定义分辨率(例如,从640x480到320x240,使用cap.set(CV_CAP_PROP_FRAME_WIDTH,320)和FRAME_HEIGHT,240))显示帧 - 两者都正常工作。

使用相同的代码进行轻微调整以使其与Ximea相机(VideoCapture cap(CV_CAP_XIAPI))配合使用,可以使用默认分辨率。 它是MU9PC_MH,默认分辨率为2592x1944,因此648 x486是所需的较低分辨率。

对于手动设置的分辨率,显示的窗口/抓取帧具有默认分辨率(2592x1944)的大小,并显示此巨大显示中捕获的较低像素数,因此上五分之一充满了疑惑像素窗户的其余部分是黑色的。

对于C ++ with VideoCapture和Mat以及C CvCaptureFromCAM和IplImage *都会产生这种效果。

当我使用set flag CV_CAP_PROP_XI_DOWNSAMPLING时,我可以看到输出图像的像素顺序正确,但显示帧仍然是默认的高分辨率,输出图像显示多次(因子取决于因素我用于下采样)。

我甚至无法将Mat或IplImage强制为预定义的大小,因为然后发生断言或访问冲突的错误(Mat图像(XRES,YRES,CV_8UC3,标量(0,0,255))(帧= cvCreateImage(cvSize(XRES,YRES),IPL_DEPTH_8U,3);.我已经通过frame.type()检查过,输出是CV_8UC3

我想要的是648x486的Ximea相机输出,显示在(理想情况下)相同尺寸的垫子上。 有没有人遇到过同样的问题? 可能是因为我缺乏关于工业相机配置/开发的知识,但是任何帮助都是值得赞赏的。

情况: Windows 7(x64) Visual Studio Professional 2012 为x86编译的OpenCV版本2.4.10,并检查了以下标志:WITH_XIMEA和WITH_OPENGL x86中的简单VS2012项目(包括发布和调试),用于摄像机流和在窗口中显示摄像机帧。

简单代码片段(不是我的,从opencv教程和ximea复制): C ++ - 风格:



#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char **argv) {
	VideoCapture cap(0); // open the default camera
	//VideoCapture cap(CV_CAP_XIAPI);  
  if(!cap.isOpened())  // check if we succeeded
        return -1;
cout<<" "<<cap.get(CV_CAP_PROP_FRAME_WIDTH)<<" "<<cap.get(CV_CAP_PROP_FRAME_HEIGHT)<<endl; //output: 640, 480
	cap.set(CV_CAP_PROP_FRAME_WIDTH,XRES);
	cap.set(CV_CAP_PROP_FRAME_HEIGHT,YRES);	
cout<<" "<<cap.get(CV_CAP_PROP_FRAME_WIDTH)<<"  "<<cap.get(CV_CAP_PROP_FRAME_HEIGHT)<<endl;  //output: 320, 240

 for(;;)
    {
        Mat frame;
        cap >> frame; // get a new frame from camera
        imshow("camera frame", frame);
    if(waitKey(30) == 27) //wait for 'esc' key press
		{
            cout << "esc key is pressed by user" << endl;
			break; 
		}
    }
    return 0;}
&#13;
&#13;
&#13;  C风格:

&#13;
&#13;
#include "cv.h" 
#include "highgui.h" 
#include <stdio.h>  
#include <iostream>

using namespace cv;
using namespace std;
// A Simple Camera Capture Framework 
int main() 
{
   CvCapture* capture = cvCaptureFromCAM( CV_CAP_XIAPI );
   if ( !capture ) {
     fprintf( stderr, "ERROR: capture is NULL \n" );
     getchar();
     return -1;
   }
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 648 ); 
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 486 );
   // Create a window in which the captured images will be presented
   cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );
   // Show the image captured from the camera in the window and repeat
   while ( 1 ) {
     // Get one frame
     IplImage* frame = cvQueryFrame( capture );
cout<<cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH); //output: 648
cout<<cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT); //output: 486

cout<<frame->height<<frame->width<<endl; //output: 1944, 2592
     if ( !frame ) {
       fprintf( stderr, "ERROR: frame is null...\n" );
       getchar();
       break;
     }
     cvShowImage( "mywindow", frame );
     // Do not release the frame!
     //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
     //remove higher bits using AND operator
     if ( (cvWaitKey(10) & 255) == 27 ) break;
   }
   // Release the capture device housekeeping
   cvReleaseCapture( &capture );
   cvDestroyWindow( "mywindow" );
   return 0;
}
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

谢谢karlphillip的回答。不幸的是,你说这不是一个理想的方式。所以我带着昨天的白雪皑皑的天气,自己找到了解决方案: resetCvImage()的{​​{1}}方法存在错误。

  

第207行if((int)image.width!= width ||(int)image.height!= height   || image.frm!=(XI_IMG_FORMAT)格式)

必须是:

cap_ximea.cpp

答案 1 :(得分:0)

VideoCapture::set()返回 bool 以指示方法是否成功。如果不检查此调用的成功/失败并在必要时重新调整捕获的大小,则不应让应用程序继续运行。

事实上,有些相机驱动程序不接受任意尺寸,而且你无能为力。但是,您可以使用默认大小检索框架,然后根据需要cv::resize()检索框架。

这不太理想,但它会完成工作。