diff --git a/Python程序设计课程设计报告模板 2024年.doc b/Python程序设计课程设计报告模板 2024年.doc index 743f27e..7565f1e 100644 Binary files a/Python程序设计课程设计报告模板 2024年.doc and b/Python程序设计课程设计报告模板 2024年.doc differ diff --git a/图片/功能模块.jpg b/图片/功能模块.jpg new file mode 100644 index 0000000..4c27433 Binary files /dev/null and b/图片/功能模块.jpg differ diff --git a/图片/功能模块.png b/图片/功能模块.png deleted file mode 100644 index a33f704..0000000 Binary files a/图片/功能模块.png and /dev/null differ diff --git a/工程/Area_tracking.py b/工程/Area_tracking.py index af9d5fb..9ced093 100644 --- a/工程/Area_tracking.py +++ b/工程/Area_tracking.py @@ -1,7 +1,23 @@ import cv2 import numpy as np +kf = cv2.KalmanFilter(4, 2) +kf.measurementMatrix = np.array([[1, 0, 0, 0], + [0, 1, 0, 0]], np.float32) +kf.transitionMatrix = np.array([[1, 0, 1, 0], + [0, 1, 0, 1], + [0, 0, 1, 0], + [0, 0, 0, 1]], np.float32) +kf.processNoiseCov = np.array([[1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1]], np.float32) * 0.03 + +# 用于初始化卡尔曼滤波器的变量 +initial_measurement = None + def main(): + global initial_measurement, kf # 初始化摄像头 cap = cv2.VideoCapture(0) @@ -31,8 +47,6 @@ def main(): color_mean = np.mean(roi_hsv, axis=(0, 1)) color_mean = np.uint8(color_mean) - # 创建颜色范围 - # color_range = 10 color_lower = np.array( [max(color_mean[0] - 30, 0), max(color_mean[1] - 60, 0), max(color_mean[2] - 55, 0)]) color_upper = np.array( @@ -65,7 +79,19 @@ def main(): if cv2.contourArea(contour) > 300: x, y, w, h = cv2.boundingRect(contour) cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) - print(color_lower, color_upper) + + # 初始化卡尔曼滤波器的测量值 + if initial_measurement is None: + initial_measurement = np.array([[x], [y]], np.float32) + kf.statePost = initial_measurement + else: + # 更新卡尔曼滤波器 + measurement = np.array([[x], [y]], np.float32) + kf.correct(measurement) + prediction = kf.predict() + cv2.rectangle(frame, (int(prediction[0]), int(prediction[1])), + (int(prediction[0] + w), int(prediction[1] + h)), + (255, 0, 0), 2) # 显示原图和结果图像 cv2.imshow('Original', frame) @@ -80,5 +106,4 @@ def main(): cv2.destroyAllWindows() if __name__ == '__main__': - main() - + main() \ No newline at end of file diff --git a/工程/Color_tracking.py b/工程/Color_tracking.py index 88b4b36..20c10f0 100644 --- a/工程/Color_tracking.py +++ b/工程/Color_tracking.py @@ -27,6 +27,7 @@ running = False kf = None cap = None root = None +stop_thread = False def initialize_kalman_filter(): """初始化卡尔曼滤波器""" global kf @@ -45,8 +46,8 @@ def initialize_kalman_filter(): # 用于初始化卡尔曼滤波器的变量 initial_measurement = None +#初始化摄像头 def initialize_camera(): - """初始化摄像头""" global cap cap = cv2.VideoCapture(0) @@ -54,19 +55,34 @@ def choose_color(): global selected_color # 显示颜色选择对话框 color_options = list(color_hsv_ranges.keys()) - selected_color = simpledialog.askstring("Choose Color", "Enter the color (blue, green, red, custom):", + selected_color = simpledialog.askstring("选择颜色", "输入颜色 (blue, green, red, custom):", initialvalue=selected_color, parent=root) # 检查颜色选择是否有效,更新阈值 if selected_color in color_options: update_color_threshold(selected_color) else: - messagebox.showerror("Error", "Invalid color selection.") + messagebox.showerror("错误", "颜色选择无效") + +def rgb_to_hsv(rgba): + """将RGB颜色转换为HSV颜色""" + rgb = rgba[:3] # 忽略alpha通道 + hsv = cv2.cvtColor(np.uint8([[rgb]]), cv2.COLOR_RGB2HSV)[0][0] + return hsv def choose_custom_color(): - color_code = colorchooser.askcolor(title="Choose Custom Color") + color_code = colorchooser.askcolor(title="选择自定义颜色") if color_code[0] is not None: - lower = np.array([color_code[0][0] / 2, color_code[0][1] / 2, color_code[0][2] / 2]) - upper = np.array([color_code[0][0], color_code[0][1], color_code[0][2]]) + hsv_color = rgb_to_hsv(color_code[0]) + + # 计算HSV的下限和上限 + lower = np.array([hsv_color[0] - 35, hsv_color[1] * 0.5, hsv_color[2] * 0.65]) + upper = np.array([hsv_color[0] + 10, hsv_color[1] * 1.2, hsv_color[2] * 1.2]) + + # 确保HSV值在有效范围内 + lower = np.clip(lower, 0, 180) + upper = np.clip(upper, 0, 255) + + # 更新自定义颜色的HSV阈值 update_custom_hsv(lower, upper) def update_custom_hsv(lower, upper): @@ -76,17 +92,19 @@ def update_custom_hsv(lower, upper): update_color_threshold('custom') def exit_app(): - global running, cap + global running, cap, stop_thread running = False + stop_thread = True + root.quit() cap.release() cv2.destroyAllWindows() - root.quit() + def initialize_gui(): """初始化GUI界面""" global root root = tk.Tk() - root.title("Color Tracker") + root.title("颜色追踪") # 开始/停止摄像头按钮 start_button = tk.Button(root, text="开始/停止", command=start_camera) start_button.pack() @@ -111,37 +129,37 @@ def initialize_gui(): ) # 自定义颜色HSV滑块 - lower_h_scale = Scale(root, from_=0, to=180, orient=HORIZONTAL, label="Hue Min", + lower_h_scale = Scale(root, from_=0, to=180, orient=HORIZONTAL, label="色调 Min", command=lambda v: set_custom_hsv(v, lower_s_scale.get(), lower_v_scale.get(), upper_h_scale.get(), upper_s_scale.get(), upper_v_scale.get())) lower_h_scale.pack() - lower_s_scale = Scale(root, from_=0, to=255, orient=HORIZONTAL, label="Saturation Min", + lower_s_scale = Scale(root, from_=0, to=255, orient=HORIZONTAL, label="饱和度 Min", command=lambda v: set_custom_hsv(lower_h_scale.get(), v, lower_v_scale.get(), upper_h_scale.get(), upper_s_scale.get(), upper_v_scale.get())) lower_s_scale.pack() - lower_v_scale = Scale(root, from_=0, to=255, orient=HORIZONTAL, label="Value Min", + lower_v_scale = Scale(root, from_=0, to=255, orient=HORIZONTAL, label="亮度 Min", command=lambda v: set_custom_hsv(lower_h_scale.get(), lower_s_scale.get(), v, upper_h_scale.get(), upper_s_scale.get(), upper_v_scale.get())) lower_v_scale.pack() - upper_h_scale = Scale(root, from_=0, to=180, orient=HORIZONTAL, label="Hue Max", + upper_h_scale = Scale(root, from_=0, to=180, orient=HORIZONTAL, label="色调 Max", command=lambda v: set_custom_hsv(lower_h_scale.get(), lower_s_scale.get(), lower_v_scale.get(), v, upper_s_scale.get(), upper_v_scale.get())) upper_h_scale.pack() - upper_s_scale = Scale(root, from_=0, to=255, orient=HORIZONTAL, label="Saturation Max", + upper_s_scale = Scale(root, from_=0, to=255, orient=HORIZONTAL, label="饱和度 Max", command=lambda v: set_custom_hsv(lower_h_scale.get(), lower_s_scale.get(), lower_v_scale.get(), upper_h_scale.get(), v, upper_v_scale.get())) upper_s_scale.pack() - upper_v_scale = Scale(root, from_=0, to=255, orient=HORIZONTAL, label="Value Max", + upper_v_scale = Scale(root, from_=0, to=255, orient=HORIZONTAL, label="亮度 Max", command=lambda v: set_custom_hsv(lower_h_scale.get(), lower_s_scale.get(), lower_v_scale.get(), upper_h_scale.get(), upper_s_scale.get(), v)) @@ -167,8 +185,8 @@ def start_camera(): def camera_thread(): """摄像头处理线程函数""" - global running, initial_measurement, lower_hsv, upper_hsv - while running: + global running, initial_measurement, lower_hsv, upper_hsv, stop_thread + while running and not stop_thread: ret, frame = cap.read() if not ret: messagebox.showerror("Error", "Failed to read frame from camera.") @@ -192,7 +210,7 @@ def camera_thread(): # 遍历轮廓,画出边界框 for contour in contours: - if cv2.contourArea(contour) > 100: + if cv2.contourArea(contour) > 300: x, y, w, h = cv2.boundingRect(contour) cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) @@ -209,6 +227,9 @@ def camera_thread(): (int(prediction[0] + w), int(prediction[1] + h)), (255, 0, 0), 2) + + print(lower_hsv, upper_hsv) + cv2.imshow('Frame', frame) cv2.imshow('Mask', mask) diff --git a/工程/invoke.py b/工程/invoke.py index 59f6606..ddd0c8a 100644 --- a/工程/invoke.py +++ b/工程/invoke.py @@ -26,9 +26,11 @@ button2.move(50, 100) button2.clicked.connect(Area_tracking.main) quit_button = QPushButton('退出', widget) -quit_button.move(150, 50) +quit_button.move(200, 50) quit_button.clicked.connect(quit_app) + + widget.show() sys.exit(app.exec())