2013-08-22 3 views

ответ

2

Для окон вы можете перечислить все камеры и решения, используя этот код:

#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; 
} 
+1

добавление компоновщика: Strmiids.lib – Indy9000

+0

Прошу прощения, но как это связано с OpenCV? – wirher

+0

Это позволяет решить (для окон) отсутствие такой функции в opencv. –

1

Вы можете использовать функцию VideoCapture::get(int propId). В пределах этой функции вы можете получить два свойства, чтобы получить разрешение видео. CV_CAP_PROP_FRAME_WIDTH и CV_CAP_PROP_FRAME_HEIGHT, которые дают вам и высоту видеопотока соответственно.

+5

Да, я знаю, но я имею в виду, как получить все возможные разрешения? (какая камера поддерживает) –

1

Вот решение с OpenCV. Но это очень медленно, а затем, вероятно, бесполезно для большинства приложений. Во всяком случае, приведенный ниже код отображает поддерживаемые разрешения. Идея состоит в том, чтобы анализировать разрешения снижаться и проверять фактическое разрешение в каждый момент времени. Просто вызовите query_resolutions() с указателем на ваш cv :: VideoCapture.

// return true if the actual resolution has changed 
bool test_resolution(cv::VideoCapture* camera, int width, int height, int &actualWidth, int &actualHeight) 
{ 
    camera->set(CV_CAP_PROP_FRAME_WIDTH, width); 
    camera->set(CV_CAP_PROP_FRAME_HEIGHT, height); 
    width = static_cast<int>(camera->get(CV_CAP_PROP_FRAME_WIDTH)); 
    height = static_cast<int>(camera->get(CV_CAP_PROP_FRAME_HEIGHT)); 

    if (width != actualWidth || height != actualHeight) 
    { 
     actualWidth = width; 
     actualHeight = height; 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

void query_resolutions(cv::VideoCapture* camera) 
{ 
    // Save current resolution 
    const int current_width = static_cast<int>(camera->get(CV_CAP_PROP_FRAME_WIDTH)); 
    const int current_height = static_cast<int>(camera->get(CV_CAP_PROP_FRAME_HEIGHT)); 

    int actualWidth = 10000; 
    int actualHeight = 10000; 
    int delta = 0; 
    do 
    { 
     // first, test to decrease width only 
     bool resoChanged = test_resolution(camera, actualWidth - delta, actualHeight, actualWidth, actualHeight); 
     if (!resoChanged) 
     { 
      // then, try to decrease height only 
      resoChanged = test_resolution(camera, actualWidth, actualHeight - delta, actualWidth, actualHeight); 
     } 
     if (!resoChanged) 
     { 
      // finally, try to decrease width and height 
      resoChanged = test_resolution(camera, actualWidth - delta, actualHeight - delta, actualWidth, actualHeight); 
     } 
     if (resoChanged) 
     { 
      delta = 100; 
      std::cout << actualWidth << "x" << actualHeight << std::endl; 
     } 
     else 
     { 
      // if these tries don't change the resolution, let's increase delta 
      delta += 100; 
     } 
    } 
    while (actualWidth > delta && actualHeight > delta); 

    // Restore resolution 
    camera->set(CV_CAP_PROP_FRAME_WIDTH, current_width); 
    camera->set(CV_CAP_PROP_FRAME_HEIGHT, current_height); 
}