如何使用opencv在python中绘制完美的线条

时间:2018-05-14 09:59:18

标签: python-3.x opencv

我试图通过单击并拖动鼠标来使用鼠标事件绘制完美的线条。 问题是在绘图时会打印多行。

这是我一直在测试的代码。

import cv2
import numpy as np

drawing = False
x1,y1 = -1,-1

def draw_shape(event,x,y,flag,parm):
    global x1,y1,drawing

    if event == cv2.EVENT_LBUTTONDOWN:
        #print('Cliked',x,y)
        #print('('+str(x)+','+str(y)+')')
        #cv2.line(img1,(x,y),(x,y),(0,0,255),2)
        drawing = True
        x1,y1 = x,y
        cv2.line(img1,(x1,y1),(x,y),(0,0,255),2)


    elif event == cv2.EVENT_MOUSEMOVE:
        #drawing = False
        #print('('+str(x)+','+str(y)+')')
        if drawing == True:
            #print('('+str(x)+','+str(y)+')')
            a = x
            b = y
            if a != x & b != y:
                cv2.line(img1,(x1,y1),(x,y),(0,0,255),2)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        #print('Released',x,y)
        cv2.line(img1,(x1,y1),(x,y),(0,0,255),2)



img1 = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('Draw')
cv2.setMouseCallback('Draw',draw_shape)


while(True):
    cv2.imshow('Draw',img1)
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()  

2 个答案:

答案 0 :(得分:2)

您应该在event == cv2.EVENT_MOUSEMOVE的每个状态中清除图像(将背景设置为黑色)。

您只需在img1[:]=0中绘制一条线之前添加event == cv2.EVENT_MOUSEMOVE即可:

elif event == cv2.EVENT_MOUSEMOVE:
    #drawing = False
    #print('('+str(x)+','+str(y)+')')
    if drawing == True:
        #print('('+str(x)+','+str(y)+')')
        a = x
        b = y
        if a != x & b != y:
            img1[:]=0 # <---------------- HERE
            cv2.line(img1,(x1,y1),(x,y),(0,0,255),2)

结果将是:

enter image description here

<强>更新

如果您想要绘制多个图片,则应冻结每个cv2.EVENT_LBUTTONDOWN:事件中的图片,并将其设置为每个cv2.EVENT_MOUSEMOVE事件:

    global x1,y1,drawing, freeze_image # <------------------------

        if event == cv2.EVENT_LBUTTONDOWN:
            freeze_image = np.copy(img1) # <------------------------
            drawing = True
            x1,y1 = x,y
            cv2.line(img1,(x1,y1),(x,y),(0,0,255),2)

...

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            a = x
            b = y
            if a != x & b != y:
                img1[:]=np.copy(freeze_image) # <------------------------
                cv2.line(img1,(x1,y1),(x,y),(0,0,255),2)

结果:

enter image description here

答案 1 :(得分:2)

在移动时绘制支持的图像可能是一个选择:

enter image description here

#!/usr/bin/python3
# 2018/05/14 19:17:13
import cv2
import numpy as np

drawing = False
x2,y2 = -1,-1

def draw_shape(event,x,y,flag,parm):
    global x2,y2,drawing, img, img2

    if event == cv2.EVENT_LBUTTONDOWN:
        print('Cliked: ', (x,y))
        drawing = True
        img2 = img.copy()
        x2,y2 = x,y
        cv2.line(img,(x2,y2),(x,y),(0,0,255),1, cv2.LINE_AA)

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            print('Moving: ',(x,y))
            a, b = x, y
            if a != x & b != y:
                img = img2.copy()
                cv2.line(img,(x2,y2),(x,y),(0,255,0),1, cv2.LINE_AA)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        print('Released: ',(x,y))
        img = img2.copy()
        cv2.line(img,(x2,y2),(x,y),(0,0,255),1, cv2.LINE_AA)


img = np.zeros((512,512,3), np.uint8)
img2 = img.copy()
cv2.namedWindow('Draw')
cv2.setMouseCallback('Draw',draw_shape)


while(True):
    cv2.imshow('Draw',img)
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()