【Obj_Detection_Edges】

import tkinter as tk
from tkinter import font, filedialog
from PIL import Image, ImageTk
import cv2
import numpy as np
import time

class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Obj_Detection")
        self.geometry('1200x600')

        # 字体设置
        self.font = font.Font(family='SimSun', size=28)
        self.font2 = font.Font(family='SimSun', size=18)

        # 创建三个框架
        self.left_frame = tk.Frame(self, width=640, height=600)
        self.center_frame = tk.Frame(self, width=266, height=600)
        self.right_frame = tk.Frame(self, width=266, height=600)

        self.left_frame.grid(row=0, column=0, padx=1, pady=1)
        self.center_frame.grid(row=0, column=1, padx=1, pady=1)
        self.right_frame.grid(row=0, column=2, padx=1, pady=1)

        # 左侧实时画面标签
        self.label_left = tk.Label(self.left_frame, text="实时画面", font=self.font)
        self.label_left.pack(pady=(10, 0))

        # 实时显示检测结果
        self.label2_left = tk.Label(self.left_frame, text="准备开始检测", font=self.font2)
        self.label2_left.pack(pady=(10, 0))

        # 中间目标图案标签
        self.label_center_top = tk.Label(self.center_frame, text="目标图案", font=self.font)
        self.label_center_top.pack(pady=(10, 0))

        # 右侧Log标签
        self.label_right_top = tk.Label(self.right_frame, text="Log 记录", font=self.font)
        self.label_right_top.pack(pady=(10, 0))

        self.log_text = tk.Text(self.right_frame, height=20, width=30)
        self.log_text.pack(pady=(10, 0))
        self.log("系统初始化完成")

        # 按钮用于截图
        self.button_capture = tk.Button(self.center_frame, text="截图后开启检测", command=self.start_capture)
        self.button_capture.pack(pady=(10, 0))

        # 设置相似度阈值
        self.threshold_label = tk.Label(self.center_frame, text="边缘检测阈值:")
        self.threshold_label.pack(pady=(10, 0))
        self.threshold_slider = tk.Scale(self.center_frame, from_=0, to=255, resolution=1, orient=tk.HORIZONTAL)
        self.threshold_slider.set(100)
        self.threshold_slider.pack(pady=(0, 10))

        # 中间下方的标签用于显示缩略图
        self.label_center_bottom = tk.Label(self.center_frame, text="缩略图")
        self.label_center_bottom.pack(pady=(10, 0))

        # 用于显示图像的Canvas
        self.canvas_left = tk.Canvas(self.left_frame, width=640, height=480)
        self.canvas_left.pack(pady=(10, 0))

        # 图像存储
        self.image_to_compare = None
        self.target_region = None
        self.selection_start = None
        self.selection_end = None

        # 开启摄像头
        self.cap = cv2.VideoCapture(0)
        self.update_frame()

    def update_frame(self):
        ret, frame = self.cap.read()
        if ret:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            img = Image.fromarray(frame)
            img_tk = ImageTk.PhotoImage(image=img)
            self.canvas_left.create_image(0, 0, anchor=tk.NW, image=img_tk)
            self.canvas_left.img = img_tk

            # 如果有目标区域,则进行边缘检测并框选
            if self.target_region is not None:
                edges = self.detect_edges(frame)
                self.display_results(frame, edges)
            
        self.after(15, self.update_frame)

    def start_capture(self):
        ret, frame = self.cap.read()
        if ret:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            self.image_to_compare = Image.fromarray(frame)
            self.image_to_compare.thumbnail((640, 480))
            img_tk = ImageTk.PhotoImage(self.image_to_compare)
            self.label_center_bottom.config(image=img_tk)
            self.label_center_bottom.img = img_tk
            self.log("截图成功")
            self.canvas_left.bind("<Button-1>", self.on_click)
            self.canvas_left.bind("<B1-Motion>", self.on_drag)
            self.canvas_left.bind("<ButtonRelease-1>", self.on_release)

    def on_click(self, event):
        self.selection_start = (event.x, event.y)

    def on_drag(self, event):
        if self.selection_start:
            self.canvas_left.delete("selection_rect")
            self.canvas_left.create_rectangle(
                self.selection_start[0], self.selection_start[1],
                event.x, event.y,
                outline="blue", tags="selection_rect"
            )

    def on_release(self, event):
        if self.selection_start and event.x != self.selection_start[0] and event.y != self.selection_start[1]:
            self.target_region = (min(event.x, self.selection_start[0]), min(event.y, self.selection_start[1]),
                                  abs(event.x - self.selection_start[0]), abs(event.y - self.selection_start[1]))
            self.canvas_left.delete("selection_rect")
            self.canvas_left.create_rectangle(
                self.target_region[0], self.target_region[1],
                self.target_region[0] + self.target_region[2], self.target_region[1] + self.target_region[3],
                outline="blue", tags="selection_rect"
            )
            self.log("目标区域选定")

    def detect_edges(self, frame):
        # 截取目标区域
        if self.target_region:
            target_region = frame[
                self.target_region[1]:self.target_region[1] + self.target_region[3],
                self.target_region[0]:self.target_region[0] + self.target_region[2]
            ]
            # 将图像转换为灰度图像
            gray = cv2.cvtColor(target_region, cv2.COLOR_RGB2GRAY)
            # 使用Canny算法检测边缘
            low_threshold = self.threshold_slider.get()
            high_threshold = low_threshold * 3  # Canny通常建议高阈值是低阈值的两到三倍
            edges = cv2.Canny(gray, low_threshold, high_threshold)
            # 将边缘图像转换回PIL格式以便在GUI中显示
            edges_img = Image.fromarray(edges)
            return edges_img

    def display_results(self, frame, edges_img):
        if self.target_region and edges_img:
            # 在实时画面上框选目标区域
            cv2.rectangle(frame, (self.target_region[0], self.target_region[1]),
                          (self.target_region[0] + self.target_region[2], self.target_region[1] + self.target_region[3]),
                          (255, 0, 0), 2)
            # 在目标区域内绘制边缘
            edges_array = np.array(edges_img)
            edges_array = cv2.cvtColor(edges_array, cv2.COLOR_GRAY2RGB)
            frame[self.target_region[1]:self.target_region[1] + self.target_region[3],
                  self.target_region[0]:self.target_region[0] + self.target_region[2]] = edges_array
            
            img = Image.fromarray(frame)
            img_tk = ImageTk.PhotoImage(image=img)
            self.canvas_left.create_image(0, 0, anchor=tk.NW, image=img_tk)
            self.canvas_left.img = img_tk

    def log(self, message):
        current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
        self.log_text.insert(tk.END, f"{current_time}: {message}\n")
        self.log_text.see(tk.END)

if __name__ == "__main__":
    app = Application()
    app.mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值