475 lines
23 KiB
Plaintext
475 lines
23 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "7b423cf2-b549-4aa3-9b8a-11d016aace3b",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/var/folders/9r/fngx7sv11bl1k4rvtyflv1pw0000gn/T/ipykernel_52043/172184081.py:3: DeprecationWarning: \n",
|
|
"Pyarrow will become a required dependency of pandas in the next major release of pandas (pandas 3.0),\n",
|
|
"(to allow more performant data types, such as the Arrow string type, and better interoperability with other libraries)\n",
|
|
"but was not found to be installed on your system.\n",
|
|
"If this would cause problems for you,\n",
|
|
"please provide us feedback at https://github.com/pandas-dev/pandas/issues/54466\n",
|
|
" \n",
|
|
" import pandas as pd\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"import cv2\n",
|
|
"import pandas as pd\n",
|
|
"import matplotlib.pyplot as plt"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "387b1580-2cff-48b0-9854-29428ef033b8",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"372.0 25.0 2560 1440\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"cap = cv2.VideoCapture('video3.mp4')\n",
|
|
"frames_count, fps, width, height = cap.get(cv2.CAP_PROP_FRAME_COUNT), cap.get(cv2.CAP_PROP_FPS), cap.get(\n",
|
|
" cv2.CAP_PROP_FRAME_WIDTH), cap.get(cv2.CAP_PROP_FRAME_HEIGHT)\n",
|
|
"width = int(width)\n",
|
|
"height = int(height)\n",
|
|
"print(frames_count, fps, width, height)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"id": "0589d5a1-1fec-4e1e-ac2f-e64396d0d539",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# creates a pandas data frame with the number of rows the same length as frame count\n",
|
|
"df = pd.DataFrame(index=range(int(frames_count)))\n",
|
|
"df.index.name = \"Frames\"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "1943e0e6-7175-4e1a-a795-d3f2b64b559a",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"framenumber = 0 # keeps track of current frame\n",
|
|
"carscrossedup = 0 # keeps track of cars that crossed up\n",
|
|
"carscrosseddown = 0 # keeps track of cars that crossed down\n",
|
|
"carids = [] # blank list to add car ids\n",
|
|
"caridscrossed = [] # blank list to add car ids that have crossed\n",
|
|
"totalcars = 0 # keeps track of total cars\n",
|
|
"fgbg = cv2.createBackgroundSubtractorMOG2() # create background subtractor"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"id": "0fb78ee3-ae0f-47d4-9adb-ca7dc0871a3f",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# information to start saving a video file\n",
|
|
"ret, frame = cap.read() # import image\n",
|
|
"ratio = .5 # resize ratio\n",
|
|
"image = cv2.resize(frame, (0, 0), None, ratio, ratio) # resize image\n",
|
|
"width2, height2, channels = image.shape\n",
|
|
"video = cv2.VideoWriter('traffic_counter.avi', cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), fps, (height2, width2), 1)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"id": "17b207f1-ca8f-4f15-9da1-ba84e71c7f3d",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"ename": "NameError",
|
|
"evalue": "name 'fgmask_resized' is not defined",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[6], line 272\u001b[0m\n\u001b[1;32m 266\u001b[0m cv2\u001b[38;5;241m.\u001b[39mmoveWindow(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcountours\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m0\u001b[39m)\n\u001b[1;32m 268\u001b[0m \u001b[38;5;66;03m# cv2.imshow(\"fgmask\", fgmask)\u001b[39;00m\n\u001b[1;32m 269\u001b[0m \u001b[38;5;66;03m# cv2.moveWindow(\"fgmask\", int(width * ratio), 0)\u001b[39;00m\n\u001b[1;32m 270\u001b[0m \n\u001b[1;32m 271\u001b[0m \u001b[38;5;66;03m# Concatenate the original frame and the resized fgmask horizontally\u001b[39;00m\n\u001b[0;32m--> 272\u001b[0m concatenated_image \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mconcatenate((frame, \u001b[43mfgmask_resized\u001b[49m), axis\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1\u001b[39m)\n\u001b[1;32m 274\u001b[0m \u001b[38;5;66;03m# Display the concatenated image\u001b[39;00m\n\u001b[1;32m 275\u001b[0m plt\u001b[38;5;241m.\u001b[39mimshow(cv2\u001b[38;5;241m.\u001b[39mcvtColor(concatenated_image, cv2\u001b[38;5;241m.\u001b[39mCOLOR_BGR2RGB))\n",
|
|
"\u001b[0;31mNameError\u001b[0m: name 'fgmask_resized' is not defined"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"while True:\n",
|
|
"\n",
|
|
" ret, frame = cap.read() # import image\n",
|
|
"\n",
|
|
" if ret: # if there is a frame continue with code\n",
|
|
"\n",
|
|
" image = cv2.resize(frame, (0, 0), None, ratio, ratio) # resize image\n",
|
|
"\n",
|
|
" gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # converts image to gray\n",
|
|
"\n",
|
|
" fgmask = fgbg.apply(gray) # uses the background subtraction\n",
|
|
"\n",
|
|
" # applies different thresholds to fgmask to try and isolate cars\n",
|
|
" # just have to keep playing around with settings until cars are easily identifiable\n",
|
|
" kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # kernel to apply to the morphology\n",
|
|
" closing = cv2.morphologyEx(fgmask, cv2.MORPH_CLOSE, kernel)\n",
|
|
" opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kernel)\n",
|
|
" dilation = cv2.dilate(opening, kernel)\n",
|
|
" retvalbin, bins = cv2.threshold(dilation, 220, 255, cv2.THRESH_BINARY) # removes the shadows\n",
|
|
"\n",
|
|
" # creates contours\n",
|
|
" contours, hierarchy = cv2.findContours(bins, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n",
|
|
"\n",
|
|
" # use convex hull to create polygon around contours\n",
|
|
" hull = [cv2.convexHull(c) for c in contours]\n",
|
|
"\n",
|
|
" # draw contours\n",
|
|
" cv2.drawContours(image, hull, -1, (0, 255, 0), 3)\n",
|
|
"\n",
|
|
" # line created to stop counting contours, needed as cars in distance become one big contour\n",
|
|
" lineypos = 250\n",
|
|
" cv2.line(image, (0, lineypos), (width, lineypos), (255, 0, 0), 5)\n",
|
|
"\n",
|
|
" # line y position created to count contours\n",
|
|
" lineypos2 = 150\n",
|
|
" cv2.line(image, (0, lineypos2), (width, lineypos2), (0, 255, 0), 5)\n",
|
|
"\n",
|
|
" # min area for contours in case a bunch of small noise contours are created\n",
|
|
" minarea = 300\n",
|
|
"\n",
|
|
" # max area for contours, can be quite large for buses\n",
|
|
" maxarea = 50000\n",
|
|
"\n",
|
|
" # vectors for the x and y locations of contour centroids in current frame\n",
|
|
" cxx = np.zeros(len(contours))\n",
|
|
" cyy = np.zeros(len(contours))\n",
|
|
"\n",
|
|
" for i in range(len(contours)): # cycles through all contours in current frame\n",
|
|
"\n",
|
|
" if hierarchy[0, i, 3] == -1: # using hierarchy to only count parent contours (contours not within others)\n",
|
|
"\n",
|
|
" area = cv2.contourArea(contours[i]) # area of contour\n",
|
|
"\n",
|
|
" if minarea < area < maxarea: # area threshold for contour\n",
|
|
"\n",
|
|
" # calculating centroids of contours\n",
|
|
" cnt = contours[i]\n",
|
|
" M = cv2.moments(cnt)\n",
|
|
" cx = int(M['m10'] / M['m00'])\n",
|
|
" cy = int(M['m01'] / M['m00'])\n",
|
|
"\n",
|
|
" if cy > lineypos: # filters out contours that are above line (y starts at top)\n",
|
|
"\n",
|
|
" # gets bounding points of contour to create rectangle\n",
|
|
" # x,y is top left corner and w,h is width and height\n",
|
|
" x, y, w, h = cv2.boundingRect(cnt)\n",
|
|
"\n",
|
|
" # creates a rectangle around contour\n",
|
|
" cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)\n",
|
|
"\n",
|
|
" # Prints centroid text in order to double check later on\n",
|
|
" cv2.putText(image, str(cx) + \",\" + str(cy), (cx + 10, cy + 10), cv2.FONT_HERSHEY_SIMPLEX,\n",
|
|
" .3, (0, 0, 255), 1)\n",
|
|
"\n",
|
|
" cv2.drawMarker(image, (cx, cy), (0, 0, 255), cv2.MARKER_STAR, markerSize=5, thickness=1,\n",
|
|
" line_type=cv2.LINE_AA)\n",
|
|
"\n",
|
|
" # adds centroids that passed previous criteria to centroid list\n",
|
|
" cxx[i] = cx\n",
|
|
" cyy[i] = cy\n",
|
|
"\n",
|
|
" # eliminates zero entries (centroids that were not added)\n",
|
|
" cxx = cxx[cxx != 0]\n",
|
|
" cyy = cyy[cyy != 0]\n",
|
|
"\n",
|
|
" # empty list to later check which centroid indices were added to dataframe\n",
|
|
" minx_index2 = []\n",
|
|
" miny_index2 = []\n",
|
|
"\n",
|
|
" # maximum allowable radius for current frame centroid to be considered the same centroid from previous frame\n",
|
|
" maxrad = 25\n",
|
|
"\n",
|
|
" # The section below keeps track of the centroids and assigns them to old carids or new carids\n",
|
|
"\n",
|
|
" if len(cxx): # if there are centroids in the specified area\n",
|
|
"\n",
|
|
" if not carids: # if carids is empty\n",
|
|
"\n",
|
|
" for i in range(len(cxx)): # loops through all centroids\n",
|
|
"\n",
|
|
" carids.append(i) # adds a car id to the empty list carids\n",
|
|
" df[str(carids[i])] = \"\" # adds a column to the dataframe corresponding to a carid\n",
|
|
"\n",
|
|
" # assigns the centroid values to the current frame (row) and carid (column)\n",
|
|
" df.at[int(framenumber), str(carids[i])] = [cxx[i], cyy[i]]\n",
|
|
"\n",
|
|
" totalcars = carids[i] + 1 # adds one count to total cars\n",
|
|
"\n",
|
|
" else: # if there are already car ids\n",
|
|
"\n",
|
|
" dx = np.zeros((len(cxx), len(carids))) # new arrays to calculate deltas\n",
|
|
" dy = np.zeros((len(cyy), len(carids))) # new arrays to calculate deltas\n",
|
|
"\n",
|
|
" for i in range(len(cxx)): # loops through all centroids\n",
|
|
"\n",
|
|
" for j in range(len(carids)): # loops through all recorded car ids\n",
|
|
"\n",
|
|
" # acquires centroid from previous frame for specific carid\n",
|
|
" oldcxcy = df.iloc[int(framenumber - 1)][str(carids[j])]\n",
|
|
"\n",
|
|
" # acquires current frame centroid that doesn't necessarily line up with previous frame centroid\n",
|
|
" curcxcy = np.array([cxx[i], cyy[i]])\n",
|
|
"\n",
|
|
" if not oldcxcy: # checks if old centroid is empty in case car leaves screen and new car shows\n",
|
|
"\n",
|
|
" continue # continue to next carid\n",
|
|
"\n",
|
|
" else: # calculate centroid deltas to compare to current frame position later\n",
|
|
"\n",
|
|
" dx[i, j] = oldcxcy[0] - curcxcy[0]\n",
|
|
" dy[i, j] = oldcxcy[1] - curcxcy[1]\n",
|
|
"\n",
|
|
" for j in range(len(carids)): # loops through all current car ids\n",
|
|
"\n",
|
|
" sumsum = np.abs(dx[:, j]) + np.abs(dy[:, j]) # sums the deltas wrt to car ids\n",
|
|
"\n",
|
|
" # finds which index carid had the min difference and this is true index\n",
|
|
" correctindextrue = np.argmin(np.abs(sumsum))\n",
|
|
" minx_index = correctindextrue\n",
|
|
" miny_index = correctindextrue\n",
|
|
"\n",
|
|
" # acquires delta values of the minimum deltas in order to check if it is within radius later on\n",
|
|
" mindx = dx[minx_index, j]\n",
|
|
" mindy = dy[miny_index, j]\n",
|
|
"\n",
|
|
" if mindx == 0 and mindy == 0 and np.all(dx[:, j] == 0) and np.all(dy[:, j] == 0):\n",
|
|
" # checks if minimum value is 0 and checks if all deltas are zero since this is empty set\n",
|
|
" # delta could be zero if centroid didn't move\n",
|
|
"\n",
|
|
" continue # continue to next carid\n",
|
|
"\n",
|
|
" else:\n",
|
|
"\n",
|
|
" # if delta values are less than maximum radius then add that centroid to that specific carid\n",
|
|
" if np.abs(mindx) < maxrad and np.abs(mindy) < maxrad:\n",
|
|
"\n",
|
|
" # adds centroid to corresponding previously existing carid\n",
|
|
" df.at[int(framenumber), str(carids[j])] = [cxx[minx_index], cyy[miny_index]]\n",
|
|
" minx_index2.append(minx_index) # appends all the indices that were added to previous carids\n",
|
|
" miny_index2.append(miny_index)\n",
|
|
"\n",
|
|
" for i in range(len(cxx)): # loops through all centroids\n",
|
|
"\n",
|
|
" # if centroid is not in the minindex list then another car needs to be added\n",
|
|
" if i not in minx_index2 and miny_index2:\n",
|
|
"\n",
|
|
" df[str(totalcars)] = \"\" # create another column with total cars\n",
|
|
" totalcars = totalcars + 1 # adds another total car the count\n",
|
|
" t = totalcars - 1 # t is a placeholder to total cars\n",
|
|
" carids.append(t) # append to list of car ids\n",
|
|
" df.at[int(framenumber), str(t)] = [cxx[i], cyy[i]] # add centroid to the new car id\n",
|
|
"\n",
|
|
" elif curcxcy[0] and not oldcxcy and not minx_index2 and not miny_index2:\n",
|
|
" # checks if current centroid exists but previous centroid does not\n",
|
|
" # new car to be added in case minx_index2 is empty\n",
|
|
"\n",
|
|
" df[str(totalcars)] = \"\" # create another column with total cars\n",
|
|
" totalcars = totalcars + 1 # adds another total car the count\n",
|
|
" t = totalcars - 1 # t is a placeholder to total cars\n",
|
|
" carids.append(t) # append to list of car ids\n",
|
|
" df.at[int(framenumber), str(t)] = [cxx[i], cyy[i]] # add centroid to the new car id\n",
|
|
"\n",
|
|
" # The section below labels the centroids on screen\n",
|
|
"\n",
|
|
" currentcars = 0 # current cars on screen\n",
|
|
" currentcarsindex = [] # current cars on screen carid index\n",
|
|
"\n",
|
|
" for i in range(len(carids)): # loops through all carids\n",
|
|
"\n",
|
|
" if df.at[int(framenumber), str(carids[i])] != '':\n",
|
|
" # checks the current frame to see which car ids are active\n",
|
|
" # by checking in centroid exists on current frame for certain car id\n",
|
|
"\n",
|
|
" currentcars = currentcars + 1 # adds another to current cars on screen\n",
|
|
" currentcarsindex.append(i) # adds car ids to current cars on screen\n",
|
|
"\n",
|
|
" for i in range(currentcars): # loops through all current car ids on screen\n",
|
|
"\n",
|
|
" # grabs centroid of certain carid for current frame\n",
|
|
" curcent = df.iloc[int(framenumber)][str(carids[currentcarsindex[i]])]\n",
|
|
"\n",
|
|
" # grabs centroid of certain carid for previous frame\n",
|
|
" oldcent = df.iloc[int(framenumber - 1)][str(carids[currentcarsindex[i]])]\n",
|
|
"\n",
|
|
" if curcent: # if there is a current centroid\n",
|
|
"\n",
|
|
" # On-screen text for current centroid\n",
|
|
" cv2.putText(image, \"Centroid\" + str(curcent[0]) + \",\" + str(curcent[1]),\n",
|
|
" (int(curcent[0]), int(curcent[1])), cv2.FONT_HERSHEY_SIMPLEX, .5, (0, 255, 255), 2)\n",
|
|
"\n",
|
|
" cv2.putText(image, \"ID:\" + str(carids[currentcarsindex[i]]), (int(curcent[0]), int(curcent[1] - 15)),\n",
|
|
" cv2.FONT_HERSHEY_SIMPLEX, .5, (0, 255, 255), 2)\n",
|
|
"\n",
|
|
" cv2.drawMarker(image, (int(curcent[0]), int(curcent[1])), (0, 0, 255), cv2.MARKER_STAR, markerSize=5,\n",
|
|
" thickness=1, line_type=cv2.LINE_AA)\n",
|
|
"\n",
|
|
" if oldcent: # checks if old centroid exists\n",
|
|
" # adds radius box from previous centroid to current centroid for visualization\n",
|
|
" xstart = oldcent[0] - maxrad\n",
|
|
" ystart = oldcent[1] - maxrad\n",
|
|
" xwidth = oldcent[0] + maxrad\n",
|
|
" yheight = oldcent[1] + maxrad\n",
|
|
" cv2.rectangle(image, (int(xstart), int(ystart)), (int(xwidth), int(yheight)), (0, 125, 0), 1)\n",
|
|
"\n",
|
|
" # checks if old centroid is on or below line and curcent is on or above line\n",
|
|
" # to count cars and that car hasn't been counted yet\n",
|
|
" if oldcent[1] >= lineypos2 and curcent[1] <= lineypos2 and carids[\n",
|
|
" currentcarsindex[i]] not in caridscrossed:\n",
|
|
"\n",
|
|
" carscrossedup = carscrossedup + 1\n",
|
|
" cv2.line(image, (0, lineypos2), (width, lineypos2), (0, 0, 255), 5)\n",
|
|
" caridscrossed.append(\n",
|
|
" currentcarsindex[i]) # adds car id to list of count cars to prevent double counting\n",
|
|
"\n",
|
|
" # checks if old centroid is on or above line and curcent is on or below line\n",
|
|
" # to count cars and that car hasn't been counted yet\n",
|
|
" elif oldcent[1] <= lineypos2 and curcent[1] >= lineypos2 and carids[\n",
|
|
" currentcarsindex[i]] not in caridscrossed:\n",
|
|
"\n",
|
|
" carscrosseddown = carscrosseddown + 1\n",
|
|
" cv2.line(image, (0, lineypos2), (width, lineypos2), (0, 0, 125), 5)\n",
|
|
" caridscrossed.append(currentcarsindex[i])\n",
|
|
"\n",
|
|
" # Top left hand corner on-screen text\n",
|
|
" cv2.rectangle(image, (0, 0), (250, 100), (255, 0, 0), -1) # background rectangle for on-screen text\n",
|
|
"\n",
|
|
" cv2.putText(image, \"Cars in Area: \" + str(currentcars), (0, 15), cv2.FONT_HERSHEY_SIMPLEX, .5, (0, 170, 0), 1)\n",
|
|
"\n",
|
|
" cv2.putText(image, \"Cars Crossed Up: \" + str(carscrossedup), (0, 30), cv2.FONT_HERSHEY_SIMPLEX, .5, (0, 170, 0),\n",
|
|
" 1)\n",
|
|
"\n",
|
|
" cv2.putText(image, \"Cars Crossed Down: \" + str(carscrosseddown), (0, 45), cv2.FONT_HERSHEY_SIMPLEX, .5,\n",
|
|
" (0, 170, 0), 1)\n",
|
|
"\n",
|
|
" cv2.putText(image, \"Total Cars Detected: \" + str(len(carids)), (0, 60), cv2.FONT_HERSHEY_SIMPLEX, .5,\n",
|
|
" (0, 170, 0), 1)\n",
|
|
"\n",
|
|
" cv2.putText(image, \"Frame: \" + str(framenumber) + ' of ' + str(frames_count), (0, 75), cv2.FONT_HERSHEY_SIMPLEX,\n",
|
|
" .5, (0, 170, 0), 1)\n",
|
|
"\n",
|
|
" cv2.putText(image, 'Time: ' + str(round(framenumber / fps, 2)) + ' sec of ' + str(round(frames_count / fps, 2))\n",
|
|
" + ' sec', (0, 90), cv2.FONT_HERSHEY_SIMPLEX, .5, (0, 170, 0), 1)\n",
|
|
"\n",
|
|
" # displays images and transformations\n",
|
|
" cv2.imshow(\"countours\", image)\n",
|
|
" cv2.moveWindow(\"countours\", 0, 0)\n",
|
|
"\n",
|
|
" # cv2.imshow(\"fgmask\", fgmask)\n",
|
|
" # cv2.moveWindow(\"fgmask\", int(width * ratio), 0)\n",
|
|
"\n",
|
|
" # Resize fgmask to match the dimensions of the original frame\n",
|
|
" fgmask_resized = cv2.resize(fgmask, (width, height)) \n",
|
|
"\n",
|
|
" # Concatenate the original frame and the resized fgmask horizontally\n",
|
|
" concatenated_image = np.concatenate((frame, fgmask_resized), axis=1)\n",
|
|
" \n",
|
|
" # Display the concatenated image\n",
|
|
" plt.imshow(cv2.cvtColor(concatenated_image, cv2.COLOR_BGR2RGB))\n",
|
|
" plt.axis('off') # Turn off axis\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
" cv2.imshow(\"closing\", closing)\n",
|
|
" cv2.moveWindow(\"closing\", width * 2, 0)\n",
|
|
"\n",
|
|
" cv2.imshow(\"opening\", opening)\n",
|
|
" cv2.moveWindow(\"opening\", 0, int(height * ratio))\n",
|
|
"\n",
|
|
" cv2.imshow(\"dilation\", dilation)\n",
|
|
" cv2.moveWindow(\"dilation\", int(width * ratio), int(height * ratio))\n",
|
|
"\n",
|
|
" cv2.imshow(\"binary\", bins)\n",
|
|
" cv2.moveWindow(\"binary\", width * 2, int(height * ratio))\n",
|
|
"\n",
|
|
" # adds to dataframe frame number\n",
|
|
" df.at[int(framenumber), \"framenumber\"] = framenumber\n",
|
|
"\n",
|
|
" k = cv2.waitKey(1)\n",
|
|
" if k == ord('q'):\n",
|
|
" break\n",
|
|
" if framenumber == frames_count - 1: # if this is the last frame, exit\n",
|
|
" break\n",
|
|
" else:\n",
|
|
" framenumber += 1 # increase the frame number\n",
|
|
"\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "43926339-1ac7-46f6-9b1b-7f01b523226e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Done processing the video, release resources\n",
|
|
"cap.release()\n",
|
|
"video.release()\n",
|
|
"cv2.destroyAllWindows()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "db30c949-f81f-4cdc-ac3c-1a24d64fcfb9",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "a9be421d-8df7-4655-bd01-783b4e39e7a9",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"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.10.10"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|