Im trying to create multiple ROIs over my webcam stream. Ive used this library called roipoly (https://github.com/jdoepfert/roipoly.py)
I modified the example code (examples/multi_roi_example.py) to work on webcam , which now looks like this
import logging
import cv2
import numpy as np
from matplotlib import pyplot as plt
from roipoly import MultiRoi
logging.basicConfig(format='%(levelname)s ''%(processName)-10s : %(asctime)s '
'%(module)s.%(funcName)s:%(lineno)s %(message)s',
level=logging.INFO)
cap = cv2.VideoCapture(1)
while cap.isOpened():
# Create image
val,img =cap.read()
#img = np.ones((100, 100)) * range(0, 100)
# Show the image
fig = plt.figure()
plt.imshow(img, interpolation='nearest', cmap="Greys")
plt.title("Click on the button to add a new ROI")
# Draw multiple ROIs
multiroi_named = MultiRoi(roi_names=['My first ROI', 'My second ROI'])
# Draw all ROIs
plt.imshow(img, interpolation='nearest', cmap="Greys")
roi_names = []
for name, roi in multiroi_named.rois.items():
roi.display_roi()
roi.display_mean(img)
roi_names.append(name)
plt.legend(roi_names, bbox_to_anchor=(1.2, 1.05))
plt.show()
# Let OpenCV manage window events
key = cv2.waitKey(50)
# If ESCAPE key pressed, stop
if key == 27:
cap.release()
But the issue is that after drawing the ROI, the video stream remains paused and never continues. How to resume the webcam stream along with the ROI on top of it
CodePudding user response:
I see few problems.
Main problem is that plt.show()
is waiting until you close window and this is blocking rest of code.
It needs plt.show(block=False)
and this needs also plt.pause(0.001)
so it would have time to update image in window.
plt.show(block=False)
plt.pause(0.001)
Other problem is that you run ROI in every loop - so you would have to use some boolean variable to skip it after selecting
select_roi = True
while cap.isOpened():
# ... code ...
if select_roi:
fig = plt.figure()
plt.imshow(img, interpolation='nearest', cmap="Greys")
plt.title("Click on the button to add a new ROI")
# Draw multiple ROIs
multiroi_named = MultiRoi(roi_names=['My first ROI', 'My second ROI'])
select_roi = False
# ... code ...
or you should select ROI before loop
fig = plt.figure()
plt.imshow(img, interpolation='nearest', cmap="Greys")
plt.title("Click on the button to add a new ROI")
# Draw multiple ROIs
multiroi_named = MultiRoi(roi_names=['My first ROI', 'My second ROI'])
while cap.isOpened():
# ... code ...
Other problem is waitKey
which works only if you display image with cv2.imshow(...)
but you don't use it so waitKey
will not get keys.
Other problem is that cv2 gives image in colors BGR
but matplotlib
needs RGB
- so you have to convert it.
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
Full working code:
version with boolean variable select_roi
import cv2
from matplotlib import pyplot as plt
from roipoly import MultiRoi
#cap = cv2.VideoCapture(0) # my built-in webcam
cap = cv2.VideoCapture(1)
select_roi = True # default value as start
while cap.isOpened():
val, img = cap.read()
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
if select_roi:
# Show the image
fig = plt.figure()
plt.imshow(img, interpolation='nearest', cmap="Greys")
plt.title("Click on the button to add a new ROI")
# Draw multiple ROIs
multiroi_named = MultiRoi(roi_names=['My first ROI', 'My second ROI'])
select_roi = False
# --- after if ---
# Draw all ROIs
plt.imshow(img, interpolation='nearest', cmap="Greys")
roi_names = []
for name, roi in multiroi_named.rois.items():
roi.display_roi()
#roi.display_mean(img)
roi_names.append(name)
plt.legend(roi_names, bbox_to_anchor=(1.2, 1.05))
plt.show(block=False)
plt.pause(0.001)
version with ROI before loop
import cv2
from matplotlib import pyplot as plt
from roipoly import MultiRoi
#cap = cv2.VideoCapture(0) # my built-in webcam
cap = cv2.VideoCapture(1)
val, img = cap.read()
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Show the image
fig = plt.figure()
plt.imshow(img, interpolation='nearest', cmap="Greys")
plt.title("Click on the button to add a new ROI")
# Draw multiple ROIs
multiroi_named = MultiRoi(roi_names=['My first ROI', 'My second ROI'])
while cap.isOpened():
val, img = cap.read()
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Draw all ROIs
plt.imshow(img, interpolation='nearest', cmap="Greys")
roi_names = []
for name, roi in multiroi_named.rois.items():
roi.display_roi()
#roi.display_mean(img)
roi_names.append(name)
plt.legend(roi_names, bbox_to_anchor=(1.2, 1.05))
plt.show(block=False)
plt.pause(0.001)
BTW: if you need rectangle ROI then there is cv2.selectROI()
to select one region and cv2.cv2.selectROIs()
to select many regions
results = cv2.selectROIs('image', img)
and it doesn't need to convert from BGR
to RGB
.