我想从视频流中保存图像,然后在显示的图像上绘制一个矩形以生成感兴趣的区域。稍后,将该ROI保存在文件中。我使用opencv python grabcut示例来使用setMouseCallback函数。但我不知道我做错了什么,因为它没有给出我期望的结果。我希望在mouse input
窗口中显示的静态图像上绘制绿色矩形,并将roi保存到文件中。请帮助调试此代码或显示更好的方法:
import cv2
rect = (0,0,1,1)
rectangle = False
rect_over = False
def onmouse(event,x,y,flags,params):
global sceneImg,rectangle,rect,ix,iy,rect_over
# Draw Rectangle
if event == cv2.EVENT_LBUTTONDOWN:
rectangle = True
ix,iy = x,y
elif event == cv2.EVENT_MOUSEMOVE:
if rectangle == True:
cv2.rectangle(sceneImg,(ix,iy),(x,y),(0,255,0),2)
rect = (min(ix,x),min(iy,y),abs(ix-x),abs(iy-y))
elif event == cv2.EVENT_LBUTTONUP:
rectangle = False
rect_over = True
cv2.rectangle(sceneImg,(ix,iy),(x,y),(0,255,0),2)
rect = (min(ix,x),min(iy,y),abs(ix-x),abs(iy-y))
x1,y1,w,h = rect
roi = sceneImg[y1:y1+h, x1:x1+w]
cv2.imwrite('roi.jpg', roi)
# Named window and mouse callback
cv2.namedWindow('video')
cv2.namedWindow('mouse input')
cv2.setMouseCallback('mouse input',onmouse)
camObj = cv2.VideoCapture(-1)
keyPressed = None
running = True
scene = False
# Start video stream
while running:
readOK, frame = camObj.read()
keyPressed = cv2.waitKey(5)
if keyPressed == ord('s'):
scene = True
cv2.imwrite('sceneImg.jpg',frame)
sceneImg = cv2.imread('sceneImg.jpg')
cv2.destroyWindow('video')
cv2.imshow('mouse input', sceneImg)
elif keyPressed == ord('r'):
scene = False
cv2.destroyWindow('mouse input')
elif keyPressed == ord('q'):
running = False
if not scene:
cv2.imshow('video', frame)
cv2.destroyAllWindows()
camObj.release()
答案 0 :(得分:1)
每次调用{event == cv2.EVENT_MOUSEMOVE:}时,您都需要重置图像。
您的代码应如下所示:
if event == cv2.EVENT_LBUTTONDOWN:
rectangle = True
ix,iy = x,y
elif event == cv2.EVENT_MOUSEMOVE:
if rectangle == True:
sceneImg = sceneImg2.copy()
cv2.rectangle(sceneImg,(ix,iy),(x,y),(0,255,0),2)
rect = (min(ix,x),min(iy,y),abs(ix-x),abs(iy-y))
elif event == cv2.EVENT_LBUTTONUP:
rectangle = False
rect_over = True
cv2.rectangle(sceneImg,(ix,iy),(x,y),(0,255,0),2)
rect = (min(ix,x),min(iy,y),abs(ix-x),abs(iy-y))
答案 1 :(得分:0)
这是我目前的工作,我再次在mouse input
上呈现EVENT_LBUTTONUP
窗口。为了避免在ROI中显示的边界框保存到文件中,我使用了输入场景的副本:
import cv2
rect = (0,0,1,1)
rectangle = False
rect_over = False
def onmouse(event,x,y,flags,params):
global sceneImg,rectangle,rect,ix,iy,rect_over, roi
# Draw Rectangle
if event == cv2.EVENT_LBUTTONDOWN:
rectangle = True
ix,iy = x,y
elif event == cv2.EVENT_MOUSEMOVE:
if rectangle == True:
# cv2.rectangle(sceneCopy,(ix,iy),(x,y),(0,255,0),1)
rect = (min(ix,x),min(iy,y),abs(ix-x),abs(iy-y))
elif event == cv2.EVENT_LBUTTONUP:
rectangle = False
rect_over = True
sceneCopy = sceneImg.copy()
cv2.rectangle(sceneCopy,(ix,iy),(x,y),(0,255,0),1)
rect = (min(ix,x),min(iy,y),abs(ix-x),abs(iy-y))
roi = sceneImg[rect[1]:rect[1]+rect[3], rect[0]:rect[0]+rect[2]]
cv2.imshow('mouse input', sceneCopy)
cv2.imwrite('roi.jpg', roi)
# Named window and mouse callback
cv2.namedWindow('mouse input')
cv2.setMouseCallback('mouse input',onmouse)
cv2.namedWindow('video')
camObj = cv2.VideoCapture(-1)
keyPressed = None
running = True
scene = False
# Start video stream
while running:
readOK, frame = camObj.read()
keyPressed = cv2.waitKey(5)
if keyPressed == ord('s'):
scene = True
cv2.destroyWindow('video')
cv2.imwrite('sceneImg.jpg',frame)
sceneImg = cv2.imread('sceneImg.jpg')
cv2.imshow('mouse input', sceneImg)
elif keyPressed == ord('r'):
scene = False
cv2.destroyWindow('mouse input')
elif keyPressed == ord('q'):
running = False
if not scene:
cv2.imshow('video', frame)
cv2.destroyAllWindows()
camObj.release()
因此,我可以看到应该绑定ROI的矩形,但是当鼠标左键按下并且鼠标光标移动时,我仍然不知道如何可视化边界框。该可视化在抓取示例中起作用,但在我的情况下我无法弄清楚。在EVENT_MOUSEMOVE
期间取消注释绘制矩形的线时,我会在图像上绘制多个矩形。如果有人用一种方法来回答单个矩形的可视化,我可以接受它。