Python OpenCV: callback del ratón para dibujar un rectángulo

Quiero guardar una imagen del flujo de video y luego dibujar un rectángulo en la imagen mostrada para producir una región de interés. Más tarde, guarde ese retorno de la inversión en un archivo. Usé el ejemplo del corte de grab de python de opencv para usar la función setMouseCallback. Pero no sé qué estoy haciendo incorrectamente, ya que no está dando el resultado que espero. Me gustaría ver el rectángulo verde dibujado en la imagen estática que se muestra en mouse input ventana de mouse input y el roi que se está guardando en el archivo. Por favor ayude a depurar este código o mostrar un mejor enfoque:

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

Debe restablecer la imagen cada vez que se llame el {evento == cv2.EVENT_MOUSEMOVE:}.

Su código debe verse algo como esto:

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

Este es mi trabajo actual en torno al lugar en el que renderizo la ventana de mouse input del mouse input en EVENT_LBUTTONUP Para evitar que aparezca el cuadro delimitador en el ROI guardado en el archivo, uso una copia de la escena ingresada:

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

Por lo tanto, puedo visualizar el rectángulo que se supone limita el ROI, pero aún no sé cómo visualizar el cuadro delimitador mientras el botón izquierdo del mouse está abajo y el cursor del mouse se está moviendo. Esa visualización funciona en el ejemplo de corte, pero no pude resolverlo en mi caso. Al descomprimir la línea para dibujar un rectángulo durante EVENT_MOUSEMOVE , obtengo múltiples rectangularjs dibujados en la imagen. Si alguien responde con una forma de visualizar un solo rectángulo a medida que se crea, puedo aceptarlo.