سؤال

في برنامجي C/C++، أستخدم OpenCV لالتقاط الصور من كاميرا الويب الخاصة بي.الكاميرا (لوجيتك QuickCam IM) يمكن التقاطها بدقة 320x240, 640x480 و 1280x960.ولكن، لسبب غريب، يعطيني OpenCV صورًا ذات دقة عالية 320x240 فقط.يدعو لتغيير القرار باستخدام cvSetCaptureProperty() مع قيم الدقة الأخرى لا تعمل.كيف يمكنني التقاط الصور بالدقة الأخرى الممكنة باستخدام كاميرا الويب الخاصة بي؟

هل كانت مفيدة؟

المحلول 2

لا يبدو أن هناك حلا.يمكن زيادة القرار إلى 640x480 استخدام هذا الاختراق نشر بواسطة حزام النجاة77.وهنا التفاصيل مستنسخة:

اضف إليه 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

أضف الوظيفة icvSetPropertyCAM_VFW ل 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;
}

وتحرير CaptureCAM_VFW_vtable كالتالي:

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

أعيد بناؤها الآن Highgui.dll.

نصائح أخرى

أنا أستخدم openCV 1.1pre1 ضمن Windows (يتم استخدام مكتبة إدخال الفيديو افتراضيًا بواسطة هذا الإصدار من openCv ضمن Windows).

باستخدام هذه التعليمات، يمكنني ضبط دقة الكاميرا.لاحظ أنني أقوم باستدعاء cvCreateCameraCapture القديم بدلاً من cvCaptureFromCam.

capture = cvCreateCameraCapture(cameraIndex);

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );


videoFrame = cvQueryFrame(capture);

لقد اختبرت ذلك باستخدام كاميرات الويب Logitech وTrust وPhilips

لقد قمت بمعالجة الصور في نظام التشغيل Linux من قبل وتخطيت وظيفة الكاميرا المدمجة في OpenCV لأنها (كما اكتشفت) غير مكتملة.

اعتمادًا على نظام التشغيل لديك، قد يكون حظك أكبر في الانتقال مباشرة إلى الأجهزة من خلال القنوات العادية بدلاً من الانتقال من خلال openCV.إذا كنت تستخدم Linux، فمن المفترض أن يمنحك video4linux أو video4linux2 وصولاً بسيطًا نسبيًا إلى كاميرات الويب USB ويمكنك استخدام libavc1394 لـ firewire.اعتمادًا على الجهاز وجودة رمز المثال الذي تتبعه، من المفترض أن تكون قادرًا على تشغيل الجهاز بالمعلمات التي تريدها خلال ساعة أو ساعتين.

تم التعديل للإضافة:أنت وحدك إذا كان Windows.أتصور أن الأمر ليس أكثر صعوبة ولكني لم أفعل ذلك مطلقًا.

أقترح بشدة استخدام مكتبة إدخال الفيديو, ، فهو يدعم أي جهاز DirectShow (حتى أجهزة متعددة في نفس الوقت) وهو أكثر قابلية للتكوين.ستقضي خمس دقائق في اللعب باستخدام OpenCV.

تحقق من هذه التذكرة:https://code.ros.org/trac/opencv/ticket/376

"الحل هو استخدام برنامج التغليف الأحدث المستند إلى libv4l.

  1. تثبيت libv4l-dev (هذه هي الطريقة التي يطلق عليها في Ubuntu)

  2. أعد تشغيل cmake، وسترى "V4L/V4L2:باستخدام libv4l"

  3. إعادة التشغيل.الآن يمكن تغيير القرار.تم اختباره باستخدام البصر المدمج على MBP."

لقد أصلح هذا الأمر بالنسبة لي باستخدام Ubuntu وقد يعمل أيضًا من أجلك.

الكود الذي بدأت العمل به أخيرًا في بايثون بمجرد أن أشار آرون هاون إلى أنني بحاجة إلى تحديد وسيطات الدالة المحددة قبل استخدامها.

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

أنا أستخدم نظامي debian وubuntu، وأواجه نفس المشكلة، ولم أتمكن من تغيير دقة إدخال الفيديو باستخدام CV_CAP_PROP_FRAME_WIDTH و CV_CAP_PROP_FRAME_HEIGHT

اتضح أن السبب هو مكتبة مفقودة.أنا ركبت lib4l-dev من خلال متشابك، أعيد بناؤها OpenCV وتم حل المشكلة!

أقوم بنشر هذا للتأكد من عدم إضاعة أي شخص آخر للوقت في وظيفة setproperty هذه.لقد أمضيت يومين في هذا الأمر لأرى أنه لا يوجد شيء يعمل.لذلك قمت باستخراج الكود (لقد قمت بتثبيت المكتبة في المرة الأولى).هذا ما يحدث بالفعل - cvSetCaptureProperty، يستدعي setProperty داخل فئة CvCapture ويلاحظ أن setProperty لا يفعل شيئًا.انها مجرد إرجاع كاذبة.بدلاً من ذلك سأختار استخدام مكتبة أخرى لتغذية OpenCV بفيديو/صور ملتقطة.أنا أستخدم OpenCV 2.2

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, WIDTH );

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);

cvQueryFrame(capture);

لن يعمل ذلك مع OpenCV 2.2، ولكن إذا كنت تستخدم OpenCV 2.1 فسوف يعمل بشكل جيد!

إذا كنت تستخدم نظام التشغيل Windows، فجرب DirectShow (IAMStreamConfig).

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

ضمن Windows حاول استخدام مكتبة VideoInput:http://robocraft.ru/blog/computervision/420.html

أجد أنه في نظام التشغيل Windows (من Win98 إلى WinXP SP3)، سيستخدم OpenCV غالبًا مكتبة VFW الخاصة بشركة Microsoft للوصول إلى الكاميرا.تكمن المشكلة في ذلك في أنه غالبًا ما يكون بطيئًا جدًا (على سبيل المثال التقاط إطار بمعدل 15 إطارًا في الثانية كحد أقصى) وعربات التي تجرها الدواب (ولهذا السبب لا يعمل cvSetCaptureProperty غالبًا).لحسن الحظ، يمكنك عادةً تغيير الدقة في برامج أخرى (خاصة "AMCAP"، وهو برنامج تجريبي متاح بسهولة) وسيؤثر ذلك على الدقة التي سيستخدمها OpenCV.على سبيل المثال، يمكنك تشغيل AMCAP لتعيين الدقة إلى 640 × 480، ومن ثم سيستخدم OpenCV ذلك افتراضيًا من تلك النقطة فصاعدًا!

ولكن إذا كان بإمكانك استخدام مكتبة مختلفة للوصول إلى كاميرا Windows مثل مكتبة "videoInput". http://muonics.net/school/spring05/videoInput/ يصل إلى الكاميرا باستخدام DirectShow الفعال للغاية (جزء من DirectX).أو إذا كان لديك كاميرا ذات جودة احترافية، فغالبًا ما تأتي مع واجهة برمجة تطبيقات مخصصة تتيح لك الوصول إلى الكاميرا، ويمكنك استخدامها للوصول السريع مع القدرة على تغيير الدقة وأشياء أخرى كثيرة.

معلومة واحدة فقط يمكن أن تكون ذات قيمة للأشخاص الذين يواجهون صعوبات في تغيير دقة الالتقاط الافتراضية (640 × 480)!لقد جربت بنفسي مثل هذه المشكلة مع opencv 2.4.x وكاميرا واحدة من Logitech ...ووجدت حلاً واحدًا!

السلوك الذي اكتشفته هو أن التنسيق الافتراضي هو الإعداد كمعلمات أولية عند بدء التقاط الكاميرا (cvCreateCameraCapture)، وكلها تطلب تغيير الارتفاع أو العرض:

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, ... 

أو

cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, ...

لا يمكن بعد ذلك!على نحو فعال، اكتشفت مع إضافة خطأ إرجاع لوظائف ioctl أن برنامج التشغيل V4l2 يعود إيبوسي للطلبات !لذلك، يجب أن يكون أحد الحلول هو تغيير القيمة الافتراضية مباشرة في Highgui/cap_v4l.cpp :

*#define DEFAULT_V4L_WIDTH  1280    // Originally 640* 

*#define DEFAULT_V4L_HEIGHT 720     // Originally 480*

بعد ذلك، أنا فقط إعادة تجميعها opencv ...ووصلت للحصول على 1280×720 دون أي مشكلة!بالطبع، يجب أن يكون الحل الأفضل هو إيقاف عملية الاستحواذ، وتغيير المعلمات، وإعادة تشغيل البث بعد ذلك، لكنني لست على دراية كافية بـ opencv للقيام بذلك!

نأمل أن يساعد.

ميشيل بيجي

جرب هذا:

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

ينبغي أن يكون كافيا!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top