{"id":2685,"date":"2020-07-12T13:34:12","date_gmt":"2020-07-12T11:34:12","guid":{"rendered":"https:\/\/www.kurokesu.com\/main\/?p=2685"},"modified":"2020-07-31T13:10:08","modified_gmt":"2020-07-31T11:10:08","slug":"pulling-full-resolution-from-a-webcam-with-opencv-windows","status":"publish","type":"post","link":"https:\/\/www.kurokesu.com\/main\/2020\/07\/12\/pulling-full-resolution-from-a-webcam-with-opencv-windows\/","title":{"rendered":"Pulling full resolution from a webcam with OpenCV (Windows)"},"content":{"rendered":"\n<p><a target=\"_blank\" href=\"https:\/\/opencv.org\/\" rel=\"noreferrer noopener\">OpenCV<\/a>&nbsp;while being the most popular tool for a lot of machine vision applications it relies on a third party and some poorly maintained code. Capturing MJPEG compressed video from a UVC USB camera was always the case and it did not work or worked with some issues. This situation is especially bad for Windows OS.<\/p>\n\n\n\n<p>Currently <a href=\"https:\/\/www.python.org\/\">Python<\/a> 3.8.4 pip has these versions of <a href=\"https:\/\/pypi.org\/project\/opencv-python\/\">OpenCV<\/a> available to be installed directly: 3.4.8.29, 3.4.9.31, 3.4.9.33, 3.4.10.35, 4.1.2.30, 4.2.0.32, 4.2.0.34, 4.3.0.36<\/p>\n\n\n\n<p>Each version can be installed (and replaced) with ease by typing so it&#8217;s fairly easy to test versions that are in pip package manager repository:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install opencv-python==4.3.0.36<\/code><\/pre>\n\n\n\n<p>Classic \/ minimalistic way to capture images is like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import cv2\n\ncamera = cv2.VideoCapture(0)\n\nwhile (1):\n    retval, im = camera.read()\n    cv2.imshow(\"image\", im)\n\n    k = cv2.waitKey(1) &amp; 0xff\n    if k == 27:\n        break\n\ncamera.release()\ncv2.destroyAllWindows()<\/code><\/pre>\n\n\n\n<p>Unfortunately, sometimes it needs some more parameters to actually capture MJPEG stream. For older OpenCV (last tested 3.4.2.x) versions there was a solution to add cv2.CAP_PROP_FOURCC property set and the whole code to have 1920&#215;1080 at 30fps stream looked like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import cv2\n\ncamera = cv2.VideoCapture(0)\n\ncodec = 0x47504A4D  # MJPG\ncamera.set(cv2.CAP_PROP_FPS, 30.0)\ncamera.set(cv2.CAP_PROP_FOURCC, codec)\ncamera.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)\ncamera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)\n\nwhile (1):\n    retval, im = camera.read(0)\n    cv2.imshow(\"image\", im)\n\n    k = cv2.waitKey(1) &amp; 0xff\n    if k == 27:\n        break\n\ncamera.release()\ncv2.destroyAllWindows()<\/code><\/pre>\n\n\n\n<p>Once the last OpenCV version available in the pip repository was updated and this workaround stopped working. Since 3.4.10.35 OpenCV version was rolled out it stopped working at all and frames could not be captured anymore. One more property had to be added cv2.CAP_DSHOW so now code looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import cv2\n\ncamera = cv2.VideoCapture(0, cv2.CAP_DSHOW)\n\ncodec = 0x47504A4D  # MJPG\ncamera.set(cv2.CAP_PROP_FPS, 30.0)\ncamera.set(cv2.CAP_PROP_FOURCC, codec)\ncamera.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)\ncamera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)\n\nwhile (1):\n    retval, im = camera.read()\n    cv2.imshow(\"image\", im)\n\n    k = cv2.waitKey(1) &amp; 0xff\n    if k == 27:\n        break\n\ncamera.release()\ncv2.destroyAllWindows()<\/code><\/pre>\n\n\n\n<p>One problem remains. Frames are not being captured at 30 frames per second rate. So one more fix and we have 1080p@30fps with MJPEG compression stream in our code.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import cv2\n\ncamera = cv2.VideoCapture(0, cv2.CAP_DSHOW)\n\ncamera.set(cv2.CAP_PROP_FPS, 30.0)\ncamera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('m','j','p','g'))\ncamera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M','J','P','G'))\ncamera.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)\ncamera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)\n\nwhile (1):\n    retval, im = camera.read()\n    cv2.imshow(\"image\", im)\n\n    k = cv2.waitKey(1) &amp; 0xff\n    if k == 27:\n        break\n\ncamera.release()\ncv2.destroyAllWindows()<\/code><\/pre>\n\n\n\n<p>This solution may not work for all operating systems, versions, and cameras. Most intense tests were performed with&nbsp;<a target=\"_blank\" href=\"https:\/\/www.kurokesu.com\/shop\/cameras\" rel=\"noreferrer noopener\">C1 family cameras<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>OpenCV&nbsp;while being the most popular tool for a lot of machine vision applications it relies on a third party and some poorly maintained code. Capturing MJPEG compressed video from a UVC USB camera was always the case and it did not work or worked with some issues. This situation is especially bad for Windows OS. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2697,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[157],"tags":[193,356,354,62,64,49,388],"class_list":["post-2685","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to","tag-c1","tag-c1-micro","tag-c1-pro","tag-camera","tag-opencv","tag-python","tag-webcam"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2020\/07\/opencv_warning2.png","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6VSmB-Hj","_links":{"self":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/2685","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/comments?post=2685"}],"version-history":[{"count":13,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/2685\/revisions"}],"predecessor-version":[{"id":2947,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/2685\/revisions\/2947"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/media\/2697"}],"wp:attachment":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/media?parent=2685"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/categories?post=2685"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/tags?post=2685"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}