2015-03-03 70 views
3

我想從視頻流中保存圖像,然後在顯示的圖像上繪製一個矩形以產生感興趣的區域。稍後,將該ROI保存在一個文件中。我使用opencv python grabcut示例來使用setMouseCallback函數。但我不知道自己做錯了什麼,因爲它沒有給出我期望的結果。我希望看到在mouse input窗口中顯示的靜態圖像上繪製的綠色矩形,並將roi保存到文件中。請幫忙調試代碼或顯示一個更好的辦法:Python OpenCV:繪製矩形的鼠標回調

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

你說是不是給你所期望的結果。結果是什麼? – 2015-03-03 06:05:14

+0

@ChristopherPeterson結果是roi沒有保存,我在'mouse input'窗口中看不到圖像上的矩形。 – samkhan13 2015-03-03 09:02:57

回答

0

這是我目前的工作圍繞在這裏我再次呼籲EVENT_LBUTTONUP渲染mouse input窗口。爲了避免邊框顯示保存到文件我用在輸入的場景副本的投資回報率高達:

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

因此,我可以想像這是應該綁定的投資回報率,但我仍然不知道該矩形如何在鼠標左鍵關閉並且鼠標光標正在移動時可視化邊界框。這個可視化工作在抓取的例子中,但我無法想象它在我的情況。在EVENT_MOUSEMOVE期間取消註釋用於繪製矩形的線條時,我會在圖像上繪製多個矩形。如果有人用一種方式來呈現一個矩形的形象,我可以接受它。

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