3

How to get webcam video feed, for specific width and height?

I have zero experience with OpenCV library, so I need help in this regard. This code is from geeksforgeeks.com. This is the only thing I have right now.

What I'm trying to achieve is that, I want to detect motion in only specified area of video feed.

import cv2, time, pandas



from datetime import datetime 



static_back = None
motion_list = [ None, None ] 
time = [] 
df = pandas.DataFrame(columns = ["Start", "End"]) 
video = cv2.VideoCapture(0) 



while True: 
    check, frame = video.read() 
    motion = 0
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 
    gray = cv2.GaussianBlur(gray, (21, 21), 0)



if static_back is None: 
    static_back = gray 
    continue

diff_frame = cv2.absdiff(static_back, gray) 

thresh_frame = cv2.threshold(diff_frame, 30, 255, cv2.THRESH_BINARY)[1] 
thresh_frame = cv2.dilate(thresh_frame, None, iterations = 2) 

(cnts, _) = cv2.findContours(thresh_frame.copy(),  
                   cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 

for contour in cnts: 
    if cv2.contourArea(contour) < 50000: 
        continue
    motion = 1

    (x, y, w, h) = cv2.boundingRect(contour) 
    # making green rectangle arround the moving object 
    cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3) 

motion_list.append(motion) 

motion_list = motion_list[-2:] 

if motion_list[-1] == 1 and motion_list[-2] == 0: 
    time.append(datetime.now()) 

if motion_list[-1] == 0 and motion_list[-2] == 1: 
    time.append(datetime.now()) 

cv2.imshow("Gray Frame", gray) 

cv2.imshow("Difference Frame", diff_frame) 

cv2.imshow("Threshold Frame", thresh_frame) 

cv2.imshow("Color Frame", frame) 

key = cv2.waitKey(1) 
if key == ord('q'): 
    # if something is movingthen it append the end time of movement 
    if motion == 1: 
        time.append(datetime.now()) 
    break


for i in range(0, len(time), 2): 
    df = df.append({"Start":time[i], "End":time[i + 1]}, ignore_index = True)

df.to_csv("Time_of_movements.csv") 
video.release() 
cv2.destroyAllWindows()
nathancy
  • 42,661
  • 14
  • 115
  • 137
MQaiser
  • 111
  • 1
  • 3
  • 8

1 Answers1

8

It seems like you want to obtain the region of interest (ROI) for a particular area of each frame. To do this in OpenCV, we can crop the image using bounding box coordinates. Consider (0,0) as the top left corner of the image with left-to-right as the x-direction and top-to-bottom as the y-direction. If we have (x1, y1) as the top-left vertex and (x2,y2) as the bottom-right vertex of a ROI, we can crop the image by:

ROI = frame[y1:y2, x1:x2]

As an illustration:

-------------------------------------------
|                                         | 
|    (x1, y1)                             |
|      ------------------------           |
|      |                      |           |
|      |                      |           | 
|      |         ROI          |           |  
|      |                      |           |   
|      |                      |           |   
|      |                      |           |       
|      ------------------------           |   
|                           (x2, y2)      |    
|                                         |             
|                                         |             
|                                         |             
-------------------------------------------

We are able to do this since images are stored as a Numpy array in OpenCV. Here is a great resource for Numpy array indexing and slicing. Once you have the desired ROI, you can do your motion detecting in this region.

nathancy
  • 42,661
  • 14
  • 115
  • 137