Python:在图像上绘制两个区域

时间:2019-03-04 11:39:20

标签: python python-3.x multithreading opencv

我试图通过单击鼠标事件来绘制两个区域,我考虑使用两个线程和一个锁,这是我的代码:

import numpy as np
import cv2
from threading import Thread, RLock
CANVAS_SIZE = (600,800)
FINAL_LINE_COLOR = (255, 255, 255)
WORKING_LINE_COLOR = (127, 127, 127)
verrou = RLock()
class ZoneDrawer(Thread):
    def __init__(self, window_name):
        Thread.__init__(self)
        self.window_name = window_name 
        self.done = False
        self.current = (0, 0) 
        self.points = [] 

    def on_mouse(self, event, x, y, buttons, user_param):
        if event == cv2.EVENT_MOUSEMOVE:
            self.current = (x, y)
        elif event == cv2.EVENT_LBUTTONDOWN:
            print("Adding point #%d with position(%d,%d)" % (len(self.points), x, y))
            self.points.append((x, y))
        elif event == cv2.EVENT_RBUTTONDOWN:
            self.done = True
    def run(self):
        cv2.namedWindow(self.window_name)
        cv2.imshow(self.window_name, np.zeros(CANVAS_SIZE, np.uint8))
        cv2.waitKey(1)
        cv2.setMouseCallback(self.window_name, self.on_mouse)
        while(not self.done):
            canvas = np.zeros(CANVAS_SIZE, np.uint8)
            with verrou:
                if (len(self.points) > 0):
                    cv2.polylines(canvas, np.array([self.points]), True, FINAL_LINE_COLOR, 1)
                    cv2.line(canvas, self.points[-1], self.current, WORKING_LINE_COLOR)
                cv2.imshow(self.window_name, canvas)
            if cv2.waitKey(50) == 27: 
                self.done = True
    cv2.waitKey()
    cv2.destroyWindow(self.window_name)

thread_1 = ZoneDrawer("zone1")
thread_2 = ZoneDrawer("zone2")
thread_1.start()
thread_2.start()
thread_1.join()
thread_2.join()

但是此代码仍然无法正常工作。有任何帮助或建议吗?

1 个答案:

答案 0 :(得分:1)

以下脚本可用于使用鼠标选择图像区域(如.gif所示)。 gif showing region selection

import cv2, numpy as np

# Mouse callback function
global click_list
positions, click_list, shapes = [(0,0)], [], []
def callback(event, x, y, flags, param):
    positions[-1] = (x,y)
    if event == 1: click_list.append((x,y))
cv2.namedWindow('img')
cv2.setMouseCallback('img', callback)

# Mainloop - show the image and collect the data
while True:
    # Create a blank image
    img = np.zeros((600,600,3), np.uint8)
    # Try to draw the shape being collected
    for idx in range(len(click_list)-1):
        cv2.line(img, click_list[idx], click_list[idx+1], (0,255,0), 5)
    # Draw the stored shapes
    for shape in shapes:
        for idx in range(len(shape)):
            cv2.line(img, shape[idx], shape[idx-1], 255, 5)
    # Show the image
    cv2.imshow('img', img)    
    # Wait, and allow the user to quit with the 'esc' key
    k = cv2.waitKey(1)
    # If user presses 's', go on to the next shape
    if k == 115:
        shapes.append(click_list)
        click_list = []
    # If user presses 'esc' break 
    if k == 27: break
# Clean up
cv2.destroyAllWindows()