opencv(py) setMouseCallback 用鼠标在图像上画出矩形框(动态)

985 阅读3分钟
  •        Python : 3.8.11
  • opencv-python : 4.1.2.30
  • opencv-contrib-python : 4.1.2.30
  •          OS : Ubuntu Kylin 20.04
  •       Conda : 4.10.1
  •     Pycharm : 2021.1.3

代码示例

import cv2
import numpy as np


def draw_circle(event, x, y, flags, param):
    global flag_mouse_lbutton_down, point_x, point_y, image

    # 鼠标左键按下
    if event == cv2.EVENT_LBUTTONDOWN:
        print("EVENT_LBUTTONDOWN", event, x, y, flags, param)
        flag_mouse_lbutton_down = True
        point_x = x
        point_y = y
        cv2.circle(image, (x, y), 1, (0, 0, 255), thickness=2)

    if event == cv2.EVENT_LBUTTONUP:
        print("EVENT_LBUTTONUP", event, x, y, flags, param)
        flag_mouse_lbutton_down = False
        cv2.rectangle(image, (point_x, point_y), (x, y), (0, 0, 255), 2)

    if event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
        print("EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON", event, x, y, flags, param)
        # 这样写是错误的
        # image和temp_image指向了同一个数据,可以用id函数进行检测
        # image = temp_image

        image[:] = temp_image
        print(id(image))
        print(id(temp_image))
        cv2.rectangle(image, (point_x, point_y), (x, y), (0, 0, 255), 2)

# 检测鼠标左键是否按下的flag
flag_mouse_lbutton_down = False
# 矩形的点
point_x = -1
point_y = -1

image_path = "opencv-image.png"
image = cv2.imread(image_path)
# 注意numpy的深拷贝
temp_image = image.copy()

cv2.namedWindow("image")
cv2.setMouseCallback("image", draw_circle)

while True:
    cv2.imshow("image", image)
    # waitKey 不能为0,必须有值,才可以刷新image
    # 鼠标点×是关不掉的,只能键盘输入q
    if cv2.waitKey(10) == ord("q"):
        break

cv2.destroyAllWindows()

运行结果

cv-mouse-click-rectangle-dynamic-1.png

/home/coder/anaconda3/bin/python3.8 /home/coder/PycharmProjects/pythonProject2/main.py
EVENT_LBUTTONDOWN 1 94 74 1 None
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 105 90 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 109 97 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 114 105 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 121 119 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 130 131 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 155 162 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 168 179 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 191 207 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 205 224 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 218 240 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 235 260 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 248 271 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 251 274 1 None
140072728071696
140072281407376
EVENT_MOUSEMOVE+EVENT_FLAG_LBUTTON 0 252 274 1 None
140072728071696
140072281407376
EVENT_LBUTTONUP 4 252 274 1 None

Process finished with exit code 0

学习推荐


Python具有开源、跨平台、解释型、交互式等特性,值得学习。
Python的设计哲学:优雅,明确,简单。提倡用一种方法,最好是只有一种方法来做一件事。
代码的书写要遵守规范,这样有助于沟通和理解。
每种语言都有独特的思想,初学者需要转变思维、踏实践行、坚持积累。