How to Set Roi in Opencv

How to set ROI in OpenCV?

I think you have something wrong. If the first one is smaller than the other one and you want to copy the second image in the first one, you don't need an ROI. You can just resize the second image in copy it into the first one.

However if you want to copy the first one in the second one, I think this code should work:

cv::Rect roi = cv::Rect((img2.cols - img1.cols)/2,(img2.rows - img1.rows)/2,img1.cols,img1.rows);

cv::Mat roiImg;
roiImg = img2(roi);

img1.copyTo(roiImg);

Set an ROI in OpenCV

First, I would recommend that you consider using a visual tracker to track each detected rectangle. This is important even if you have an ROI to crop the image close to your counting zone/line. That is because even if the ROI is localized, the detection might still blink a couple of times causing a miscount. That is especially valid if another vehicle can enter the ROI while the first one is still passing it.

I recommend using the easy-to-use tracker provided by the widely used dlib library. Please refer to this example on how to use it.

Instead of counting detections within an ROI, you need to define an ROI line (within your ROI). Then, track detections rectangles centers in each frame. Finally, increase your counter once a rectangle center passes the ROI line.

Regarding how to count a rectangle passing the ROI line:

  1. Select two points to define your ROI line.
  2. Use your points to find the parameters for the general line formula ax + by + c = 0
  3. For each frame, plug the rectangle center coordinates in the formula and keep track of the sign of the result.
  4. If the sign of the result changes that means that the rectangle center has passed the line.

Region of Interest opencv python

Okay, On further analysis realized that the cv2 since it has been supporting numpy array structure, there is no longer any need for a API, the entire image can be manipulated in the array itself.
eg:

img = cv2.imread('image.png')
img = img[c1:c1+25,r1:r1+25]

Here c1 is the left side column pixel location, and r1 is the corresponding row location. And img now has the image specified within the pixels as the ROI.

EDIT:
Very nicely explained here, How to copy a image region using opencv in python?

Setting Custom RoI for OpenCV BoundryBox in Python

Your error comes from a misunderstanding of what cv2.rectangle does.

It doesn't return a rectangle as you imagine. It is actually a drawing function. It draws the rectangle on the image you pass as argument and returns None.

A rectangle is just a tuple in Python with the following coordinates: (start_col, start_row, width, height). You can create it without using an OpenCV function.

Python OpenCV select ROI on video/stream while its playing

You can't use cv2.selectROI() in that case because the function is blocking, i.e. it stops the execution of your program until you have selected your region of interest (or cancelled it).

To achieve what you want you will need to handle the selection of the ROI yourself. Here is a short example of how you can do that, using two left-clicks to define the ROI and a right-click to erase it.

import cv2, sys

cap = cv2.VideoCapture(sys.argv[1])
cv2.namedWindow('Frame', cv2.WINDOW_NORMAL)

# Our ROI, defined by two points
p1, p2 = None, None
state = 0

# Called every time a mouse event happen
def on_mouse(event, x, y, flags, userdata):
global state, p1, p2

# Left click
if event == cv2.EVENT_LBUTTONUP:
# Select first point
if state == 0:
p1 = (x,y)
state += 1
# Select second point
elif state == 1:
p2 = (x,y)
state += 1
# Right click (erase current ROI)
if event == cv2.EVENT_RBUTTONUP:
p1, p2 = None, None
state = 0

# Register the mouse callback
cv2.setMouseCallback('Frame', on_mouse)

while cap.isOpened():
val, frame = cap.read()

# If a ROI is selected, draw it
if state > 1:
cv2.rectangle(frame, p1, p2, (255, 0, 0), 10)
# Show image
cv2.imshow('Frame', frame)

# Let OpenCV manage window events
key = cv2.waitKey(50)
# If ESCAPE key pressed, stop
if key == 27:
cap.release()

Select a static ROI on webcam video on python openCV

Sample Image

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()

How can I select ROI in a separate image in opencv-python?

In the for loop you keep setting/overwriting area1, so the output will always be just one image. You can solve this easily by moving the imshow() into the for loop.

At the top of your code add:

prevNrOfContours = 0

Alter the frame-loop with this code:

    # create a window for each roi
nrOfContours = len(conts)
for i in range(nrOfContours):
x,y,w,h=cv2.boundingRect(conts[i])
area=img[y:y+h, x:x+w] #selecting my ROI
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255), 2)
cv2.imshow("area" + str(i), area)

# if there are more open windows then roi's
# then close the windows that will not be refreshed
if prevNrOfContours > nrOfContours:
for i in range(nrOfContours, prevNrOfContours):
cv2.destroyWindow("area" + str(i))

# store the number of roi's in this frame, so it can
# be used in the next frame
prevNrOfContours = nrOfContours

Edit: extended code to remove unnecessary opened windows

Edit2: to only select the 2 largest contours:

    # instantiate list
contour_list = []

for cnt in contours:
# get contour size
area = cv2.contourArea(cnt)
# add tuple of the contour and its size to the list
contour_list.append((cnt, area))

# sort list on size
sorted_list = sorted(contour_list, key=lambda x: x[1])
# create a window for the 2 largest contours
for i in range(-2,0):
x,y,w,h=cv2.boundingRect(sorted_list[i][0])
roi=img[y:y+h, x:x+w] #selecting my ROI
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255), 2)
cv2.imshow("area" + str(i), roi)


Related Topics



Leave a reply



Submit