2014-12-19 4 views
1
описание

задачи камеры:Доступ Ximea камеры и установки предопределенного разрешение с OpenCV показывает недоуменный выход, из-за Мат в размере разрешения по умолчанию

С простой код, который я могу получить доступ к внутренней веб камеры, а также изменить разрешение. Таким образом, отображение кадра с разрешением по умолчанию и с предопределенным разрешением (например, от 640x480 до 320x240, с cap.set (CV_CAP_PROP_FRAME_WIDTH, 320) и FRAME_HEIGHT, 240)) - оба работают нормально.

Используя тот же код с небольшой адаптацией, чтобы он работал с камерой Ximea (крышка VideoCapture (CV_CAP_XIAPI)), работает для разрешения по умолчанию. Это MU9PC_MH с разрешением по умолчанию 2592x1944, поэтому 648 x486 - это более низкое разрешение, которое требуется.

Для установленного вручную разрешения отображаемый оконный/захваченный кадр имеет размер разрешения по умолчанию (2592x1944) и показывает меньшее количество пикселей захвата на этом огромном дисплее, так что верхние пятые заполнены озадаченным пикселей, а остальная часть окна черная.

Этот эффект происходит как для C++, так и для VideoCapture и Mat и для C CvCaptureFromCAM и IplImage *.

Когда я использую установленный флаг CV_CAP_PROP_XI_DOWNSAMPLING, я могу видеть выходное изображение с пикселями в правильном порядке, но кадр отображения по-прежнему имеет высокое разрешение по умолчанию, а выходное изображение отображается несколько раз (коэффициент зависит от фактор, который я использую для понижающей дискретизации).

Я даже не могу заставить Mat или IplImage иметь предопределенный размер, потому что тогда возникает ошибка утверждения или нарушения доступа (изображение мата (XRES, YRES, CV_8UC3, Scalar (0,0,255)) (кадр = cvCreateImage (cvSize (XRES, YRES), IPL_DEPTH_8U, 3) ;. Я проверил через frame.type(), что выход является CV_8UC3

Что я хочу - это выход камеры Ximea 648x486, показанный на (в идеале) Mat того же размера. ли кто-нибудь опыт с той же проблемой? Возможно, это происходит из-за отсутствия в моих знаний о промышленной конфигурации камеры/развития, но любая помощь приветствуется.

ситуации : Windows 7 (x64) Visual Studio Professional 2012 OpenCV Version 2.4.10, скомпилированный для x86 с проверенными флажками: WITH_XIMEA и WITH_OPENGL Простой проект VS2012 на x86 (как для выпуска, так и для отладки) для потоковой передачи и отображения кадра камеры в окно.

Простой фрагменты кода (не мои, скопированы из 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) { 
 
\t VideoCapture cap(0); // open the default camera 
 
\t //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 
 
\t cap.set(CV_CAP_PROP_FRAME_WIDTH,XRES); 
 
\t cap.set(CV_CAP_PROP_FRAME_HEIGHT,YRES); \t 
 
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 
 
\t \t { 
 
      cout << "esc key is pressed by user" << endl; 
 
\t \t \t break; 
 
\t \t } 
 
    } 
 
    return 0;}
C-Style:

#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; 
 
}

ответ

1

спасибо karlphillip за ваш ответ. К сожалению, вы правы, что это был не идеальный путь. Поэтому я беру вчерашнюю снежную шляпу и сам нашел решение: Ошибка в методе resetCvImage()cap_ximea.cpp.

линия 207, если (! = Ширина || (интермедиат) image.height! =! =() Формат XI_IMG_FORMAT (интермедиат) image.width высота || image.frm)

имеет :

if((int)image.width != **frame->**width || (int)image.height != **frame->**height || image.frm != (XI_IMG_FORMAT)format) 
+0

Вы строили OpenCV с этим исправлением, и это сработало? – karlphillip

+0

Да, точно. Попробовал это также с cap.set (CV_CAP_PROP_XI_DOWNSAMPLING, 2), так что разрешение сократилось наполовину (= 1296 972), cap.set (CV_CAP_PROP_FRAME_WIDTH, 648) и т. Д. - просто чтобы убедиться, что он работает. Изменение метода приводит к тому, что первоначально созданный Ipimage, который имеет размер камеры по умолчанию (= 2592x1944), также обновляет измененные свойства. – AfterEight

0

VideoCapture::set() возвращается a bool, чтобы указать успешность метод. Вы не должны допустить, чтобы ваше приложение продолжало работать, не проверяя успех/сбой этого вызова и при необходимости корректируя размер захвата.

Дело в том, что некоторые драйверы камеры не принимают произвольные размеры, и вы ничего не можете с этим поделать.Тем не менее, вы можете получить фрейм, используя размер по умолчанию, а затем cv::resize() его по вашим потребностям.

Это не идеальный вариант, но он выполнит свою работу.