单击时在图像中绘制一个固定大小的矩形,并通过移动鼠标来更改其位置

时间:2018-02-01 23:03:08

标签: python python-3.x opencv mouseevent

单击鼠标左键时,我需要在图像中绘制一个固定大小的矩形,并通过移动鼠标在图像中更改其位置。 我想出了这个代码,它基本上在图像中绘制矩形,其中鼠标指针是矩形对角线的交点。

import cv2 as cv
import numpy as np

#flags
move_rectangle = False

#color for rectangle
BLUE = [255,0,0]

def mouse(event,x,y,flags,params):
    global move_rectangle, BLUE

    #draw rectangle where x,y is rectangle center
    if event == cv.EVENT_LBUTTONDOWN:
        move_rectangle = True

    elif event == cv.EVENT_MOUSEMOVE:
        if move_rectangle:
            cv.rectangle(bg,(x-int(0.5*cols),y-int(0.5*rows)),
            (x+int(0.5*cols),y+int(0.5*rows)),BLUE, -1)

    elif event == cv.EVENT_LBUTTONUP:
        move_rectangle = False
        cv.rectangle(bg,(x-int(0.5*cols),y-int(0.5*rows)),
        (x+int(0.5*cols),y+int(0.5*rows)),BLUE, -1)


if __name__ == '__main__':

    #loading images
    fg = cv.imread('sample.jpg')
    bg = cv.imread('beach.jpg')
    #grabing height and width of foreground image
    rows, cols = fg.shape[:2]

    cv.namedWindow('draw')
    cv.setMouseCallback('draw', mouse)

    while True:

        cv.imshow('draw', bg)
        k = cv.waitKey(1)

        #waiting for esc to exit
        if k == 27 & 0xFF:
            break

    cv.destroyAllWindows()

但是,我无法弄清楚如何只在鼠标指针的位置绘制矩形。我需要摆脱那个"影子"在前面的矩形后面。

image description

如何做到这一点?

1 个答案:

答案 0 :(得分:0)

我相信您需要做的只是在收到移动事件时重新初始化您的图像

import cv2 as cv

move_rectangle = False
BLUE = [255,0,0]

fg = cv.imread('sample.jpg')
bg = cv.imread('beach.jpg')
bgCopy = bg.copy()

def mouse(event,x,y,flags,params):
    global move_rectangle, BLUE, fg, bg, bgCopy
    #draw rectangle where x,y is rectangle center
    if event == cv.EVENT_LBUTTONDOWN:
        move_rectangle = True

    elif event == cv.EVENT_MOUSEMOVE:
        bg = bgCopy.copy() #!! your image is reinitialized with initial one
        if move_rectangle:
            cv.rectangle(bg,(x-int(0.5*cols),y-int(0.5*rows)),
            (x+int(0.5*cols),y+int(0.5*rows)),BLUE, -1)

    elif event == cv.EVENT_LBUTTONUP:
        move_rectangle = False
        cv.rectangle(bg,(x-int(0.5*cols),y-int(0.5*rows)),
        (x+int(0.5*cols),y+int(0.5*rows)),BLUE, -1)

if __name__ == '__main__':
    rows, cols = fg.shape[:2]

    cv.namedWindow('draw')
    cv.setMouseCallback('draw', mouse)

    while True:

        cv.imshow('draw', bg)
        k = cv.waitKey(1)

        #waiting for esc to exit
        if k == 27 & 0xFF:
            break

    cv.destroyAllWindows()