OpenCV: get C ++ camera resolution

Is there a way in OpenCV to get a list of camera permissions?

+4
source share
3 answers

For windows, you can list 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 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; } 
+2
source

You can use the VideoCapture :: get (int propId) function . Within this function, you can get two properties to get the video resolution. CV_CAP_PROP_FRAME_WIDTH and CV_CAP_PROP_FRAME_HEIGHT , which give you the height of the video stream, respectively.

+1
source

Here is a solution with OpenCV. But it is very slow , and then probably useless for most applications. Anyway, the code below displays the supported permissions. The idea is to analyze the permissions to decline and check the actual resolution at each point in time. Just call query_resolutions () with a pointer to your 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 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); } 
+1
source

Source: https://habr.com/ru/post/1498290/


All Articles