Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV: Get camera resolutions C++

Is there any way in OpenCV to get the list of camera's resolutions?

like image 564
mariusz-s Avatar asked Aug 22 '13 01:08

mariusz-s


1 Answers

For windows you can enumerate all cameras and resolutions using this code:

#include <dshow.h>
#include <locale>
#include <vector>
using namespace std;

#define BLUE    0x0001
#define GREEN   0x0002
#define RED     0x0004
#define GRAY    0x0007

static void setcolor(unsigned int color)                                                                                                         
{
    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); 
    SetConsoleTextAttribute(hCon,color|FOREGROUND_INTENSITY);
}

void _FreeMediaType(AM_MEDIA_TYPE& mt)
{
    if (mt.cbFormat != 0)
    {
        CoTaskMemFree((PVOID)mt.pbFormat);
        mt.cbFormat = 0;
        mt.pbFormat = NULL;
    }
    if (mt.pUnk != NULL)
    {
        // pUnk should not be used.
        mt.pUnk->Release();
        mt.pUnk = NULL;
    }
}


HRESULT CamCaps(IBaseFilter *pBaseFilter)
{
    HRESULT hr = 0;
    vector<IPin*> pins;
    IEnumPins *EnumPins;
    pBaseFilter->EnumPins(&EnumPins);
    pins.clear();
    for(;;)
    {
        IPin *pin;
        hr=EnumPins->Next(1,&pin,NULL);
        if(hr!=S_OK){break;}
        pins.push_back(pin);
        pin->Release();
    }   
    EnumPins->Release();

    printf("Device pins number: %d\n",pins.size());

    PIN_INFO pInfo; 
    for(int i=0;i<pins.size();i++)
    {
        pins[i]->QueryPinInfo(&pInfo);

        setcolor(RED);

        if(pInfo.dir==0)
        {
            wprintf(L"Pin name: %s (Ввод)\n",pInfo.achName);
        }

        if(pInfo.dir==1)
        {
            wprintf(L"Pin name: %s (Выход)\n",pInfo.achName);
        }

        IEnumMediaTypes *emt=NULL;
        pins[i]->EnumMediaTypes(&emt);

        AM_MEDIA_TYPE *pmt;

        vector<SIZE> modes;
        setcolor(GRAY);
        wprintf(L"Avialable resolutions.\n",pInfo.achName);
        for(;;)
        {   
            hr=emt->Next(1,&pmt,NULL);
            if(hr!=S_OK){break;}

            if ( (pmt->formattype == FORMAT_VideoInfo) &&
                //(pmt->subtype == MEDIASUBTYPE_RGB24) &&
                (pmt->cbFormat >= sizeof(VIDEOINFOHEADER)) &&
                (pmt->pbFormat != NULL) )
            {
                VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
                SIZE s;
                // Get frame size
                s.cy=pVIH->bmiHeader.biHeight;
                s.cx=pVIH->bmiHeader.biWidth;
                // Битрейт
                unsigned int bitrate=pVIH->dwBitRate;
                modes.push_back(s);
                // Bits per pixel
                unsigned int bitcount=pVIH->bmiHeader.biBitCount;
                REFERENCE_TIME t=pVIH->AvgTimePerFrame; // blocks (100ns) per frame
                int FPS=floor(10000000.0/static_cast<double>(t));
                printf("Size: x=%d\ty=%d\tFPS: %d\t bitrate: %ld\tbit/pixel:%ld\n",s.cx,s.cy,FPS,bitrate,bitcount);
            }
            _FreeMediaType(*pmt);
        }
        //----------------------------------------------------
        // 
        // 
        // 
        //----------------------------------------------------
        modes.clear();
        emt->Release();
    }

    pins.clear();

    return S_OK;
}

/*
* Do something with the filter. In this sample we just test the pan/tilt properties.
*/
void process_filter(IBaseFilter *pBaseFilter)
{
    CamCaps(pBaseFilter);
}


/*
* Enumerate all video devices
*
* See also:
*
* Using the System Device Enumerator:
*     http://msdn2.microsoft.com/en-us/library/ms787871.aspx
*/
int enum_devices()
{
    HRESULT hr;
    setcolor(GRAY);
    printf("Enumeraring videoinput devices ...\n");

    // Create the System Device Enumerator.
    ICreateDevEnum *pSysDevEnum = NULL;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
        IID_ICreateDevEnum, (void **)&pSysDevEnum);
    if(FAILED(hr))
    {
        fprintf(stderr, "Error. Can't create enumerator.\n");
        return hr;
    }

    // Obtain a class enumerator for the video input device category.
    IEnumMoniker *pEnumCat = NULL;
    hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);

    if(hr == S_OK) 
    {
        // Enumerate the monikers.
        IMoniker *pMoniker = NULL;
        ULONG cFetched;
        while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
        {
            IPropertyBag *pPropBag;
            hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
                (void **)&pPropBag);
            if(SUCCEEDED(hr))
            {
                // To retrieve the filter's friendly name, do the following:
                VARIANT varName;
                VariantInit(&varName);
                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
                if (SUCCEEDED(hr))
                {
                    // Display the name in your UI somehow.
                    setcolor(GREEN);
                    wprintf(L"------------------> %s <------------------\n", varName.bstrVal);
                }
                VariantClear(&varName);

                // To create an instance of the filter, do the following:
                IBaseFilter *pFilter;
                hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
                    (void**)&pFilter);

                process_filter(pFilter);

                //Remember to release pFilter later.
                pPropBag->Release();
            }
            pMoniker->Release();
        }
        pEnumCat->Release();
    }
    pSysDevEnum->Release();

    return 0;
}


int wmain(int argc, wchar_t* argv[])
{
    setlocale(LC_ALL, "Russian");
    int result;

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    result = enum_devices();

    CoUninitialize();
    getchar();
    return result;
}
like image 59
Andrey Smorodov Avatar answered Oct 07 '22 05:10

Andrey Smorodov