从opencv-python入门opencv--GUI功能之绘图鼠标与图像界面的交互

server/2024/12/22 2:08:59/

opencv-python入门opencv--GUI功能之绘图和鼠标操作

  • 一、文章介绍
  • 二、opencv绘制直线、矩形、圆形
    • 1、cv.line()
    • 2、cv.circle()
    • 3、cv.rectangle()
    • 4、在图像上绘制直线、矩形和圆形
    • 5、cv.ellipse()(在空白画布上绘制椭圆)
      • (1)img = cv.ellipse( img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]] )
      • (2)img = cv.ellipse( img, box, color[, thickness[, lineType]]
    • 6、cv.putText()
  • 三、opencv鼠标回调功能
    • 1、基本用法
    • 3、注册回调函数
    • 4、鼠标事件类型
  • 四、案例:鼠标和键盘配合在图像中绘制图形。
    • 1、代码
    • 2、思路
  • 五、案例:鼠标点击显示图像当前位置的像素和坐标
    • 1、代码
    • 2、思路
  • 六、案例:删除上一次鼠标绘制及一次性清空所有鼠标绘制
    • 1、代码
    • 2、思路

一、文章介绍

1、本文主要介绍opencv的绘图功能以及鼠标与图像界面的交互功能。
2、包含直线、矩形、圆形的绘制。
3、opencv鼠标回调功能介绍。
4、案例:鼠标和键盘配合在图像中绘制图形。
效果展示:
在这里插入图片描述
5、案例:鼠标点击显示图像当前位置的像素和坐标。
效果展示:
在这里插入图片描述

6、案例:删除上一次鼠标绘制及一次性清空所有鼠标绘制。
效果展示:
在这里插入图片描述

opencv_15">二、opencv绘制直线、矩形、圆形

1、cv.line()

在这里插入图片描述
【1】img指要绘制的图形,可以是空白的图像,也可以是读取的图像
【2】pt1和pt2表示要绘制直线的两个端点的坐标,(横坐标,纵坐标)表示
【3】color表示颜色,(B,G,R),如果是灰度图,只需传一个标量值。
【4】thickness: 图形边界的厚度。如果传 -1 就是像圆这样的闭合图形,它将填充形状。 默认 thickness = 1
【5】lineType:线条类型,如 8 连接,抗锯齿线等。默认情况下,它是 8 连接。cv.LINE_AA 画出抗锯齿线,非常好看的曲线。
【6】shift表示坐标单位表示的像素的个数(2^shift),默认是0,坐标1表示1个像素,如果是1,表示1个坐标2两个像素,精度就是0.5。

2、cv.circle()

在这里插入图片描述

3、cv.rectangle()

在这里插入图片描述
pt1和pt2分别表示矩形的左上角和右下角

4、在图像上绘制直线、矩形和圆形

代码:

python">
import cv2 as cv
img = cv.imread('data\gui\starry_night.jpg')
# 画一条 5px 宽的蓝色对角线
cv.line(img,(0,0),(200,300),(0,255,0),5)
cv.rectangle(img,(200,300),(300,500),(255,0,0),3)
cv.circle(img,(300,300), 50, (0,0,255), -1)
cv.imshow('img',img)
k=cv.waitKey(0)
if k == 27: # ESC 退出cv.destroyAllWindows()

效果:

5、cv.ellipse()(在空白画布上绘制椭圆)

在这里插入图片描述
opencv-python中,有两种方式绘制椭圆

(1)img = cv.ellipse( img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]] )

center 是椭圆的中心点,axes 是长轴和短轴的长度,angle 是椭圆的旋转角度,startAngle 和 endAngle 定义了绘制的角度范围。startAngle和endAngle 为0和360时,绘制的才是完整的椭圆。
代码:

python">import cv2 as cv
import numpy as np# 创建一个黑色图像
img = np.zeros((400, 400, 3), dtype=np.uint8)# 定义椭圆的参数
center = (200, 200)  # 中心点
axes = (100, 50)     # 半轴长度 (长轴, 短轴)
angle = 30           # 旋转角度
startAngle = 0       # 起始角度
endAngle = 360       # 结束角度
color = (255, 0, 0)  # 颜色 (B, G, R)
thickness = 2        # 线条厚度# 绘制椭圆
cv.ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness)# 显示图像
cv.imshow("Ellipse Example", img)
cv.waitKey(0)
cv.destroyAllWindows()

效果:
在这里插入图片描述
如果startAngle和endAngle 为0和90:
在这里插入图片描述
表明0度为横坐标方向,顺时针为角度增加。

(2)img = cv.ellipse( img, box, color[, thickness[, lineType]]

使用一个外接矩形的参数 box,box指的是旋转矩形,其中包含中心点的坐标、宽度和高度、旋转角度。
代码:

python">import cv2 as cv
import numpy as np# 创建一个黑色图像
img = np.zeros((400, 400, 3), dtype=np.uint8)# 定义 旋转矩阵RotatedRect 的参数
center = (200, 200)  # 中心点
size = (130, 80)     # (宽度, 高度)
angle = 30           # 旋转角度
# 创建 RotatedRect
rotated_rect = ((center[0], center[1]), (size[0], size[1]), angle)
color = (0, 255, 0)         # 颜色 (B, G, R)
thickness = 2               # 线条厚度# 绘制椭圆
cv.ellipse(img, rotated_rect, color,thickness)# 显示图像
cv.imshow("Ellipse Example", img)
cv.waitKey(0)
cv.destroyAllWindows()

效果:

6、cv.putText()

在这里插入图片描述
【1】img: 要在其上绘制文本的图像。
【2】text: 要绘制的文本字符串。
【3】org: 文本的左下角位置,格式为 (x, y)。
【4】fontFace: 字体类型,可以是以下常量之一:
cv.FONT_HERSHEY_SIMPLEX
cv.FONT_HERSHEY_PLAIN
cv.FONT_HERSHEY_DUPLEX
cv.FONT_HERSHEY_COMPLEX
cv.FONT_HERSHEY_TRIPLEX
cv.FONT_HERSHEY_COMPLEX_SMALL
cv.FONT_HERSHEY_SCRIPT_SIMPLEX
cv.FONT_HERSHEY_SCRIPT_COMPLEX
【5】fontScale: 字体大小的缩放因子。
【6】color: 文本颜色,格式为 (B, G, R)。
【7】thickness: 线条厚度(可选,默认为 1)。
【8】ineType: 线条类型(可选,默认为 LINE_8)。
【9】bottomLeftOrigin: 如果为 true,则文本的原点在左下角(可选,默认为 false)
代码:

python">import cv2 as cv
import numpy as np# 创建一个黑色图像
img = np.zeros((400, 600, 3), dtype=np.uint8)# 定义文本内容和属性
text = "Hello, OpenCV!"
org = (50, 200)  # 文本的左下角位置
fontFace = cv.FONT_HERSHEY_SIMPLEX
fontScale = 1
color = (255, 255, 255)  # 白色
thickness = 2# 在图像上绘制文本
cv.putText(img, text, org, fontFace, fontScale, color, thickness)# 显示图像
cv.imshow("Text Example", img)
cv.waitKey(0)
cv.destroyAllWindows()

效果:
在这里插入图片描述

opencv_164">三、opencv鼠标回调功能

OpenCV 的鼠标回调功能允许用户在图像窗口中处理鼠标事件,例如点击、移动、按下和释放鼠标键。这种功能在图形用户界面(GUI)开发和交互式应用程序中非常有用。

1、基本用法

(1)创建窗口:使用 cv2.namedWindow() 创建一个可用于接收鼠标事件的窗口。

(2)定义鼠标回调函数:创建一个回调函数,处理不同的鼠标事件。在这个函数中,可以获取鼠标的位置、按键状态等信息。

(3)注册回调函数:使用 cv2.setMouseCallback() 将定义的回调函数与窗口绑定。

(4)显示图像并等待事件:使用 cv2.imshow() 显示图像,然后使用 cv2.waitKey() 等待用户输入.

3、注册回调函数

在这里插入图片描述
其中,参数一是需要交互的窗口的名称,参数二是回调函数的名称,参数三是一个指向用户自定义数据的指针,可以用来在回调函数中传递额外的信息,可以将任何类型的数据传递给回调函数,以便在处理鼠标事件时使用,默认为 0(空指针),如果不需要传递额外数据,可以省略或传递 nullptr。

回调函数格式如下:
在这里插入图片描述
(1)event: 鼠标事件类型(如 EVENT_LBUTTONDOWN 表示左键按下)。
(2)x, y: 鼠标事件发生时的坐标。
(3)flags: 一些额外的标志(如 SHIFT、CTRL 键是否按下)。
(4)userdata: 传递给回调函数的用户数据。

4、鼠标事件类型

在 OpenCV 中,有多种鼠标事件可以使用,常用的包括:
cv2.EVENT_LBUTTONDOWN: 左键按下
cv2.EVENT_RBUTTONDOWN: 右键按下
cv2.EVENT_MOUSEMOVE: 鼠标移动
cv2.EVENT_LBUTTONUP: 左键释放
cv2.EVENT_RBUTTONUP: 右键释

四、案例:鼠标和键盘配合在图像中绘制图形。

1、代码

python">
import numpy as np
import cv2 as cv
drawing = False # 如果 True 是鼠标按下
mode = True # 如果 True,画矩形,按下‘m’切换到画圆点
ix,iy = -1,-1
# 鼠标回调函数
def draw_circle(event,x,y,flags,param):global ix,iy,drawing,modeif event == cv.EVENT_LBUTTONDOWN:drawing = Trueix,iy = x,yelif event == cv.EVENT_MOUSEMOVE:if drawing == True:if mode == True:cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)else:cv.circle(img,(x,y),1,(0,0,255),-1)elif event == cv.EVENT_LBUTTONUP:drawing = Falseif mode == True:cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)else:cv.circle(img,(x,y),10,(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)k = cv.waitKey(1) & 0xFFif k == ord('c'):mode = not modeelif k == 27:breakcv.destroyAllWindows()

2、思路

代码中定义drawing变量判断鼠标是否按下。使用mode变量表示键盘’c’键是否按下。
按下鼠标左键,画一个绿色的点,移动鼠标绘制绿色的矩形。
按下‘c’键盘按键后,切换到画圆形。鼠标左键按下,绘制一个半径为5个像素点的圆形,鼠标滑动,连续绘制半径为1个像素点的圆形。

五、案例:鼠标点击显示图像当前位置的像素和坐标

1、代码

python">import numpy as np
import cv2 as cv
drawing = False # 如果 True 是鼠标按下
ix,iy = -1,-1
# 鼠标回调函数
def draw_circle(event,x,y,flags,param):global ix, iy, drawingif event == cv.EVENT_LBUTTONDOWN:drawing = Trueix,iy = x,yelif event == cv.EVENT_LBUTTONUP:if drawing==True:cv.putText(img, f'Coordinates: ({x}, {y})', (x, y), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)cv.putText(img, f'value: ({img[y, x]})', (x, y + 25), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)cv.circle(img, (x, y), 2, (0, 0, 255), -1)drawing = Falseif __name__ == "__main__":img = cv.imread('data\gui\starry_night.jpg')cv.namedWindow('image')cv.setMouseCallback('image', draw_circle)while (1):cv.imshow('image', img)k = cv.waitKey(1) & 0xFFif k == 27:breakcv.destroyAllWindows()

2、思路

使用drawing标识是否绘制,鼠标左键按下时,表示需要绘制,鼠标左键松开时,绘制坐标点和像素点,然后将drawing置为False表示绘制完毕。

六、案例:删除上一次鼠标绘制及一次性清空所有鼠标绘制

1、代码

python">import cv2 as cv
import numpy as np# 读取图像
img = cv.imread('data\gui\starry_night.jpg')
if img is None:print("Error: Could not read the image.")exit()# 保存原始图像
original_img = img.copy()
drawing = False  # 标记是否正在绘制
history = []  # 用于存储历史图像状态def mouse_callback(event, x, y, flags, param):global img, original_img, drawing, historyif event == cv.EVENT_LBUTTONDOWN:  # 左键按下# 保存当前状态到历史记录history.append(img.copy())drawing = Trueelif event == cv.EVENT_LBUTTONUP:  # 左键抬起drawing = Falsecv.circle(img, (x, y), 20, (0, 255, 0), -1)  # 绘制绿色圆形elif event == cv.EVENT_RBUTTONDOWN:  # 右键按下img = original_img.copy()  # 清空图像,恢复为原始图像history.clear()  # 清空历史记录# 创建窗口并设置鼠标回调
cv.namedWindow('image')
cv.setMouseCallback('image', mouse_callback)while True:cv.imshow('image', img)key = cv.waitKey(1) & 0xFFif key == ord('q'):  # 按 'q' 键退出breakelif key == ord('u'):  # 按 'u' 键撤销上一步if history:img = history.pop()  # 撤销上一步cv.destroyAllWindows()

2、思路

将原始图像拷贝备份。每次绘制之前,将当前图片保存,如果按下’u’,则删除一张图像,如果右键按下,显示原始图像。


http://www.ppmy.cn/server/132209.html

相关文章

用AI做期货量化交易应该怎么做

用AI做期货量化交易主要分为几个步骤,包括数据收集、数据处理、特征工程、模型选择与训练、策略回测以及实盘交易。以下是一个更详细的过程说明: 1. 数据收集 量化交易首先需要大量的市场数据,这些数据包括: 历史期货价格数据&…

Linux nohup 命令详解

文章目录 Linux nohup 命令详解基本语法nohup 工作原理实用示例示例 1:运行一个脚本并保持后台执行示例 2:指定输出文件示例 3:结合 sleep 命令 使用 jobs 和 bg 管理后台进程使用 ps 和 kill 管理进程常见的 nohup 参数结合 nohup 和 cron注…

反走样算法(MSAA、TAA、FXAA、DLSS)

光栅化的采样过程会导致图形走样,走样有很多种形式: 锯齿 摩尔纹 走样的本质原因是采样速度跟不上信号变化的速度 采样频率低,使得我们将连续变化的信号离散化. 反走样方法 anti-alisaing MSAA 多重采样反走样 超采样 优点: 对几何反走样效果良好 缺点…

p20 docker自己commit一个镜像 p21 容器数据卷 p22mysql同步数据(国内镜像被封锁暂时往后放)p23具名挂载和匿名挂载

如何自己commit一个镜像 这里还是先引用一下老师的笔记 关于如何自己commit一个镜像这个问题目前因为从仓库中拉下来的Tomcat里面是没有项目的,所以把webapps.dist里面的拷贝到webapps里面去作为自己的镜像在commit一下 这里用Tomcat举例子首先把镜像拉取下来执…

HTML 常用的块级元素和行内元素

1. 常用的块级元素 块级元素具有如下特点: 占据父容器的整行宽度。通常从新的一行开始。可以包含其他块级元素和行内元素。 常用的块级元素: div:通用的容器,用于布局和分块内容。 h1 到 h6:标题标签,定义…

Cesium如果链接着色器的?

Cesium的着色器是一个很庞大的技术体系,我们使用起来相对还是比较容易的。Cesium内置了很多以CZM_开头的函数和Uniform。这些着色器是如何关联,又是如何调用的呢? 为了方便表示,我们可以做一个想象。一堆货物需要经过码头&#x…

【Vue】鼠标滚轮横向滚动操作设计

需求&#xff1a; 鼠标滑轮滚动&#xff0c;操作横向滚动条 解决&#xff1a; 监控滚动操作&#xff0c;根据滚动偏移量&#xff0c;修改横向滚动条的位置 <template><div class"image_view"><div class"image_content"><divv-fo…

OpenUAV:首个专为现实无人机视觉语言导航设计的大规模轨迹数据集,由大约 12k 个轨迹组成,涵盖了多种环境和复杂的飞行动态。

2024-10-10&#xff0c;由北京航空航天大学人工智能研究所、香港中文大学MMLab以及感知与交互智能中心共同创建了OpenUAV数据集&#xff0c;首个专为现实无人机&#xff08;UAV&#xff09;视觉语言导航&#xff08;VLN&#xff09;任务设计的大型轨迹数据集&#xff0c;该数据…