{ "cells": [ { "cell_type": "markdown", "id": "8ec612eb-87b1-464b-acb7-3d3dc449a7ab", "metadata": {}, "source": [ "#
Optical flow
" ] }, { "cell_type": "markdown", "id": "537d47bb-eec0-479c-8c4c-80c75a4ed891", "metadata": {}, "source": [ "
Optical flow الگوی حرکت ظاهری اجسام بین دو فریم متوالی است که در اثر حرکت جسم یا دوربین ایجاد می شود. \n", "
" ] }, { "cell_type": "markdown", "id": "dea2d4a4-fb31-40fe-9e33-8b9f6cc4f9c0", "metadata": {}, "source": [ "### Lucas-Kanade Optical Flow in OpenCV " ] }, { "cell_type": "code", "execution_count": 20, "id": "057b9837-dacc-4702-b532-c86302300021", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import cv2\n", "\n", "cap = cv2.VideoCapture('videos/slow_traffic_small.mp4')\n", "\n", "# params for ShiTomasi corner detection\n", "feature_params = dict( maxCorners = 100,\n", " qualityLevel = 0.3,\n", " minDistance = 7,\n", " blockSize = 7 )\n", "\n", "# Parameters for lucas kanade optical flow\n", "lk_params = dict( winSize = (15, 15),\n", " maxLevel = 2,\n", " criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))\n", "\n", "# Create some random colors\n", "color = np.random.randint(0, 255, (100, 3))\n", "\n", "# Take first frame and find corners in it\n", "_, old_frame = cap.read()\n", "old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)\n", "p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)\n", "# Create a mask image for drawing purposes\n", "mask = np.zeros_like(old_frame)\n", "\n", "while True:\n", " ret, frame = cap.read()\n", " if not ret:\n", " print('No frames grabbed!')\n", " break\n", " frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n", " # calculate optical flow\n", " p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)\n", " # Select good points\n", " if p1 is not None:\n", " good_new = p1[st==1]\n", " good_old = p0[st==1]\n", " # draw the tracks\n", " for i, (new, old) in enumerate(zip(good_new, good_old)):\n", " a, b = new.ravel()\n", " c, d = old.ravel()\n", " mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)\n", " frame = cv2.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)\n", " img = cv2.add(frame, mask)\n", " cv2.imshow('frame', img)\n", " k = cv2.waitKey(30) & 0xff\n", " if k == 27:\n", " break\n", " # Now update the previous frame and previous points\n", " old_gray = frame_gray.copy()\n", " p0 = good_new.reshape(-1, 1, 2)\n", "cv2.destroyAllWindows()" ] }, { "cell_type": "markdown", "id": "646cb5f0-1247-40fe-96fc-66922c930cf1", "metadata": {}, "source": [ "### Dense Optical Flow in OpenCV " ] }, { "cell_type": "code", "execution_count": 24, "id": "63e62515-7048-44d0-966e-be59c7ab7adb", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import cv2\n", "cap = cv2.VideoCapture('videos/vtest.avi')\n", "ret, frame1 = cap.read()\n", "prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)\n", "hsv = np.zeros_like(frame1)\n", "hsv[..., 1] = 255\n", "while True:\n", " ret, frame2 = cap.read()\n", " if not ret:\n", " print('No frames grabbed!')\n", " break\n", " next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)\n", " flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)\n", " mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])\n", " hsv[..., 0] = ang*180/np.pi/2\n", " hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)\n", " bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)\n", " cv2.imshow('frame2', bgr)\n", " k = cv2.waitKey(30) & 0xff\n", " if k == 27:\n", " break\n", " elif k == ord('s'):\n", " cv2.imwrite('opticalfb.png', frame2)\n", " cv2.imwrite('opticalhsv.png', bgr)\n", " prvs = next\n", "cv2.destroyAllWindows()" ] }, { "cell_type": "code", "execution_count": 26, "id": "b4bab69e-87b8-4548-811c-69064cfe737d", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import cv2\n", "\n", "\n", "\n", "def draw_flow(img, flow, step=16):\n", "\n", " h, w = img.shape[:2]\n", " y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)\n", " fx, fy = flow[y,x].T\n", "\n", " lines = np.vstack([x, y, x-fx, y-fy]).T.reshape(-1, 2, 2)\n", " lines = np.int32(lines + 0.5)\n", "\n", " img_bgr = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)\n", " cv2.polylines(img_bgr, lines, 0, (0, 255, 0))\n", "\n", " for (x1, y1), (_x2, _y2) in lines:\n", " cv2.circle(img_bgr, (x1, y1), 1, (0, 255, 0), -1)\n", "\n", " return img_bgr\n", "\n", "\n", "def draw_hsv(flow):\n", "\n", " h, w = flow.shape[:2]\n", " fx, fy = flow[:,:,0], flow[:,:,1]\n", "\n", " ang = np.arctan2(fy, fx) + np.pi\n", " v = np.sqrt(fx*fx+fy*fy)\n", "\n", " hsv = np.zeros((h, w, 3), np.uint8)\n", " hsv[...,0] = ang*(180/np.pi/2)\n", " hsv[...,1] = 255\n", " hsv[...,2] = np.minimum(v*4, 255)\n", " bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)\n", "\n", " return bgr\n", "\n", "\n", "\n", "\n", "cap = cv2.VideoCapture(0)\n", "\n", "suc, prev = cap.read()\n", "prevgray = cv2.cvtColor(prev, cv2.COLOR_BGR2GRAY)\n", "\n", "\n", "while True:\n", "\n", " suc, img = cap.read()\n", " gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n", "\n", " flow = cv2.calcOpticalFlowFarneback(prevgray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)\n", " \n", " prevgray = gray\n", "\n", "\n", " cv2.imshow('flow', draw_flow(gray, flow))\n", " cv2.imshow('flow HSV', draw_hsv(flow))\n", "\n", "\n", " key = cv2.waitKey(5)\n", " if key == ord('q'):\n", " break\n", "\n", "\n", "cap.release()\n", "cv2.destroyAllWindows()\n" ] }, { "cell_type": "markdown", "id": "f031cfb8-68bb-4f27-af7c-34a266ea9e97", "metadata": {}, "source": [ "Sources:\n", " \n", " - https://docs.opencv.org/4.6.0/d4/dee/tutorial_optical_flow.html\n", " - https://github.com/niconielsen32/ComputerVision/tree/master/opticalFlow" ] } ], "metadata": { "kernelspec": { "display_name": "vision-class", "language": "python", "name": "tensorflow_25" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 5 }