【问题标题】:Python : Draw two zones on an imagePython:在图像上绘制两个区域
【发布时间】:2019-07-25 17:19:08
【问题描述】:

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

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()

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

【问题讨论】:

  • 欢迎来到 SO! 这段代码仍然无法正常工作是什么意思?您能否详细说明问题/错误并更具体
  • 我只能画一个区域,但我需要画两个区域

标签: python python-3.x multithreading opencv


【解决方案1】:

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

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()

【讨论】:

  • 感谢分享这个脚本,但我需要画不规则的形状
  • @AyoubAlIsmaaili 我修改了代码,以便您可以选择具有任意数量的角的形状。
猜你喜欢
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 2013-06-18
  • 1970-01-01
  • 2017-11-18
相关资源
最近更新 更多