I need to selec a ROI (region of interest), or work area, on a live video from my webcam and take a snapshot of ONLY this work area or ROI, but I can't found how to do this.
In this page https://www.learnopencv.com/how-to-select-a-bounding-box-roi-in-opencv-cpp-python/ have a code for draw a ROI but only with images, not a live video.
import cv2
cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cv2.namedWindow("test")
img_counter = 0
while True:
ret, frame = cam.read()
cv2.imshow("test", frame)
if not ret:
break
k = cv2.waitKey(1)
if k % 256 == 27:
# ESC pressed
print("Escape hit, closing...")
break
elif k % 256 == 32:
# SPACE pressed
img_name = "opencv_frame_{}.png".format(img_counter)
cv2.imwrite(img_name, frame)
print("{} written!".format(img_name))
img_counter += 1
cam.release()
cv2.destroyAllWindows()
This code take a snapshot with space key but not draw a ROI area.
Thanks in advance!
Here's a widget to select static ROIs from a video frame. Essentially the idea is to use cv2.setMouseCallback() and event handlers to detect if the mouse has been clicked or released. For this implementation, you can extract coordinates by holding down the left mouse button and dragging to select the desired ROI. You can reset the ROI using the right mouse button. To use the widget, press c to pause the video and start cropping. Then you are free to select the ROI. Once you have selected your ROI, press c again to crop the desired section. To resume the video, press r.
import cv2
class staticROI(object):
def __init__(self):
self.capture = cv2.VideoCapture('fedex.mp4')
# Bounding box reference points and boolean if we are extracting coordinates
self.image_coordinates = []
self.extract = False
self.selected_ROI = False
self.update()
def update(self):
while True:
if self.capture.isOpened():
# Read frame
(self.status, self.frame) = self.capture.read()
cv2.imshow('image', self.frame)
key = cv2.waitKey(2)
# Crop image
if key == ord('c'):
self.clone = self.frame.copy()
cv2.namedWindow('image')
cv2.setMouseCallback('image', self.extract_coordinates)
while True:
key = cv2.waitKey(2)
cv2.imshow('image', self.clone)
# Crop and display cropped image
if key == ord('c'):
self.crop_ROI()
self.show_cropped_ROI()
# Resume video
if key == ord('r'):
break
# Close program with keyboard 'q'
if key == ord('q'):
cv2.destroyAllWindows()
exit(1)
else:
pass
def extract_coordinates(self, event, x, y, flags, parameters):
# Record starting (x,y) coordinates on left mouse button click
if event == cv2.EVENT_LBUTTONDOWN:
self.image_coordinates = [(x,y)]
self.extract = True
# Record ending (x,y) coordintes on left mouse bottom release
elif event == cv2.EVENT_LBUTTONUP:
self.image_coordinates.append((x,y))
self.extract = False
self.selected_ROI = True
# Draw rectangle around ROI
cv2.rectangle(self.clone, self.image_coordinates[0], self.image_coordinates[1], (0,255,0), 2)
# Clear drawing boxes on right mouse button click
elif event == cv2.EVENT_RBUTTONDOWN:
self.clone = self.frame.copy()
self.selected_ROI = False
def crop_ROI(self):
if self.selected_ROI:
self.cropped_image = self.frame.copy()
x1 = self.image_coordinates[0][0]
y1 = self.image_coordinates[0][1]
x2 = self.image_coordinates[1][0]
y2 = self.image_coordinates[1][1]
self.cropped_image = self.cropped_image[y1:y2, x1:x2]
print('Cropped image: {} {}'.format(self.image_coordinates[0], self.image_coordinates[1]))
else:
print('Select ROI to crop before cropping')
def show_cropped_ROI(self):
cv2.imshow('cropped image', self.cropped_image)
if __name__ == '__main__':
static_ROI = staticROI()
Related
I am trying to write some code, where I want to save some images from the webcam on python using opencv and then I want to open each image, and on each image using a bounding box select a region of interest(ROI) that will be cropped out and save this cropped image in a new folder. For this, I am using the cv2.setMouseCallback and drawing a rectangle on each image. My code works, but the cropped images that are stored are very strange.
import cv2
# Opens the inbuilt camera of laptop to capture video.
cap = cv2.VideoCapture(0)
i = 0
training_images = []
def draw_bounding_box(click, x, y, flag_param, parameters):
global x_pt, y_pt, drawing, top_left_point, bottom_right_point, image
if click == cv2.EVENT_LBUTTONDOWN:
drawing = True
print("drawing="+str(drawing))
x_pt, y_pt = x, y
print("x_pt="+str(x_pt))
elif click == cv2.EVENT_MOUSEMOVE:
if drawing:
top_left_point, bottom_right_point = (x_pt,y_pt), (x,y)
image[y_pt:y, x_pt:x] = 255 - image[y_pt:y, x_pt:x]
cv2.rectangle(image, top_left_point, bottom_right_point, (0,255,0), 2)
elif click == cv2.EVENT_LBUTTONUP:
drawing = False
top_left_point, bottom_right_point = (x_pt,y_pt), (x,y)
copy[y_pt:y, x_pt:x] = 255 - copy[y_pt:y, x_pt:x]
cv2.rectangle(image, top_left_point, bottom_right_point, (0,255,0), 2)
bounding_box = (x_pt, y_pt, x-x_pt, y-y_pt)
cropped_im = image[y_pt:y,x_pt:x]
training_images.append(cropped_im)
if len(cropped_im)>0:
cv2.imshow("cropped",cropped_im)
cv2.imwrite('C:/Downloads/testingPictures/Frame'+str(i)+'.jpg',cropped_im)
cv2.waitKey(3000)
else:
print("could not save")
if __name__ == '__main__':
drawing = False
while(cap.isOpened() and i<10):
ret, frame = cap.read()
# This condition prevents from infinite looping
# incase video ends.
if ret == False:
break
# Save Frame by Frame into disk using imwrite method
cv2.imwrite('C:/Downloads/testingPictures/Frame'+str(i)+'.jpg', frame)
i += 1
print(i)
while(i>=1):
image = cv2.imread('C:/Users/shrut/Downloads/testingPictures/Frame'+str(i-1)+'.jpg')
copy = image.copy()
i = i-1
s = len(training_images)
cv2.namedWindow('Frame')
cv2.imshow('Frame', copy)
cv2.setMouseCallback('Frame', draw_bounding_box)
s_curr = len(training_images)
k = cv2.waitKey(5000) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
print(i)
print(len(training_images))
This is what the saved "cropped images" look like
(https://i.stack.imgur.com/KUrEs.jpg)
It looks like multiple bounding boxes superposed on the image. How can I avoid this and get the area from the image instead?
import cv2
class ExtractImageWidget(object):
def __init__(self):
self.original_image = cv2.imread('0001.jpg')
# Resize image, remove if you want raw image size
self.original_image = cv2.resize(self.original_image, (640, 556))
self.clone = self.original_image.copy()
cv2.namedWindow('image')
cv2.setMouseCallback('image', self.extract_coordinates)
# Bounding box reference points and boolean if we are extracting coordinates
self.image_coordinates = []
self.extract = False
def extract_coordinates(self, event, x, y, flags, parameters):
# Record starting (x,y) coordinates on left mouse button click
if event == cv2.EVENT_LBUTTONDOWN:
self.image_coordinates = [(x,y)]
self.extract = True
# Record ending (x,y) coordintes on left mouse bottom release
elif event == cv2.EVENT_LBUTTONUP:
self.image_coordinates.append((x,y))
self.extract = False
print('top left: {}, bottom right: {}'.format(self.image_coordinates[0], self.image_coordinates[1]))
# Draw rectangle around ROI
cv2.rectangle(self.clone, self.image_coordinates[0], self.image_coordinates[1], (0,255,0), 2)
cv2.imshow("image", self.clone)
# Clear drawing boxes on right mouse button click
elif event == cv2.EVENT_RBUTTONDOWN:
self.clone = self.original_image.copy()
def show_image(self):
return self.clone
if __name__ == '__main__':
extract_image_widget = ExtractImageWidget()
while True:
cv2.imshow('image', extract_image_widget.show_image())
key = cv2.waitKey(1)
# Close program with keyboard 'q'
if key == ord('q'):
cv2.destroyAllWindows()
exit(1)
I am working on video input where video is divided into frames. Now I have to draw a rectangle over the text which my region of interest. So, I need to store all the coordinate points of all the rectangles which I drew on frame in the csv file. And I need to crop all the rectangle from each frame.
I am sending the program which is written in python. Extend to that, I want all rectangle to be selected per frame.
self.capture = cv2.VideoCapture('ch3_train/Video_2_1_2.mp4')
# Bounding box reference points and boolean if we are extracting coordinates
self.image_coordinates = []
self.extract = False
self.selected_ROI = False
self.update()
def update(self):
while True:
if self.capture.isOpened():
# Read frame
(self.status, self.frame) = self.capture.read()
for i in range(len(self.frame)):
cv2.imshow('image', self.frame)
key = cv2.waitKey(2)
# Crop image
if key == ord('c'):
self.clone = self.frame.copy()
cv2.namedWindow('image')
cv2.setMouseCallback('image', self.extract_coordinates)
while True:
key = cv2.waitKey(2)
cv2.imshow('image', self.clone)
# Crop and display cropped image
if key == ord('c'):
self.crop_ROI()
self.show_cropped_ROI()
# Resume video
if key == ord('r'):
break
# Close program with keyboard 'q'
if key == ord('q'):
cv2.destroyAllWindows()
self.capture.release()
exit(1)
else:
sys.exit()
#pass
def extract_coordinates(self, event, x, y, flags, parameters):
# Record starting (x,y) coordinates on left mouse button click
if event == cv2.EVENT_LBUTTONDOWN:
self.image_coordinates = [(x,y)]
self.extract = True
# Record ending (x,y) coordintes on left mouse bottom release
elif event == cv2.EVENT_LBUTTONUP:
self.image_coordinates.append((x,y))
self.extract = False
self.selected_ROI = True
# (x1,y1,x2,y2)=[int(v) for v in f ]
# Draw rectangle around ROI
cv2.rectangle(self.clone, self.image_coordinates[0], self.image_coordinates[1], (0,255,0), 2)
'''
while self.selected_ROI:
x1 = self.image_coordinates[0][0]
y1 = self.image_coordinates[0][1]
x2 = self.image_coordinates[1][0]
y2 = self.image_coordinates[1][1]
with open ('train_annotations_bbox.csv',mode='w') as bboxfile:
bboxwriter=csv.writer(bboxfile,delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
bboxwriter.writerow(['Xmin','Xmax','Ymin','Ymax'])#[self.image_coordinators[1],self.image_coordinators[0]])
bboxwriter.writerow([x1*0.001,y1*0.001,x2*0.001,y2*0.001])
'''
#for i in event:
# cv2.imwrite("frame%d"+i+".jpg",self.clone)
# Clear drawing boxes on right mouse button click
elif event == cv2.EVENT_RBUTTONDOWN:
self.clone = self.frame.copy()
self.selected_ROI = False
def crop_ROI(self):
if self.selected_ROI:
self.cropped_image = self.frame.copy()
x1 = self.image_coordinates[0][0]
y1 = self.image_coordinates[0][1]
x2 = self.image_coordinates[1][0]
y2 = self.image_coordinates[1][1]
self.cropped_image = self.cropped_image[y1:y2, x1:x2]
print('Cropped image: {} {}'.format(self.image_coordinates[0], self.image_coordinates[1]))
#fromCenter=False
#ROIs=cv2.selectROIs('Select ROIs',self.selected_ROI,fromCenter)
#for i, ctr in enumerate(self.selected_ROI):
# cv2.imshow('roi'+str(i),self.cropped_image)
else:
print('Select ROI to crop before cropping')
def show_cropped_ROI(self):
cv2.imshow('cropped image', self.cropped_image)
I expected the output to be loop over rectangles to store its coordinate points in csv file.But actual output is storing only last rectangle selected in the csv file.
AM doing a project on selected object tracking as part of it i have to detect orb feature in a selected square region a video using opencv and python.but this code doesn't work.please help me and thanks in advance
import numpy as np
import cv2
rect = (0,0,0,0)
startPoint = False
endPoint = False
def on_mouse(event,x,y,flags,params):
global rect,startPoint,endPoint
# get mouse click
if event == cv2.EVENT_LBUTTONDOWN:
if startPoint == True and endPoint == True:
startPoint = False
endPoint = False
rect = (0, 0, 0, 0)
if startPoint == False:
rect = (x, y, 0, 0)
startPoint = True
elif endPoint == False:
rect = (rect[0], rect[1], x, y)
endPoint = True
cap = cv2.VideoCapture('demo.mp4')
waitTime = 50
#Reading the first frame
(grabbed, frame) = cap.read()
#taking frames one by one
while(cap.isOpened()):
(grabbed, frame) = cap.read()
cv2.namedWindow('frame')
cv2.setMouseCallback('frame', on_mouse)
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
orb = cv2.ORB_create()
kp = orb.detect(gray,None)
img2=frame.copy()
frame=cv2.drawKeypoints(gray,kp,img2,color=(0,255,0),flags=0)
cv2.imshow('frame', img2)
#waitkey
if cv2.waitKey(10)==27:
break
cv2.imshow('Video', img2)
cap.release()
cv2.destroyAllWindows()
i am new to opencv -python.
I want to draw a rectangle in a live stream video captured from my webcam. While drawing the rectangle,the video must freeze. I am successful in drawing a rectangle on a image,but i don't know how to do the same on a live video using opencv and python . Please help..
This is a code that I'm using to draw a rectange in videos.
The code works like that:
click on video and the script save the start point
click again and the script save the end point and draw the rectangle
click again to start drawing another retangle
import numpy as np
import cv2
rect = (0,0,0,0)
startPoint = False
endPoint = False
def on_mouse(event,x,y,flags,params):
global rect,startPoint,endPoint
# get mouse click
if event == cv2.EVENT_LBUTTONDOWN:
if startPoint == True and endPoint == True:
startPoint = False
endPoint = False
rect = (0, 0, 0, 0)
if startPoint == False:
rect = (x, y, 0, 0)
startPoint = True
elif endPoint == False:
rect = (rect[0], rect[1], x, y)
endPoint = True
cap = cv2.VideoCapture('../videos/sample.avi')
waitTime = 50
#Reading the first frame
(grabbed, frame) = cap.read()
while(cap.isOpened()):
(grabbed, frame) = cap.read()
cv2.namedWindow('frame')
cv2.setMouseCallback('frame', on_mouse)
#drawing rectangle
if startPoint == True and endPoint == True:
cv2.rectangle(frame, (rect[0], rect[1]), (rect[2], rect[3]), (255, 0, 255), 2)
cv2.imshow('frame',frame)
key = cv2.waitKey(waitTime)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()