Увеличение разрешения захвата камеры в OpenCV

В моей программе C / C ++ я использую OpenCV для захвата изображений с моей веб-камеры. Камера ( Logitech QuickCam IM ) может снимать в разрешениях 320х240 , 640х480 и 1280х960 . Но, по какой-то странной причине, OpenCV дает мне изображения только с разрешением 320x240 . Вызовы для изменения разрешения с помощью cvSetCaptureProperty () с другими значениями разрешения просто не работают. Как я могу захватывать изображения с другими разрешениями, возможными с моей веб-камерой?

18.08.2008 07:45:33
Примечание. Распространенное неправильное использование термина «разрешение» означает количество пикселей в изображении. Это НЕ то, как его описывают различные стандарты. Разрешение тесно связано с размером пикселей, а не их числом. Вы можете получить 10-мегапиксельное изображение с плохим разрешением или 1-мегапиксельное изображение с высоким разрешением. Даже документация OpenCV достаточно удачливая, не делает эту ошибку. Фактически, если вы, например, перейдете по адресу docs.opencv.org/modules/superres/doc/super_resolution.html и посмотрите на ссылки внизу, вы увидите, что разрешение изображения четко отличается от количества пикселей.
rbaleksandar 29.04.2014 10:43:54
15 ОТВЕТОВ
РЕШЕНИЕ

Кажется, нет решения. Разрешение может быть увеличено до 640x480 с помощью этого хака, которым поделился lifebelt77 . Вот воспроизводимые детали:

Добавьте к highgui.h :

#define CV_CAP_PROP_DIALOG_DISPLAY 8
#define CV_CAP_PROP_DIALOG_FORMAT 9
#define CV_CAP_PROP_DIALOG_SOURCE 10
#define CV_CAP_PROP_DIALOG_COMPRESSION 11
#define CV_CAP_PROP_FRAME_WIDTH_HEIGHT 12

Добавьте функцию icvSetPropertyCAM_VFW в cvcap.cpp :

static int icvSetPropertyCAM_VFW( CvCaptureCAM_VFW* capture, int property_id, double value )
{
    int result = -1;
    CAPSTATUS capstat;
    CAPTUREPARMS capparam;
    BITMAPINFO btmp;

    switch( property_id )
    {
        case CV_CAP_PROP_DIALOG_DISPLAY:
            result = capDlgVideoDisplay(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEODISPLAY,0,0);
            break;

        case CV_CAP_PROP_DIALOG_FORMAT:
            result = capDlgVideoFormat(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEOFORMAT,0,0);
            break;

        case CV_CAP_PROP_DIALOG_SOURCE:
            result = capDlgVideoSource(capture->capWnd);
            //SendMessage(capture->capWnd,WM_CAP_DLG_VIDEOSOURCE,0,0);
            break;

        case CV_CAP_PROP_DIALOG_COMPRESSION:
            result = capDlgVideoCompression(capture->capWnd);
            break;

        case CV_CAP_PROP_FRAME_WIDTH_HEIGHT:
            capGetVideoFormat(capture->capWnd, &btmp, sizeof(BITMAPINFO));
            btmp.bmiHeader.biWidth = floor(value/1000);
            btmp.bmiHeader.biHeight = value-floor(value/1000)*1000;
            btmp.bmiHeader.biSizeImage = btmp.bmiHeader.biHeight *
            btmp.bmiHeader.biWidth * btmp.bmiHeader.biPlanes *
            btmp.bmiHeader.biBitCount / 8;
            capSetVideoFormat(capture->capWnd, &btmp, sizeof(BITMAPINFO));
            break;

        default:
            break;
    }

    return result;
}

и отредактируйте captureCAM_VFW_vtable следующим образом:

static CvCaptureVTable captureCAM_VFW_vtable =
{
6,
(CvCaptureCloseFunc)icvCloseCAM_VFW,
(CvCaptureGrabFrameFunc)icvGrabFrameCAM_VFW,
(CvCaptureRetrieveFrameFunc)icvRetrieveFrameCAM_VFW,
(CvCaptureGetPropertyFunc)icvGetPropertyCAM_VFW,
(CvCaptureSetPropertyFunc)icvSetPropertyCAM_VFW, // was NULL
(CvCaptureGetDescriptionFunc)0
};

Теперь восстановлен highgui.dll .

17
18.08.2008 07:46:15
Этот метод ограничивает разрешение в 640x480?
posit labs 5.04.2012 01:25:42

Я уже занимался обработкой изображений в Linux и пропустил встроенную в OpenCV функциональность камеры, потому что она (как вы обнаружили) неполная.

В зависимости от вашей ОС, вам может больше повезти, если вы будете использовать аппаратные средства по обычным каналам, а не через openCV. Если вы используете Linux, video4linux или video4linux2 должны предоставить вам довольно простой доступ к USB-камерам USB, и вы можете использовать libavc1394 для FireWire. В зависимости от устройства и качества примера кода, которому вы будете следовать, вы сможете запустить устройство с нужными параметрами в течение часа или двух.

Отредактировано, чтобы добавить: Вы самостоятельно, если это Windows. Я думаю, что это не намного сложнее, но я никогда не делал этого.

5
19.08.2008 00:20:02

Я настоятельно рекомендую использовать VideoInput lib , он поддерживает любое устройство DirectShow (даже несколько устройств одновременно) и является более настраиваемым. Вы потратите пять минут, чтобы заставить его играть с OpenCV.

5
1.09.2008 17:15:00

Я использую openCV 1.1pre1 под Windows (библиотека videoinput по умолчанию используется этой версией openCv под windows).

С помощью этих инструкций я могу установить разрешение камеры. Обратите внимание, что я вызываю старый cvCreateCameraCapture вместо cvCaptureFromCam.

capture = cvCreateCameraCapture(cameraIndex);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );


videoFrame = cvQueryFrame(capture);

Я проверил это с помощью веб-камер Logitech, Trust и Philips.

42
1.05.2011 15:41:28
У меня тоже работает на OpenCV 1.1, и я бы рекомендовал это, чтобы быть принятым ответом.
Ray Hidayat 16.07.2009 23:32:43
да, я подтверждаю, что это работает для меня тоже. Текущее принятое решение не является обязательным.
hoju 13.10.2009 05:13:06
В документах говорится, что это не поддерживается, но работает даже при разрешении HD. Однако, если запрошенное разрешение не доступно с камеры, оно автоматически возвращается к разрешению по умолчанию. Текущее принятое решение не является обязательным.
Nestor 9.03.2010 01:25:12
проверьте возвращаемые значения из свойства cvSetCapture, не все камеры примут инструкцию
Martin Beckett 5.10.2010 21:30:43
cvQueryFrame(capture);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, any_supported_size );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, any_supported_size);

cvQueryFrame(capture);

должно быть достаточно!

-3
23.03.2011 21:21:40
Может быть, вы можете попытаться объяснить больше о вашем коде. Поскольку вы ответили на очень старый вопрос, оригинальный спрашивающий может не вернуться, но может помочь другим.
Swapnil 19.12.2012 16:36:02

Попробуй это:

capture = cvCreateCameraCapture(-1);
//set resolution
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, frameWidth);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, frameHeight);
-1
5.10.2010 21:24:47
Итак, вы предлагаете установить начальный параметр -1, тогда? Чего это достичь?
JoshDM 10.12.2012 16:21:10
Начальный параметр -1 для cvCreateCameraCapture выберет первое доступное устройство / камеру.
Matthias 29.03.2013 11:34:42

Проверьте этот билет: https://code.ros.org/trac/opencv/ticket/376

«Решение состоит в том, чтобы использовать более новую оболочку на основе libv4l.

  1. установить libv4l-dev (так называется в Ubuntu)

  2. Перезапустите cmake, вы увидите «V4L / V4L2: Использование libv4l»

  3. выполнить заново. Теперь разрешение можно изменить. протестировано со встроенным isight на MBP. "

Это исправило это для меня с помощью Ubuntu и, возможно, подойдет и вам.

5
28.10.2010 10:33:09
Где должен быть назван cmake?
sorush-r 3.12.2011 17:22:59
Yo-L 13.12.2011 08:54:04

Я обнаружил, что в Windows (от Win98 до WinXP SP3) OpenCV часто использует библиотеку VFW от Microsoft для доступа к камере. Проблема в том, что он часто очень медленный (скажем, максимум 15 кадров в секунду) и глючит (следовательно, почему cvSetCaptureProperty часто не работает). К счастью, вы можете изменить разрешение в другом программном обеспечении (в частности, «AMCAP», которое является легко доступной демонстрационной программой), и это повлияет на разрешение, которое будет использовать OpenCV. Например, вы можете запустить AMCAP, чтобы установить разрешение 640x480, а затем OpenCV будет использовать его по умолчанию с этого момента!

Но если вы можете использовать другую библиотеку доступа к камере Windows, такую ​​как библиотека "videoInput", http://muonics.net/school/spring05/videoInput/, которая обращается к камере с помощью очень эффективного DirectShow (часть DirectX). Или, если у вас камера профессионального качества, то часто она поставляется с пользовательским API, который позволяет вам получить доступ к камере, и вы можете использовать его для быстрого доступа с возможностью изменения разрешения и многих других вещей.

0
10.02.2012 07:00:52

Под Windows попробуйте использовать библиотеку VideoInput: http://robocraft.ru/blog/computervision/420.html

0
25.01.2012 12:15:49
Работает ли VideoInput для захвата изображений с несколькими экспозициями?
Abc 4.09.2017 12:03:19

Я использую Debian и Ubuntu, у меня была та же проблема, я не мог изменить разрешение видео, используя CV_CAP_PROP_FRAME_WIDTH и CV_CAP_PROP_FRAME_HEIGHT

Выяснилось, что причиной стала пропавшая библиотека. Я установил lib4l-dev через synaptic, перестроил OpenCV, и проблема решена!

4
28.04.2011 10:06:45

Я публикую это, чтобы никто больше не тратил время на эту функцию setproperty. Я потратил на это 2 дня, чтобы убедиться, что ничего не работает. Поэтому я выкопал код (я установил библиотеку в первый раз). Это то, что на самом деле происходит - cvSetCaptureProperty, вызывает setProperty внутри класса CvCapture и вот что setProperty ничего не делает. Это просто возвращает ложь. Вместо этого я воспользуюсь другой библиотекой для подачи OpenCV видео / изображений. Я использую OpenCV 2.2

2
1.05.2011 15:16:52

cvSetCaptureProperty (захват, CV_CAP_PROP_FRAME_WIDTH, WIDTH);

cvSetCaptureProperty (захват, CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);

cvQueryFrame (захват);

Это не будет работать с OpenCV 2.2, но если вы используете OpenCV 2.1, он будет работать нормально!

0
6.06.2011 09:52:00

Если вы находитесь на платформе Windows, попробуйте DirectShow (IAMStreamConfig).

http://msdn.microsoft.com/en-us/library/dd319784%28v=vs.85%29.aspx

0
12.06.2011 09:56:29

Код, который я, наконец, начал работать в Python, как только Аарон Хаун указал, что мне нужно определить аргументы функции set перед их использованием.

#Camera_Get_Set.py
#By Forrest L. Erickson of VRX Company Inc. 8-31-12.
#Opens the camera and reads and reports the settings.
#Then tries to set for higher resolution.
#Workes with Logitech C525 for resolutions 960 by 720 and 1600 by 896


import cv2.cv as cv
import numpy

CV_CAP_PROP_POS_MSEC = 0
CV_CAP_PROP_POS_FRAMES = 1
CV_CAP_PROP_POS_AVI_RATIO = 2
CV_CAP_PROP_FRAME_WIDTH = 3
CV_CAP_PROP_FRAME_HEIGHT = 4
CV_CAP_PROP_FPS = 5
CV_CAP_PROP_POS_FOURCC = 6
CV_CAP_PROP_POS_FRAME_COUNT = 7
CV_CAP_PROP_BRIGHTNESS = 8
CV_CAP_PROP_CONTRAST = 9
CV_CAP_PROP_SATURATION = 10
CV_CAP_PROP_HUE = 11

CV_CAPTURE_PROPERTIES = tuple({
CV_CAP_PROP_POS_MSEC,
CV_CAP_PROP_POS_FRAMES,
CV_CAP_PROP_POS_AVI_RATIO,
CV_CAP_PROP_FRAME_WIDTH,
CV_CAP_PROP_FRAME_HEIGHT,
CV_CAP_PROP_FPS,
CV_CAP_PROP_POS_FOURCC,
CV_CAP_PROP_POS_FRAME_COUNT,
CV_CAP_PROP_BRIGHTNESS,
CV_CAP_PROP_CONTRAST,
CV_CAP_PROP_SATURATION,
CV_CAP_PROP_HUE})

CV_CAPTURE_PROPERTIES_NAMES = [
"CV_CAP_PROP_POS_MSEC",
"CV_CAP_PROP_POS_FRAMES",
"CV_CAP_PROP_POS_AVI_RATIO",
"CV_CAP_PROP_FRAME_WIDTH",
"CV_CAP_PROP_FRAME_HEIGHT",
"CV_CAP_PROP_FPS",
"CV_CAP_PROP_POS_FOURCC",
"CV_CAP_PROP_POS_FRAME_COUNT",
"CV_CAP_PROP_BRIGHTNESS",
"CV_CAP_PROP_CONTRAST",
"CV_CAP_PROP_SATURATION",
"CV_CAP_PROP_HUE"]


capture = cv.CaptureFromCAM(0)

print ("\nCamera properties before query of frame.")
for i in range(len(CV_CAPTURE_PROPERTIES_NAMES)):
#    camera_valeus =[CV_CAPTURE_PROPERTIES_NAMES, foo]
    foo = cv.GetCaptureProperty(capture, CV_CAPTURE_PROPERTIES[i])
    camera_values =[CV_CAPTURE_PROPERTIES_NAMES[i], foo]
#    print str(camera_values)
    print str(CV_CAPTURE_PROPERTIES_NAMES[i]) + ": " + str(foo)


print ("\nOpen a window for display of image")
cv.NamedWindow("Camera", 1)
while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("Camera", img)
    if cv.WaitKey(10) == 27:
        break
cv.DestroyWindow("Camera")


#cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1024)
#cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 768)
cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1600)
cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 896)


print ("\nCamera properties after query and display of frame.")
for i in range(len(CV_CAPTURE_PROPERTIES_NAMES)):
#    camera_valeus =[CV_CAPTURE_PROPERTIES_NAMES, foo]
    foo = cv.GetCaptureProperty(capture, CV_CAPTURE_PROPERTIES[i])
    camera_values =[CV_CAPTURE_PROPERTIES_NAMES[i], foo]
#    print str(camera_values)
    print str(CV_CAPTURE_PROPERTIES_NAMES[i]) + ": " + str(foo)


print ("/nOpen a window for display of image")
cv.NamedWindow("Camera", 1)
while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("Camera", img)
    if cv.WaitKey(10) == 27:
        break
cv.DestroyWindow("Camera")
5
3.09.2012 20:26:00

Только одна информация, которая может быть полезна людям, испытывающим трудности с изменением разрешения захвата по умолчанию (640 x 480)! Я экспериментировал с такой проблемой с opencv 2.4.x и одной камерой Logitech ... и нашел один обходной путь!

Обнаруженное мной поведение заключается в том, что формат по умолчанию устанавливается в качестве начальных параметров при запуске захвата камеры (cvCreateCameraCapture), и все запросы об изменении высоты или ширины:

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, ... 

или

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, ...

невозможно потом! Фактически, с добавлением ошибки возврата функций ioctl я обнаружил, что драйвер V4l2 возвращает EBUSY для этих запросов! Следовательно, одним из обходных путей должно быть изменение значения по умолчанию непосредственно в файле highgui / cap_v4l.cpp:

*#define DEFAULT_V4L_WIDTH  1280    // Originally 640* 

*#define DEFAULT_V4L_HEIGHT 720     // Originally 480*

После этого я просто перекомпилировал opencv ... и приехал, чтобы получить 1280 x 720 без проблем! Конечно, лучшим решением будет остановить сбор данных, изменить параметры и перезапустить поток после этого, но я недостаточно знаком с opencv для этого!

Надеюсь, это поможет.

Мишель Беги

0
10.09.2015 14:19:40