Python实践——简单的机器视觉调试工具

这是一个机器视觉调试程序,它允许您设置一些图像处理参数,如阈值和模糊核大小,并能对选择的图像进行处理和显示处理前后的效果。您还可以保存设置的参数和处理前后的图像。

一、开发环境准备

  1. 安装所需的库
    • 在命令行中使用以下命令安装 tkinteropencv-pythonpillow 库:
      pip install tkinter opencv-python pillow
      

二、代码结构分析

  1. 导入所需的模块

    import tkinter as tk
    import cv2
    from tkinter import filedialog
    from PIL import Image, ImageTk
    
    • tkinter 用于创建图形用户界面。
    • cv2 用于图像处理。
    • filedialog 用于打开文件选择对话框。
    • ImageImageTkpillow 库导入,用于图像格式转换和在 tkinter 中显示图像。
  2. VisionDebugger

    • __init__ 方法:初始化主窗口,创建参数设置的控件和框架,以及图像显示的框架。
    • select_image 方法:处理选择图像的操作,读取图像并进行后续处理。
    • process_image 方法:对图像进行灰度转换、模糊和阈值处理。
    • show_images 方法:使用 pillow 将处理后的图像转换为 tkinter 支持的格式并显示在窗口中。
    • save_parameters 方法:保存设置的参数到文本文件,并保存处理前后的图像。
  3. run 方法

    • 启动主事件循环,使窗口保持可见并响应交互。

三、功能实现步骤

  1. 创建主窗口和参数设置区域

    • 使用 tk.Tk 创建主窗口,并设置标题。
    • 使用 tk.Frame 创建参数设置和图像显示的框架,并使用 pack 方法布局。
  2. 参数设置控件

    • 使用 tk.IntVar 创建整数型变量来关联输入框的值。
    • 创建标签和输入框,并将变量与输入框关联,设置默认值和提示信息。
  3. 选择图像

    • 使用 filedialog.askopenfilename 打开文件选择对话框获取图像路径。
    • 使用 cv2.imread 读取图像,处理读取失败的情况。
  4. 图像处理

    • 根据图像的通道数进行灰度转换。
    • 使用 cv2.GaussianBlur 进行模糊处理。
    • 使用 cv2.threshold 进行阈值处理。
  5. 图像显示

    • 使用 pillowImage.fromarrayopencv 的图像格式转换为 pillow 的格式。
    • 再使用 ImageTk.PhotoImagepillow 格式转换为 tkinter 支持的图像格式。
    • 创建标签并显示图像,同时处理之前显示的图像的清除。
  6. 保存参数和图像

    • 使用 filedialog.asksaveasfilename 获取保存参数的文件路径。
    • 将参数写入文本文件。
    • 使用 cv2.imwrite 保存处理前后的图像。

四、调试与优化

  1. 运行代码,检查是否能正常打开窗口、选择图像、处理和显示图像,以及保存参数和图像。
  2. 检查参数的上下限限制是否生效,输入超出范围的值时是否有正确的提示或处理。
  3. 优化图像显示的性能,例如只在必要时重新加载和显示图像。

五、程序代码

import tkinter as tk
import cv2
from tkinter import filedialog
from PIL import Image, ImageTk

class VisionDebugger:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("机器视觉调试程序")

        # 左侧:参数设置
        self.param_frame = tk.Frame(self.root)
        self.param_frame.pack(side=tk.LEFT, padx=10, pady=10)

        # 调试参数
        self.threshold_value = tk.IntVar(value=128)
        self.blur_kernel_size = tk.IntVar(value=5)

        # 参数设置标签和输入框
        tk.Label(self.param_frame, text="阈值(0 - 255):").pack()
        tk.Entry(self.param_frame, textvariable=self.threshold_value).pack()

        tk.Label(self.param_frame, text="模糊核大小(奇数,3 - 15):").pack()
        tk.Entry(self.param_frame, textvariable=self.blur_kernel_size).pack()

        # 选择图片按钮
        tk.Button(self.param_frame, text="选择图片", command=self.select_image).pack()

        # 保存参数按钮
        tk.Button(self.param_frame, text="保存参数", command=self.save_parameters).pack()

        # 右侧:图像显示
        self.image_frame = tk.Frame(self.root)
        self.image_frame.pack(side=tk.RIGHT, padx=10, pady=10)

    def select_image(self):
        file_path = filedialog.askopenfilename()
        if file_path:
            self.original_image = cv2.imread(file_path, cv2.IMREAD_UNCHANGED)
            if self.original_image is None:
                print("无法读取图像,请检查文件路径是否正确")
                return
            self.process_image()

    def process_image(self):
        # 转换为灰度图像
        if len(self.original_image.shape) == 3:  # 如果是彩色图像
            gray_image = cv2.cvtColor(self.original_image, cv2.COLOR_BGR2GRAY)
        else:  # 如果已经是灰度图像
            gray_image = self.original_image

        # 应用模糊
        blurred_image = cv2.GaussianBlur(gray_image, (self.blur_kernel_size.get(), self.blur_kernel_size.get()), 0)

        # 应用阈值
        _, thresholded_image = cv2.threshold(blurred_image, self.threshold_value.get(), 255, cv2.THRESH_BINARY)

        # 显示图像
        self.show_images(thresholded_image)

    def show_images(self, processed_image):
        # 使用 PIL 转换为 Tkinter 支持的格式
        original_image_pil = Image.fromarray(cv2.cvtColor(self.original_image, cv2.COLOR_BGR2RGB))
        processed_image_pil = Image.fromarray(cv2.cvtColor(processed_image, cv2.COLOR_BGR2RGB))

        original_photo = ImageTk.PhotoImage(original_image_pil)
        processed_photo = ImageTk.PhotoImage(processed_image_pil)

        # 清除之前的图像(如果有)
        for widget in self.image_frame.winfo_children():
            widget.destroy()

        # 显示新的图像
        tk.Label(self.image_frame, image=original_photo, text="原始图像", compound=tk.TOP).pack(side=tk.LEFT)
        tk.Label(self.image_frame, image=processed_photo, text="处理后图像", compound=tk.TOP).pack(side=tk.RIGHT)

        # 保持对图像对象的引用,防止被垃圾回收
        self.original_photo_reference = original_photo
        self.processed_photo_reference = processed_photo

    def save_parameters(self):
        save_path = filedialog.asksaveasfilename(defaultextension=".txt")
        if save_path:
            with open(save_path, 'w') as file:
                file.write(f"Threshold: {self.threshold_value.get()}\n")
                file.write(f"Blur Kernel Size: {self.blur_kernel_size.get()}\n")

            original_save_path = os.path.splitext(save_path)[0] + "_original.jpg"
            processed_save_path = os.path.splitext(save_path)[0] + "_processed.jpg"

            cv2.imwrite(original_save_path, self.original_image)
            cv2.imwrite(processed_save_path, cv2.cvtColor(cv2.imread(processed_save_path), cv2.COLOR_BGR2RGB))

    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    debugger = VisionDebugger()
    debugger.run()

运行界面

  • 24
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

elvis_z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值