Описание проблемы:
С помощью простого кода я могу получить доступ к своей внутренней камере веб-камеры, а также изменить разрешение. Поэтому отображение кадра с разрешением по умолчанию и с предварительно определенным разрешением (например, от 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;}
Спасибо, Карлфиллип, за твой ответ. К сожалению, вы правы, что это был не идеальный способ. Поэтому я взял вчерашнюю снежную погоду и сам нашел решение:
Там есть ошибка в 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)
VideoCapture::set()
возвращает BOOL указать на успех метода. Вы не должны позволять вашему приложению продолжать работу, не проверяя успех / неудачу этого вызова и корректируя размер захвата, когда это необходимо.
Дело в том, что некоторые драйверы камер не принимают произвольные размеры, и вы просто ничего не можете с этим поделать. Однако вы можете извлечь кадр, используя размер по умолчанию, а затем cv::resize()
это для ваших нужд.
Это не идеально, но это сделает работу.