Camera_Match


import cv2
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import numpy as np
import datetime

class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Camera_Match")
        self.geometry("800x600")

        # 初始化全局变量
        self.ix, self.iy = -1, -1
        self.roi_set = False
        self.roi = None
        self.drawing = False
        self.template_loaded = False
        self.match_done = False
        self.template = None
        self.method = tk.StringVar(value="cv2.TM_CCOEFF_NORMED")  # 默认匹配方法
        self.results_text = ""
        self.matches = []
        self.match_status = tk.StringVar(value="等待开始")

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

        # 创建主画布
        self.canvas = tk.Canvas(self, width=640, height=480)
        self.canvas.pack(side=tk.TOP, padx=10, pady=10)

        # 创建状态标签
        self.status_label = tk.Label(self, textvariable=self.match_status, font=("Arial", 16), fg="red")
        self.status_label.pack(side=tk.TOP)

        # 创建退出按钮
        self.quit_button = tk.Button(self, text="退出", command=self.quit)
        self.quit_button.pack(side=tk.TOP, padx=10, pady=10)

        # 创建选择框
        self.method_frame = tk.Frame(self)
        self.method_frame.pack(side=tk.TOP, padx=10, pady=10)

        self.method_label = tk.Label(self.method_frame, text="匹配方法:")
        self.method_label.pack(side=tk.LEFT, padx=5)

        methods = [
            ("模板匹配", "cv2.TM_CCOEFF_NORMED"),
            ("矩阵归一化", "cv2.normalize"),
            ("矩阵归一化33", "cv2.normalize"),

            ("寻找最值", "cv2.minMaxLoc")
        ]

        for text, mode in methods:
            b = tk.Radiobutton(self.method_frame, text=text, variable=self.method, value=mode, command=self.select_method)
            b.pack(side=tk.LEFT)

        # 创建用于显示操作记录和匹配结果的区域
        self.results_frame = tk.Frame(self)
        self.results_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=10)

        self.results_label = tk.Label(self.results_frame, text="操作记录与匹配结果:")
        self.results_label.pack(side=tk.TOP, padx=5, pady=5)

        self.results_textbox = tk.Text(self.results_frame, wrap='word', height=10, width=40)
        self.results_textbox.pack(side=tk.TOP, padx=5, pady=5)

        # 绑定鼠标事件
        self.canvas.bind("<ButtonPress-1>", self.on_button_press)
        self.canvas.bind("<B1-Motion>", self.on_mouse_motion)
        self.canvas.bind("<ButtonRelease-1>", self.on_button_release)

        # 启动摄像头读取和显示循环
        self.update_frame()

    def select_method(self):
        self.results_text += f"选择了匹配方法:{self.method.get()}\n"
        self.update_results_text()

    def on_button_press(self, event):
        self.drawing = True
        self.ix, self.iy = event.x, event.y

    def on_mouse_motion(self, event):
        if self.drawing:
            self.canvas.delete("rect")
            self.canvas.create_rectangle(min(self.ix, event.x), min(self.iy, event.y),
                                         max(self.ix, event.x), max(self.iy, event.y),
                                         outline="green", tag="rect")

    def on_button_release(self, event):
        if self.drawing:
            self.drawing = False
            self.canvas.delete("rect")
            self.ix, self.iy = min(self.ix, event.x), min(self.iy, event.y)
            self.roi = self.frame[min(self.iy, event.y):max(self.iy, event.y),
                                  min(self.ix, event.x):max(self.ix, event.x)]
            self.roi_set = True
            self.template = self.roi
            self.results_text += f"选择了区域:({min(self.ix, event.x)}, {min(self.iy, event.y)}) -> ({max(self.ix, event.x)}, {max(self.iy, event.y)})\n"
            self.update_results_text()
            self.match_status.set("匹配中")

    def update_results_text(self):
        self.results_textbox.delete(1.0, tk.END)
        self.results_textbox.insert(tk.END, self.results_text)

    def update_frame(self):
        ret, frame = self.cap.read()
        if ret:
            frame = cv2.flip(frame, 1)  # 镜像翻转图像

            # 确保 frame 是一个有效的 numpy 数组
            self.frame = frame.copy()  # 使用 .copy() 来避免引用问题

            # 如果已经设置了 ROI,则进行模板匹配
            if self.roi_set and self.template is not None and self.template.size > 0:
                method = eval(self.method.get())
                if method == cv2.TM_CCOEFF_NORMED:
                    template = cv2.cvtColor(self.template, cv2.COLOR_BGR2GRAY)
                    w, h = template.shape[::-1]
                    res = cv2.matchTemplate(cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY), template, method)
                    threshold = 0.8
                    loc = np.where(res >= threshold)
                    matches = list(zip(*loc[::-1]))
                    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    self.matches.clear()
                    if len(matches) > 0:
                        for pt in matches:
                            cv2.rectangle(self.frame, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
                            self.results_text += f"{current_time} 匹配位置: {pt}, 匹配度: {res[pt[1], pt[0]]:.2f}\n"
                            self.matches.append(True)
                        self.match_status.set("匹配完成")
                    else:
                        self.match_status.set("匹配失败")
                    self.update_results_text()

            # 将OpenCV BGR格式转换为Tkinter PhotoImage格式
            frame_tk = self.cv_to_tk(self.frame)
            self.canvas.create_image(0, 0, anchor=tk.NW, image=frame_tk)
            self.canvas.image = frame_tk

        # 更新并重复调用
        self.after(30, self.update_frame)

    @staticmethod
    def cv_to_tk(image_cv):
        image_cv_rgb = cv2.cvtColor(image_cv, cv2.COLOR_BGR2RGB)
        image_pil = Image.fromarray(image_cv_rgb)
        return ImageTk.PhotoImage(image_pil)

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

    # 释放资源
    app.cap.release()
 

逐行详细解释: void DstExistenceFusion::UpdateWithoutMeasurement(const std::string &sensor_id, double measurement_timestamp, double target_timestamp, double min_match_dist) { SensorObjectConstPtr camera_object = nullptr; if (common::SensorManager::Instance()->IsCamera(sensor_id)) { camera_object = track_ref_->GetSensorObject(sensor_id); UpdateToicWithoutCameraMeasurement(sensor_id, measurement_timestamp, min_match_dist); } SensorObjectConstPtr lidar_object = track_ref_->GetLatestLidarObject(); SensorObjectConstPtr camera_object_latest = track_ref_->GetLatestCameraObject(); SensorObjectConstPtr radar_object = track_ref_->GetLatestRadarObject(); if ((lidar_object != nullptr && lidar_object->GetSensorId() == sensor_id) || (camera_object_latest != nullptr && camera_object_latest->GetSensorId() == sensor_id) || (radar_object != nullptr && radar_object->GetSensorId() == sensor_id && lidar_object == nullptr && camera_object_latest == nullptr)) { Dst existence_evidence(fused_existence_.Name()); double unexist_factor = GetUnexistReliability(sensor_id); base::ObjectConstPtr obj = track_ref_->GetFusedObject()->GetBaseObject(); double dist_decay = ComputeDistDecay(obj, sensor_id, measurement_timestamp); double obj_unexist_prob = unexist_factor * dist_decay; existence_evidence.SetBba( {{ExistenceDstMaps::NEXIST, obj_unexist_prob}, {ExistenceDstMaps::EXISTUNKNOWN, 1 - obj_unexist_prob}}); // TODO(all) hard code for fused exist bba const double unexist_fused_w = 1.0; double min_match_dist_score = min_match_dist; // if (!sensor_manager->IsCamera(sensor_id)) { // min_match_dist_score = std::max(1 - min_match_dist / // options_.track_object_max_match_distance_, 0.0); // } ADEBUG << " before update exist prob: " << GetExistenceProbability() << " min_match_dist: " << min_match_dist << " min_match_dist_score: " << min_match_dist_score; fused_existence_ = fused_existence_ + existence_evidence * unexist_fused_w * (1 - min_match_dist_score); ADEBUG << " update without, EXIST prob: " << GetExistenceProbability() << " 1 - match_dist_score: " << 1 - min_match_dist_score << " sensor_id: " << sensor_id << " dist_decay: " << dist_decay << " track_id: " << track_ref_->GetTrackId(); } UpdateExistenceState(); }
06-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值