Вопрос по python, mouseevent, opencv, draw – Python OpenCV: обратный вызов мыши для рисования прямоугольника

3

Я хочу сохранить изображение из видеопотока, а затем нарисовать прямоугольник на показанном изображении, чтобы создать интересующую область. Позже сохраните эту область в файле. Я использовал opencv python grabcut для использования функции setMouseCallback. Но я не знаю, что я делаю неправильно, потому что это не дает ожидаемого результата. Я хотел бы видеть зеленый прямоугольник, нарисованный на статическом изображении, показанном на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

    # 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()
Вы сказали, что это не дает ожидаемого результата. Что в итоге? Christopher Peterson
@ChristopherPeterson результат - то, что roi не сохранен, и я не вижу прямоугольник на изображении вmouse input окно. samkhan13

Ваш Ответ

2   ответа
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))
0

Это моя текущая работа, где я снова рендерингmouse input окно наEVENT_LBUTTONUP, Чтобы избежать появления ограничительной рамки в области интереса, сохраненной в файле, я использую копию введенной сцены:

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 Я получаю несколько прямоугольников, нарисованных на изображении. Если кто-то отвечает способом визуализации одного прямоугольника во время его создания, я могу принять его.

Похожие вопросы