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

Описание проблемы:

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

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

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

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

Когда я использую установленный флаг 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

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

Ситуация:
Windows 7 (x64)
Visual Studio Professional 2012
Версия 2.4.10 OpenCV скомпилирована для 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) {
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;}

1

Решение

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

строка 207 if ((int) image.width! = width || (int) image.height! = высота
|| формат image.frm! = (XI_IMG_FORMAT))

должно быть:

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

Другие решения

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

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

Это не идеально, но это сделает работу.

0

По вопросам рекламы [email protected]