Pergunta

No meu programa C/C++, estou usando OpenCV para capturar imagens da minha webcam.A câmera (Logitech QuickCam IM) pode capturar em resoluções 320x240, 640x480 e 1280x960.Mas, por alguma razão estranha, o OpenCV me dá imagens de resolução 320x240 apenas.Chamadas para alterar a resolução usando cvSetCaptureProperty() com outros valores de resolução simplesmente não funcionam.Como faço para capturar imagens com as outras resoluções possíveis com minha webcam?

Foi útil?

Solução 2

Não parece haver uma solução.A resolução pode ser aumentada para 640x480 usando esse truque compartilhado por cinto salva-vidas77.Aqui estão os detalhes reproduzidos:

adicionar à 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

Adicione a função icvSetPropertyCAM_VFW para 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;
}

e editar captureCAM_VFW_vtable como segue:

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

Agora reconstruído highgui.dll.

Outras dicas

Estou usando o openCV 1.1pre1 no Windows (a biblioteca videoinput é usada por padrão por esta versão do openCv no Windows).

Com estas instruções posso definir a resolução da câmera.Observe que eu chamo o antigo cvCreateCameraCapture em vez de cvCaptureFromCam.

capture = cvCreateCameraCapture(cameraIndex);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );


videoFrame = cvQueryFrame(capture);

Eu testei com webcams Logitech, Trust e Philips

Já fiz processamento de imagens no Linux antes e pulei a funcionalidade integrada da câmera do OpenCV porque ela está (como você descobriu) incompleta.

Dependendo do seu sistema operacional, você pode ter mais sorte indo direto para o hardware através dos canais normais, em vez de através do openCV.Se você estiver usando Linux, video4linux ou video4linux2 devem fornecer acesso relativamente trivial a webcams USB e você pode usar libavc1394 para firewire.Dependendo do dispositivo e da qualidade do código de exemplo que você segue, você poderá fazer o dispositivo funcionar com os parâmetros desejados em uma ou duas horas.

Editado para adicionar:Você está sozinho se for Windows.Imagino que não seja muito mais difícil, mas nunca fiz isso.

Eu sugiro fortemente usar Biblioteca VideoInput, ele suporta qualquer dispositivo DirectShow (até mesmo vários dispositivos ao mesmo tempo) e é mais configurável.Você gastará cinco minutos para jogar com o OpenCV.

Confira esse ingresso:https://code.ros.org/trac/opencv/ticket/376

"A solução é usar o wrapper mais recente baseado em libv4l.

  1. instale libv4l-dev (é assim que é chamado no Ubuntu)

  2. execute novamente o cmake, você verá "V4L/V4L2:Usando libv4l"

  3. reexecutar fazer.agora a resolução pode ser alterada.testado com isight integrado no MBP."

Isso corrigiu o problema para mim usando o Ubuntu e também pode funcionar para você.

Código que finalmente comecei a trabalhar em Python quando Aaron Haun apontou que eu precisava definir os argumentos da função set antes de usá-los.

#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")

Estou usando debian e ubuntu, tive o mesmo problema, não consegui alterar a resolução da entrada de vídeo usando CV_CAP_PROP_FRAME_WIDTH e CV_CAP_PROP_FRAME_HEIGHT

Descobri que o motivo era uma biblioteca desaparecida.Eu instalei lib4l-dev através da sináptica, reconstruído OpenCV e o problema está RESOLVIDO!

Estou postando isso para garantir que ninguém mais perca tempo com esta função setproperty.Passei 2 dias nisso para ver que nada parecia estar funcionando.Então descobri o código (instalei a biblioteca na primeira vez).Isso é o que realmente acontece - cvSetCaptureProperty, chama setProperty dentro da classe CvCapture e eis que setProperty não faz nada.Apenas retorna falso.Em vez disso, usarei outra biblioteca para alimentar o OpenCV com captura de vídeo/imagens.Estou usando OpenCV 2.2

cvSetCaptureProperty(captura, CV_CAP_PROP_FRAME_WIDTH, WIDTH);

cvSetCaptureProperty(captura, CV_CAP_PROP_FRAME_HEIGHT, ALTURA);

cvQueryFrame(captura);

Isso não funcionará com OpenCV 2.2, mas se você usar OpenCV 2.1 funcionará bem!

Se você estiver na plataforma Windows, experimente DirectShow (IAMStreamConfig).

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

No Windows, tente usar a biblioteca VideoInput:http://robocraft.ru/blog/computervision/420.html

Acho que no Windows (do Win98 ao WinXP SP3), o OpenCV costuma usar a biblioteca VFW da Microsoft para acesso à câmera.O problema com isso é que geralmente é muito lento (digamos, uma captura de quadro máxima de 15 FPS) e com erros (daí o motivo pelo qual cvSetCaptureProperty geralmente não funciona).Felizmente, geralmente você pode alterar a resolução em outro software (particularmente "AMCAP", que é um programa de demonstração facilmente disponível) e isso afetará a resolução que o OpenCV usará.Por exemplo, você pode executar o AMCAP para definir a resolução para 640x480, e então o OpenCV usará isso por padrão a partir desse ponto!

Mas se você puder usar uma biblioteca diferente de acesso à câmera do Windows, como a biblioteca "videoInput" http://muonics.net/school/spring05/videoInput/ que acessa a câmera usando DirectShow muito eficiente (parte do DirectX).Ou se você tiver uma câmera de qualidade profissional, muitas vezes ela virá com uma API personalizada que permite acessar a câmera, e você pode usá-la para acesso rápido com a capacidade de alterar a resolução e muitas outras coisas.

Apenas uma informação que pode ser valiosa para pessoas com dificuldades em alterar a resolução padrão de captura (640 x 480)!Eu experimentei esse problema com opencv 2.4.x e uma câmera Logitech ...e encontrei uma solução alternativa!

O comportamento que detectei é que o formato padrão é configurado como parâmetros iniciais quando a captura da câmera é iniciada (cvCreateCameraCapture) e todas as solicitações para alterar a altura ou largura:

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, ... 

ou

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, ...

não são possíveis depois!Efetivamente, descobri ao adicionar erro de retorno de funções ioctl que o driver V4l2 está retornando EBUSY para os pedidos!Portanto, uma solução alternativa deve ser alterar o valor padrão diretamente em highgui/cap_v4l.cpp :

*#define DEFAULT_V4L_WIDTH  1280    // Originally 640* 

*#define DEFAULT_V4L_HEIGHT 720     // Originally 480*

Depois disso, apenas recompilei opencv ...e cheguei a obter 1280 x 720 sem nenhum problema!É claro que uma solução melhor seria interromper a aquisição, alterar os parâmetros e reiniciar o stream depois, mas não estou familiarizado o suficiente com o opencv para fazer isso!

Espero que ajude.

Michel BEGEY

Experimente isto:

capture = cvCreateCameraCapture(-1);
//set resolution
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, frameWidth);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, frameHeight);
cvQueryFrame(capture);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, any_supported_size );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, any_supported_size);

cvQueryFrame(capture);

deve ser apenas o suficiente!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top