【问题标题】:Drag mouse to draw a line and get cordinates of end points of line in opencv Python在opencv Python中拖动鼠标绘制一条线并获取线的端点坐标
【发布时间】:2017-07-11 04:57:21
【问题描述】:

我需要在图像中画一条线,以便我单击 pt1 并拖动到 pt2。所以结果会显示一条线,我也得到了 pt1 和 pt2 的坐标。我目前正在使用两次单独的鼠标单击来绘制一条带有以下代码的线

import numpy as np
import cv2

def get_points(im):
    # Set up data to send to mouse handler
    data = {}
    data['im'] = im.copy()
    data['points'] = []

    # Set the callback function for any mouse event
    cv2.imshow("Image", im)
    cv2.setMouseCallback("Image", mouse_handler, data)
    cv2.waitKey(0)

    # Convert array to np.array
    points = np.vstack(data['points']).astype(float)

    return points

def mouse_handler(event, x, y, flags, data):

    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(data['im'], (x, y), 3, (0, 0, 255), 5, 16);
        cv2.imshow("Image", data['im']);
        if len(data['points']) < 2: # This can be changed for more or less points
            data['points'].append([x, y])


# Running the code
img = cv2.imread('image.jpg', 0)
pts = get_points(img)
cv2.line(img, (pts[0][0], pts[0][1]), (pts[1][0], pts[1][1]), (0,0,0), 2)
cv2.imshow('Image', img)
cv2.waitKey(0)

它有效,但不能解决我的问题。我希望它从 pt1 向下拖动到 pt2 并自己画一条线,而不是我使用点击获得​​点然后画线。因此,例如,左下图是我当前的实现,但我想像右图中那样做

提前感谢您的建议。

【问题讨论】:

    标签: python opencv image-processing mouseevent


    【解决方案1】:

    也可以使用其他事件。

    这是一个快速的肮脏解决方案:

    import numpy as np
    import cv2
    
    btn_down = False
    
    def get_points(im):
        # Set up data to send to mouse handler
        data = {}
        data['im'] = im.copy()
        data['lines'] = []
    
        # Set the callback function for any mouse event
        cv2.imshow("Image", im)
        cv2.setMouseCallback("Image", mouse_handler, data)
        cv2.waitKey(0)
    
        # Convert array to np.array in shape n,2,2
        points = np.uint16(data['lines'])
    
        return points, data['im']
    
    def mouse_handler(event, x, y, flags, data):
        global btn_down
    
        if event == cv2.EVENT_LBUTTONUP and btn_down:
            #if you release the button, finish the line
            btn_down = False
            data['lines'][0].append((x, y)) #append the seconf point
            cv2.circle(data['im'], (x, y), 3, (0, 0, 255),5)
            cv2.line(data['im'], data['lines'][0][0], data['lines'][0][1], (0,0,255), 2)
            cv2.imshow("Image", data['im'])
    
        elif event == cv2.EVENT_MOUSEMOVE and btn_down:
            #thi is just for a ine visualization
            image = data['im'].copy()
            cv2.line(image, data['lines'][0][0], (x, y), (0,0,0), 1)
            cv2.imshow("Image", image)
    
        elif event == cv2.EVENT_LBUTTONDOWN and len(data['lines']) < 2:
            btn_down = True
            data['lines'].insert(0,[(x, y)]) #prepend the point
            cv2.circle(data['im'], (x, y), 3, (0, 0, 255), 5, 16)
            cv2.imshow("Image", data['im'])
    
    
    # Running the code
    img = cv2.imread('C://image.jpg', 1)
    pts, final_image = get_points(img)
    cv2.imshow('Image', final_image)
    print pts
    cv2.waitKey(0)
    

    如果这是您的想法,请告诉我。

    【讨论】:

      猜你喜欢
      • 2012-12-14
      • 2013-02-01
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      相关资源
      最近更新 更多