图像入门3

图像识别3

0. 序章

​ 从本章起,我们的OpenCV将会插入一段美好而虚空的幻想故事……请各位勇士进入幻境,开始你们的学习之旅。

1. 大纲

1、处理OpenCV中鼠标事件

2、学习以鼠标作为画笔,如cv.setMouseCallback()函数

2. 使用鼠标作为画笔

1)鼠标回调函数

​ 在遥远的圣彼得堡,住着一位美丽动人的公主——Libeaka,许多勇士都慕名而来,想要求娶这位美丽的公主,但是这位公主非常喜欢OpenCV,她希望嫁给一位精通OpenCV的勇士。面对这crush,你暗自下定决心,要学好OpenCV……

​ 公主的第一个心结是要求各位勇士用鼠标作为画笔绘制出一个填充的矩形……愚蠢的你不知道该从何下手,于是你求助到了正在学OpenCV的我,我看在你情真意切,决定告诉你怎么做。

​ 我们想要创建一个简单的应用程序,使得无论我们在屏幕上哪里双击一下,屏幕上都会绘制出一个圆形。我们需要创建一个鼠标回调函数,该函数在发生鼠标事件时执行。鼠标事件可以是与鼠标相关的任何事务,例如鼠标键按下,并返回点击位置的x,y值。

# 鼠标回调函数
def draw_circle(event, x, y, flags, param):
    双击后在双击位置绘制圆形
    if event == cv.EVENT_LBUTTONDBLCLK:
        cv.circle(img, (x, y), 100, (56, 212, 136), -1)


​ 然而,我们的目标似乎更加远大,不止满足于此,这会让你在公主面前疯狂加分。我们希望我们能够通过拖动鼠标来绘制矩形或者圆形,所以我们应该监控鼠标upDOWNMOVE三种状态,这些可以用于目标跟踪,图像分割地图等方面。

# 鼠标回调函数
def draw_circle(event, x, y, flags, param):
    global ix, iy, drawing, mode
    if event == cv.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    elif event == cv.EVENT_MOUSEMOVE:
        if drawing:
            if mode:
                cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1, lineType=cv.LINE_AA)
            else:
                cv.circle(img, (x, y), 5, (0, 0, 255), -1)
    elif event == cv.EVENT_LBUTTONUP:
        drawing = False
        if mode:
            cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 3)
        else:
            cv.circle(img, (x, y), 5, (0, 0, 255), -1)


​ 贪心的Libeaka公主显然不止满足于此,她想要用鼠标绘制出未填充的矩形。即使是我,我也需要想想再告诉你,那么,聪明的勇士,你能自己想出来这个问题的答案嘛?(答案见完整代码部分)

3. 附完整代码

​ 用鼠标移动绘制填充矩形,完整代码如下:

import cv2 as cv
import numpy as np

drawing = False     # 如果按下鼠标,则为真
mode = True     # 如果为真,绘制矩形。按M键可以切换到曲线
ix, iy = -1, -1


# 鼠标回调函数
def draw_circle(event, x, y, flags, param):
    """
    双击后在双击位置绘制圆形
    if event == cv.EVENT_LBUTTONDBLCLK:
        cv.circle(img, (x, y), 100, (56, 212, 136), -1)
    """
    global ix, iy, drawing, mode
    if event == cv.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    elif event == cv.EVENT_MOUSEMOVE:
        if drawing:
            if mode:
                cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1, lineType=cv.LINE_AA)
            else:
                cv.circle(img, (x, y), 5, (0, 0, 255), -1)
    elif event == cv.EVENT_LBUTTONUP:
        drawing = False
        if mode:
            cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 3)
        else:
            cv.circle(img, (x, y), 5, (0, 0, 255), -1)


if __name__ == "__main__":
    # 创建一个黑色的图像,一个窗口,并绑定到窗口功能
    img = np.zeros((512, 512, 3), np.uint8)
    cv.namedWindow('image')
    # 回调
    cv.setMouseCallback('image', draw_circle)
    while(1):
        cv.imshow('image', img)
        # 按ESC窗口被强制关闭
        if cv.waitKey(20) & 0xFF == 27:
            break
    cv.destroyAllWindows()

​ 用鼠标移动绘制未填充矩形,完整代码如下:

import cv2 as cv
import numpy as np

drawing = False     # 如果按下鼠标,则为真
mode = True     # 如果为真,绘制矩形。按M键可以切换到曲线
ix, iy = -1, -1


# 鼠标回调函数
def draw_circle(event, x, y, flags, param):
    """
    双击后在双击位置绘制圆形
    if event == cv.EVENT_LBUTTONDBLCLK:
        cv.circle(img, (x, y), 100, (56, 212, 136), -1)
    """
    global ix, iy, drawing, mode
    if event == cv.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    elif event == cv.EVENT_MOUSEMOVE:
        if drawing:
            if mode:
                cv.rectangle(img, (0, 0), (640, 480), (0, 0, 0), -1)
                cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1, lineType=cv.LINE_AA)
            else:
                cv.circle(img, (x, y), 5, (0, 0, 255), -1)
    elif event == cv.EVENT_LBUTTONUP:
        drawing = False
        if mode:
            cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 1)
        else:
            cv.circle(img, (x, y), 5, (0, 0, 255), -1)


if __name__ == "__main__":
    # 创建一个黑色的图像,一个窗口,并绑定到窗口功能
    img = np.zeros((512, 512, 3), np.uint8)
    cv.namedWindow('image')
    # 回调
    cv.setMouseCallback('image', draw_circle)
    while True:
        cv.imshow('image', img)
        # 按ESC窗口被强制关闭
        if cv.waitKey(20) & 0xFF == 27:
            break
    cv.destroyAllWindows()

posted @   叽叽cccc  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示