基于Tkinter和OpenCV的图像处理系统
功能介绍
一个简单的数字图像处理系统,采用图形用户界面(GUI),实现常用图像处理功能、交互操作功能、画图等功能。
-
图像处理功能:
(1) 点运算:二值化(自适应阈值)。
(2) 几何变换:旋转、放大、缩小、裁剪
(3) 滤波:均值、高斯、中值
(4) 边缘检测:Canny 算法、外轮廓检测、填充轮廓
(5) 直方图均衡化:局部、全局、限制对比度自适应
(6) 形态学操作:开、闭、膨胀、腐蚀
(7) 水印:水印内容通过对话框输入(文字)
-
GUI 功能:
(1) 有菜单、工具栏、状态栏:在菜单栏中要有所有操作,工具栏上有常用操作的按钮。
(2) 在软件界面上显示图像,软件标题栏显示软件名称、作者信息和所打开的文件名。
(3) 图像处理时所需的参数用对话框来输入或者通过主界面上的控件来输入参数或者用鼠标交互操作来完成。
(4) 每次处理之后,能在界面上显示当前处理结果;下次处理是对前面处理结果继续处理,而不是仍然对原图进行处理。
(5) 每次图像处理操作,都能撤销。
-
交互功能:
(1) 鼠标在图片上时,在状态栏实时显示鼠标在图像中的位置,及该位置的颜色
(2) 用鼠标滚轮进行图片的放大缩小
(3) 当图片放大后,大于界面显示区域时,能够用鼠标进行平移操作
-
文件操作功能:
(1) 能用对话框选择图像文件(要用文件扩展名过滤)。
(2) 能保存当前处理结果图,并用对话框选择图片保存路径和文件名。
(3) 新建图像。
-
画图功能:
(1) 用鼠标在图像上画图形:矩形、圆、任意多边形
(2) 在图像上写字,位置由鼠标指定
上手指南
安装步骤
要在Windows上运行这个程序,您需要安装以下依赖库:
- OpenCV:用于图像处理功能
- Tkinter:用于构建图形用户界面
- PIL (Python Imaging Library) 或 Pillow:用于图像格式转换(例如从OpenCV的格式转换为Tkinter支持的格式)
以下是在Windows上安装所需库的步骤:
-
确保已经安装了Python。如果没有,请访问Python官网下载并安装。
-
安装OpenCV库。打开命令提示符或PowerShell并输入以下命令:
pip install opencv-python
-
默认情况下,Python 3.x版本应该已经包含了Tkinter库。如果遇到问题,可以尝试使用以下命令进行安装:
pip install tk
-
安装Pillow库(Python Imaging Library 的更先进分支)。在命令提示符或PowerShell中输入以下命令:
pip install pillow
安装完成后,您可以运行代码。在命令提示符或PowerShell中切换到该文件所在的目录,并输入以下命令:
python .\gui.py
代码逻辑
-
导入所需库和模块:导入了OpenCV(cv2),os,tkinter,PIL等库以及自定义的图像处理模块(image_processing)。
-
定义全局变量:创建一系列全局变量,如image_path、image、processed_image、temp_image、history、history_index等,用于在整个程序中跟踪和控制图像状态。
-
文件操作函数:
- 打开图像:show_image()
- 根据传入的图像,在画布上显示图像,并为鼠标事件(移动、滚轮滚动和拖拽)绑定相应的处理函数。
- 选择图像:select_image()
- 打开文件对话框,让用户选择图像文件,然后读取并显示图像,同时更新窗口标题栏并清空历史记录。
- 撤销与重做:undo() redo()
- 分别进行撤销和重做操作,通过调整history_index来回退或前进到不同的图像状态。
- 新建:new_image_question() new_image()
- 先询问用户是否需要保存当前图片,然后新建空白图像(white.jpg)并清空历史记录。
- 另存为:save_image()
- 打开文件对话框,让用户选择保存路径,将处理后的图像保存到指定路径。
- 打开图像:show_image()
-
创建主窗口和菜单栏:使用Tkinter创建程序的主窗口(root)以及菜单栏(menubar),并向菜单栏中添加“文件”、“编辑”、“图像处理”、“画图功能”等菜单项及其子菜单。
-
图像处理功能函数:实现了各种图像处理功能的调用,包括:
- 点运算(二值化):threshold()
- 将图像转换为灰度图像,然后使用自适应阈值二值化方法进行处理。最终返回二值化后的图像。
- 几何运算(旋转):rotate(),
- 以指定的角度旋转图像。计算旋转矩阵并将其应用于输入图像。
- 几何运算(裁剪):crop()
- 裁剪图像。通过鼠标交互式地选择裁剪区域,并在按下ESC或Q键时返回裁剪后的图像。
- 滤波(均值滤波):mean_filter()
- 使用3x3的核进行均值滤波。
- 滤波(高斯滤波):gaussian_filter(),
- 使用3x3的高斯核进行高斯滤波。
- 滤波(中值滤波):median_filter()
- 使用3x3的大小进行中值滤波。
- 边缘检测(Canny算法):canny()
- 首先将图像转换为灰度图像,然后使用Canny算法进行边缘检测。
- 边缘检测(外轮廓检测):contour_detection()
- 在原图像上绘制外轮廓。
- 边缘检测(填充检测):fill_contour()
- 填充图像中的轮廓。
- 直方图均衡化(全局直方图均衡化):global_histogram_equalization()
- 对灰度图像应用全局直方图均衡化。
- 直方图均衡化(局部直方图均衡化):local_histogram_equalization()
- 对灰度图像应用局部直方图均衡化。
- 直方图均衡化(自适应直方图均衡化):contrast_limited_adaptive_histogram_equalization()
- 将图像转换为Lab色彩空间,然后对L通道进行限制对比度自适应直方图均衡化。最后将图像转换回BGR色彩空间。
- 形态学操作(开运算):opening_operation()
- 使用5x5的结构元素进行开运算。
- 形态学操作(闭运算):closing_operation()
- 使用5x5的结构元素进行闭运算。
- 形态学操作(膨胀操作):dilation()
- 使用3x3的结构元素对图像进行膨胀操作。
- 形态学操作(腐蚀操作):erosion()
- 使用3x3的结构元素对图像进行腐蚀操作。
- 添加水印:watermark()
- 获取用户输入的水印文字。
- 生成一个与输入图像大小相同的全白图像(img_wm)。
- 将输入的水印文字绘制在img_wm上。
- 计算水印图像(img_wm)在原图像中的位置(x, y)。
- 调整水印图像尺寸并将其添加到原始图像上。
- 返回添加水印后的图像。
- 点运算(二值化):threshold()
-
画图功能函数:
- 画笔:pencil()
- 定义全局变量drawing、ix和iy用来确定鼠标左键是否被按下以及存储绘图的起始坐标。
- pencil_mouse_callback(event, x, y, flags, param)鼠标回调函数:
- 当检测到鼠标左键按下事件时,设置drawing为True并更新起始坐标ix和iy。
- 如果drawing为True且鼠标正在移动,则在输入图像param上绘制从(ix, iy)到(x, y)的直线,并不断更新ix和iy。
- 鼠标左键弹起时,drawing设为False并绘制最后一条直线。
- 在pencil_algorithm()函数中,创建一个窗口并将鼠标回调函数与之绑定。
- 循环显示图像,直到用户按ESC键或Q键退出循环。
- 关闭窗口并返回添加了画笔轨迹的图像。
- 绘制矩形:rectangle()
- 使用类似于画笔的方法编写rectangle_mouse_callback()鼠标回调函数,唯一的区别在于当鼠标左键按下时,仅更新起始坐标,而不进行绘制;当鼠标移动时,若drawing为True,则在临时图像temp_image(param的副本)上绘制矩形并实时显示;鼠标左键弹起时,在原始图像param上绘制最终的矩形。
- 在rectangle_algorithm()函数中,创建一个窗口并将鼠标回调函数与之绑定,循环显示图像并等待用户按下ESC键或Q键退出循环,然后返回绘制了矩形的图像。
- 绘制圆形:circle()
- 实现逻辑与绘制矩形类似。在circle_mouse_callback()鼠标回调函数中,在临时图像temp_image上根据鼠标移动实时绘制圆形;鼠标左键弹起时,在输入图像param(原始图像)上绘制最终的圆形。
- circle_algorithm()函数负责创建窗口、绑定回调函数和进行循环显示,最终返回绘制了圆形的图像。
- 绘制多边形(直线拼接):polygon()
- 实现逻辑与画笔功能类似。polyline_mouse_callback()鼠标回调函数在鼠标移动过程中连续绘制直线;鼠标左键弹起时,将当前直线绘制到输入图像param上。
- line_algorithm()函数负责创建窗口、绑定回调函数和进行循环显示,最终返回添加了多边形轨迹的图像。
- 画笔:pencil()
-
交互功能函数:
鼠标事件(如移动、滚轮滚动和拖拽)已经绑定到画布
temp_image
上。事件触发时会自动调用对应的函数。- 鼠标移动:on_mouse_move()
- 当鼠标在画布上移动时,此函数更新状态栏以显示当前图像的鼠标位置、颜色信息和缩放比例。在函数内部,通过
event.x
和event.y
获取鼠标坐标,并使用processed_image[y, x]
获取对应点的颜色值。
- 当鼠标在画布上移动时,此函数更新状态栏以显示当前图像的鼠标位置、颜色信息和缩放比例。在函数内部,通过
- 滚轮滚动:on_scroll()
- 此函数实现图像缩放功能。首先,判断滚轮的滚动方向:如果
event.delta > 0
,则为缩小;否则为放大。接着,计算缩放因子scale_factor = 1 - delta * 0.1
,并将其作用于zoom_ratio
全局变量。然后,根据新的尺寸(new_h
,new_w
)使用cv2.resize()函数调整processed_image
大小。最后,调用show_image()
函数显示缩放后的图像。
- 此函数实现图像缩放功能。首先,判断滚轮的滚动方向:如果
- 拖拽:on_drag()
- 当用户按住鼠标左键在画布上拖动时,此函数使画布的显示区域跟随鼠标移动。通过调用
temp_image.scan_dragto(event.x, event.y, gain=1)
,实现画布显示区域的移动,其中gain
控制拖动速度。
- 当用户按住鼠标左键在画布上拖动时,此函数使画布的显示区域跟随鼠标移动。通过调用
- 鼠标移动:on_mouse_move()
-
主窗口布局设置:调整主窗口的大小、位置以及状态栏,使其位于屏幕中央,并创建状态栏用于显示鼠标位置和缩放比例等信息。
-
运行主循环:使用root.mainloop()运行Tkinter主循环,使程序能够持续运行并响应用户操作。在程序执行过程中,用户可以交互式地操作图像、应用处理功能并查看结果。
通过这个图像处理系统,用户可以方便地对图像进行各种处理操作,实现所需的图像效果。同时,系统还具有与用户交互的功能,使得操作更加直观和便捷。
如需代码,请私信联系