{"id":6633,"date":"2026-06-22T23:33:57","date_gmt":"2026-06-22T18:33:57","guid":{"rendered":"https:\/\/cifrum.kz\/?p=6633"},"modified":"2026-06-23T09:19:58","modified_gmt":"2026-06-23T04:19:58","slug":"install-opencv-python-smart-camera","status":"publish","type":"post","link":"https:\/\/cifrum.kz\/en\/install-opencv-python-smart-camera\/","title":{"rendered":"How to install OpenCV in Python and build a smart camera"},"content":{"rendered":"<p class=\"has-large-font-size wp-block-paragraph\"><strong>This guide builds a working smart camera in Python:<\/strong> OpenCV captures webcam frames, detects motion, reads QR codes, and saves event images. You will also learn how to replace the webcam with an RTSP stream and add a trained YOLO model.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Current as of June 22, 2026.<\/strong> Commands were checked against the <a href=\"https:\/\/pypi.org\/project\/opencv-python\/\" target=\"_blank\" rel=\"noopener\">opencv-python package page<\/a> and official OpenCV guides for <a href=\"https:\/\/docs.opencv.org\/4.x\/dd\/d43\/tutorial_py_video_display.html\" target=\"_blank\" rel=\"noopener\">video capture<\/a>, <a href=\"https:\/\/docs.opencv.org\/4.x\/d1\/dc5\/tutorial_background_subtraction.html\" target=\"_blank\" rel=\"noopener\">background subtraction<\/a>, and <a href=\"https:\/\/docs.opencv.org\/4.x\/df\/d77\/group__objdetect__qrcode.html\" target=\"_blank\" rel=\"noopener\">QRCodeDetector<\/a>. The stable PyPI release at publication time is 4.13.0.92.<\/p><\/blockquote>\n<h2 class=\"wp-block-heading\">What you will build<\/h2><ul class=\"wp-block-list\"><li>a live camera window;<\/li><li>boxes around substantial moving regions;<\/li><li>local QR decoding;<\/li><li>event snapshots limited to one every five seconds;<\/li><li>a foundation for an IP camera or YOLO.<\/li><\/ul>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cifrum.kz\/wp-content\/uploads\/2026\/06\/opencv-workflow-en.jpg\" alt=\"OpenCV smart camera processing workflow\"\/><figcaption class=\"wp-element-caption\">The program captures a frame, processes motion and QR data, then decides whether to save an event.<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">Step 1. Create a project and virtual environment<\/h2><p>macOS and Linux:<\/p><pre class=\"wp-block-code\"><code>mkdir opencv-smart-camera\ncd opencv-smart-camera\npython3 -m venv .venv\nsource .venv\/bin\/activate<\/code><\/pre><p>Windows PowerShell:<\/p><pre class=\"wp-block-code\"><code>mkdir opencv-smart-camera\ncd opencv-smart-camera\npy -m venv .venv\n.venv\\Scripts\\Activate.ps1<\/code><\/pre>\n<h2 class=\"wp-block-heading\">Step 2. Install OpenCV<\/h2><pre class=\"wp-block-code\"><code>python -m pip install --upgrade pip\npython -m pip install opencv-python\npython -c \"import cv2; print(cv2.__version__)\"<\/code><\/pre><p>Install only one OpenCV package in an environment. Use <code>opencv-python-headless<\/code> on a server without GUI windows, or <code>opencv-contrib-python<\/code> when extra modules are required.<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cifrum.kz\/wp-content\/uploads\/2026\/06\/opencv-install-en.jpg\" alt=\"Commands for installing OpenCV in an isolated Python environment\"\/><figcaption class=\"wp-element-caption\">The PyPI package is named <code>opencv-python<\/code>, while the Python import is <code>cv2<\/code>.<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">Step 3. Test the webcam<\/h2><pre class=\"wp-block-code\"><code>import cv2\ncamera = cv2.VideoCapture(0)\nif not camera.isOpened(): raise SystemExit(\"Cannot open camera\")\nwhile True:\n    ok, frame = camera.read()\n    if not ok: break\n    cv2.imshow(\"Camera test\", frame)\n    if cv2.waitKey(1) &amp; 0xFF == ord(\"q\"): break\ncamera.release(); cv2.destroyAllWindows()<\/code><\/pre><p>Save this as <code>camera_test.py<\/code> and run <code>python camera_test.py<\/code>. If it fails, close Zoom or other camera apps, check OS permissions, and try index <code>1<\/code>.<\/p>\n<h2 class=\"wp-block-heading\">Step 4. Add motion and QR detection<\/h2><p>MOG2 learns the static background. Thresholding removes its shadow values, morphology filters small noise, and <code>MIN_AREA<\/code> rejects tiny contours.<\/p>\n<pre class=\"wp-block-code\"><code>from datetime import datetime\nfrom pathlib import Path\nimport time\nimport cv2\nimport numpy as np\n\nSOURCE, MIN_AREA, COOLDOWN = 0, 2500, 5.0\nout = Path(\"events\"); out.mkdir(exist_ok=True)\ncamera = cv2.VideoCapture(SOURCE)\nif not camera.isOpened(): raise SystemExit(\"Cannot open camera\")\nmodel = cv2.createBackgroundSubtractorMOG2(500, 36, True)\nqr = cv2.QRCodeDetector()\nkernel = np.ones((3, 3), np.uint8)\nlast_saved = 0.0\n\ntry:\n    while True:\n        ok, frame = camera.read()\n        if not ok: break\n        mask = model.apply(frame)\n        _, mask = cv2.threshold(mask, 200, 255, cv2.THRESH_BINARY)\n        mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=2)\n        mask = cv2.dilate(mask, kernel, iterations=2)\n        motion = False\n        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL,\n                                       cv2.CHAIN_APPROX_SIMPLE)\n        for contour in contours:\n            if cv2.contourArea(contour) &lt; MIN_AREA: continue\n            x, y, w, h = cv2.boundingRect(contour)\n            cv2.rectangle(frame, (x,y), (x+w,y+h), (0,220,180), 2)\n            motion = True\n        text, points, _ = qr.detectAndDecode(frame)\n        if text and points is not None:\n            pts = points.astype(int).reshape(-1, 2)\n            cv2.polylines(frame, [pts], True, (0,210,255), 3)\n            cv2.putText(frame, f\"QR: {text[:40]}\", (20,70),\n                        cv2.FONT_HERSHEY_SIMPLEX, .7, (0,210,255), 2)\n        now = time.monotonic()\n        if motion and now-last_saved &gt;= COOLDOWN:\n            name = datetime.now().strftime(\"event_%Y%m%d_%H%M%S.jpg\")\n            cv2.imwrite(str(out\/name), frame); last_saved = now\n        cv2.imshow(\"OpenCV smart camera\", frame)\n        if cv2.waitKey(1) &amp; 0xFF == ord(\"q\"): break\nfinally:\n    camera.release(); cv2.destroyAllWindows()<\/code><\/pre>\n<h2 class=\"wp-block-heading\">Step 5. Run and tune it<\/h2><pre class=\"wp-block-code\"><code>python smart_camera.py<\/code><\/pre><ul><li>increase <code>MIN_AREA<\/code> to ignore small shadows;<\/li><li>increase <code>COOLDOWN<\/code> to save fewer images;<\/li><li>press <code>Q<\/code> to release the camera cleanly.<\/li><\/ul>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/cifrum.kz\/wp-content\/uploads\/2026\/06\/opencv-result-en.jpg\" alt=\"OpenCV smart camera demonstration screen\"\/><figcaption class=\"wp-element-caption\">Demonstration result with a motion box, QR code, FPS, and event history.<\/figcaption><\/figure>\n<h2 class=\"wp-block-heading\">Step 6. Use a video or RTSP camera<\/h2><pre class=\"wp-block-code\"><code>SOURCE = \"video.mp4\"\n# or\nSOURCE = \"rtsp:\/\/USER:PASSWORD@CAMERA_IP:554\/STREAM_PATH\"<\/code><\/pre><p>Never commit a real password or show it in screenshots. Keep the camera on a restricted network and do not expose its RTSP port directly to the internet.<\/p>\n<h2 class=\"wp-block-heading\">Step 7. Add YOLO26<\/h2><pre class=\"wp-block-code\"><code>python -m pip install ultralytics<\/code><\/pre><pre class=\"wp-block-code\"><code>from ultralytics import YOLO\nmodel = YOLO(\"best.pt\")\nresults = model.predict(frame, conf=0.35, verbose=False)\nframe = results[0].plot()<\/code><\/pre><p>Run the neural network every second or third frame to reduce load. Training is covered in the <a href=\"https:\/\/cifrum.kz\/en\/how-to-install-train-yolo26\/\">YOLO26 guide<\/a>.<\/p>\n<h2 class=\"wp-block-heading\">Common problems<\/h2><ul><li><strong>Camera will not open:<\/strong> check permissions, index, and apps holding the device.<\/li><li><strong>No window on a server:<\/strong> headless packages do not support <code>imshow<\/code>.<\/li><li><strong>Too many events:<\/strong> raise <code>MIN_AREA<\/code> and <code>COOLDOWN<\/code>.<\/li><li><strong>QR will not decode:<\/strong> improve lighting, move closer, and reduce glare.<\/li><\/ul>\n<h2 class=\"wp-block-heading\">Conclusion<\/h2><p>OpenCV can produce a useful local prototype without a cloud service: capture video, isolate motion, decode a QR code, and save an event. Stabilize the webcam version first, then add RTSP and YOLO one at a time.<\/p><p><em>The featured image was created with a generative model. Diagrams contain no real camera addresses, credentials, or personal information.<\/em><\/p>\n<style>body.postid-6633 .cf-code-copy-wrap{position:relative;margin:1.5em 0}body.postid-6633 .cf-code-copy-wrap pre{margin:0;padding-top:3.25rem;overflow-x:auto}body.postid-6633 .cf-code-copy-button{position:absolute;top:.75rem;right:.75rem;z-index:2;padding:.45rem .75rem;background:#fff;border:1px solid #cbd4e5;border-radius:5px;font-weight:600}<\/style><script>document.addEventListener('DOMContentLoaded',function(){document.querySelectorAll('body.postid-6633 pre.wp-block-code').forEach(function(p){var w=document.createElement('div');w.className='cf-code-copy-wrap';p.parentNode.insertBefore(w,p);w.appendChild(p);var b=document.createElement('button');b.className='cf-code-copy-button';b.textContent='Copy';b.onclick=function(){var t=(p.querySelector('code')||p).innerText;navigator.clipboard.writeText(t).catch(function(){var a=document.createElement('textarea');a.value=t;document.body.appendChild(a);a.select();document.execCommand('copy');a.remove()}).then(function(){b.textContent='Copied'})};w.insertBefore(b,p)})});<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Install OpenCV in Python and build a smart camera with webcam input, motion detection, QR scanning, event snapshots, RTSP, and optional YOLO.<\/p>\n","protected":false},"author":1,"featured_media":6627,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"rank_math_focus_keyword":"install OpenCV in Python","rank_math_title":"Install OpenCV in Python and build a smart camera","rank_math_description":"Install OpenCV in Python and build a smart camera with motion detection, QR scanning, event snapshots, RTSP, and optional YOLO.","rank_math_canonical_url":"","rank_math_seo_score":"70","rank_math_pillar_content":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"","rank_math_twitter_image_id":"","rank_math_news_sitemap_genre":"","rank_math_news_sitemap_keywords":"","rank_math_news_sitemap_stock_tickers":"","rank_math_robots":"","rank_math_advanced_robots":"","rank_math_schema_News":"","footnotes":""},"categories":[2104,1631],"tags":[],"cifrum_os_content_type":[],"class_list":["post-6633","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-artificial-intelligence-en","category-artificial_intelligence"],"acf":[],"_links":{"self":[{"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/posts\/6633","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/comments?post=6633"}],"version-history":[{"count":1,"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/posts\/6633\/revisions"}],"predecessor-version":[{"id":6636,"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/posts\/6633\/revisions\/6636"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/media\/6627"}],"wp:attachment":[{"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/media?parent=6633"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/categories?post=6633"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/tags?post=6633"},{"taxonomy":"cifrum_os_content_type","embeddable":true,"href":"https:\/\/cifrum.kz\/en\/wp-json\/wp\/v2\/cifrum_os_content_type?post=6633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}