问题描述:
使用简单的代码,我可以访问我的内部摄像头摄像头,并改变分辨率。因此,以默认分辨率和预定义分辨率(例如,640x480到320x240,使用cap.set(CV_CAP_PROP_FRAME_WIDTH,320)和FRAME_HEIGHT,240)显示帧--两者都工作得很好。
使用相同的代码,稍微进行适配,这样它就可以与Ximea摄像机(VideoCapture cap(CV_CAP_XIAPI))一起工作,这样就可以实现默认的分辨率。它是一个默认分辨率为2592x1944的MU9PC_MH,因此648 x486是所需的较低分辨率。
对于手动设置的分辨率,显示的窗口/抓取帧具有默认分辨率(2592x1944)的大小,并在这个巨大的显示中显示捕获像素的较低数量,因此上五分之四充满了困惑的像素,而窗口的其余部分则是黑色的。
这种效果发生在两种情况下,C++和VideoCapture和Mat,以及C CvCaptureFromCAM和IplImage*。
当我使用set标志CV_CAP_PROP_XI_DOWNSAMPLING时,我可以看到以正确顺序显示像素的输出图像,但是显示帧仍然具有默认的高分辨率,并且输出图像被多次显示(该因子取决于我用于下采样的因子)。
我甚至无法强制Mat或IplImage达到预定义的大小,因为这时会出现断言或访问冲突错误(Mat图像(XRES、YRES、CV_8UC3、Scalar(0,0,255)) (frame = cvCreateImage(cvSize( XRES,YRES),IPL_DEPTH_8U,3))。我已经检查了frame.type(),输出是一个CV_8UC3
我想要的是一个西美相机输出的648x486显示在一个(理想的)相同大小的垫。有谁遇到过同样的问题吗?这可能是因为我对工业相机的配置/开发缺乏了解,但任何帮助都是非常感谢的。
情境: Windows 7(x64) 2012 OpenCV版本2.4.10,为x86编译,选中了以下标志: x86中的WITH_XIMEA和WITH_OPENGL简单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;}C风格:
#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;
}
发布于 2015-01-25 09:14:41
谢谢你的回答。不幸的是,你是对的,这不是一个理想的方式。所以我取了昨天下雪的时间,自己找到了解决方案:resetCvImage()的cap_ximea.cpp方法有一个错误。
第207号行if( (int)image.width !=宽幅\x\ (int)image.height != line \x\x_ image.frm != (XI_IMG_FORMAT)格式)
必须:
if( (int)image.width != **frame->**width || (int)image.height != **frame->**height || image.frm != (XI_IMG_FORMAT)format)发布于 2014-12-20 23:35:28
VideoCapture::set()返回一个bool来表示该方法的成功。如果不检查此调用的成功/失败以及在必要时重新调整捕获的大小,您就不应该让应用程序继续运行。
事实上,有些相机驱动程序不接受任意尺寸,而且你对此无能为力。但是,您可以使用默认大小检索框架,然后根据需要对其进行cv::resize()。
这并不理想,但它会完成任务的。
https://stackoverflow.com/questions/27565133
复制相似问题