Search code examples
c++opencvresolutions

OpenCV: Get camera resolutions C++


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


Solution

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