Embedded_game/002_B_Car/xdl/找圆2.py
2025-02-25 18:51:58 +08:00

143 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding:utf-8 -*-
# @Author len
# @Create 2023/11/30 11:08
import sensor, lcd, time
from machine import Timer, PWM
lcd.init(freq=15000000) # 初始化LCD
sensor.reset() # 复位和初始化摄像头
sensor.set_vflip(1) # 将摄像头设置成后置方式(所见即所得)
sensor.set_pixformat(sensor.RGB565)# 设置像素格式为彩色 RGB565
sensor.set_framesize(sensor.QVGA) # 设置帧大小为 QVGA (320x240)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
sensor.set_auto_gain(0, 0)
sensor.skip_frames(time=200) # 等待设置生效
def draw_circles():
"""
检测并绘制图像中的圆形,仅在图像的右半部分进行检测,
"""
start_time = time.ticks_ms() # 记录开始时间(毫秒)
def circles_overlap(c1, c2):
"""判断两个圆是否重叠"""
dx = c1.x() - c2.x()
dy = c1.y() - c2.y()
distance = (dx**2 + dy**2)**0.5
return distance < (c1.r() + c2.r())
def merge_circles(new_circle, cache):
"""尝试合并新检测到的圆与缓存中的圆"""
for existing in cache:
if circles_overlap(new_circle, existing):
return False # 如果重叠,不加入新的圆
cache.append(new_circle) # 如果没有重叠,添加到缓存中
return True
def calculate_lab(area, img):
"""计算给定区域的平均 LAB 值"""
stats = img.get_statistics(roi=area)
return stats.l_mean(), stats.a_mean(), stats.b_mean()
def determine_color_from_lab(lab):
"""
返回最接近的颜色以及对应的距离
:param lab: (l, a, b) 三元组
:return: (closest_color, min_distance)
"""
# 你可以根据实际情况添加或修改更多预设颜色及其 LAB
predefined_colors = {
"红色": (50, 38, 1),
"黄色": (86, 2, 27),
"绿色": (75, -29, 15)
}
min_distance = float('inf')
closest_color = "灰色" # 默认或者未匹配时
# 打印一下实际检测到的LAB便于调试
# print("检测到的LAB:", lab)
for color_name, (l_ref, a_ref, b_ref) in predefined_colors.items():
distance = ((lab[0] - l_ref) ** 2 +
(lab[1] - a_ref) ** 2 +
(lab[2] - b_ref) ** 2) ** 0.5
if distance < min_distance:
min_distance = distance
closest_color = color_name
if min_distance < 10:
print("最接近的颜色={}, 距离={:.2f}".format(closest_color, min_distance))
# print("最接近的颜色={}, 距离={:.2f}".format(closest_color, min_distance))
return closest_color, min_distance
count=0
min_color='red'
min_distance=50
while True:
img = sensor.snapshot()
# 只处理右半部分
roi = (img.width() // 2, 0, img.width() // 2, img.height())
# 在此根据整体亮度简单调参,阈值可自行调整
threshold = max(1000, min(5000, int(img.get_statistics().l_mean() * 50)))
# find_circles 参数可根据实际效果调整
circles = img.find_circles(roi=roi,
threshold=2500,
x_margin=20,
y_margin=20,
r_margin=20,
r_min=15,
r_max=30,
r_step=2)
if circles:
closest_circle = None
closest_distance = float('inf')
closest_color = "未知"
for c in circles:
area = (c.x() - c.r(), c.y() - c.r(), 2*c.r(), 2*c.r())
lab_val = calculate_lab(area, img)
color_name, distance = determine_color_from_lab(lab_val)
# 找出最小距离(与预设颜色最相似)的那个圆
if distance < closest_distance:
closest_distance = distance
closest_color = color_name
closest_circle = c
if closest_circle is None:
print('没有识别到')
continue
elif closest_distance<20:
area = (closest_circle.x() - closest_circle.r(),
closest_circle.y() - closest_circle.r(),
2*closest_circle.r(), 2*closest_circle.r())
# 画框和画圆
img.draw_rectangle(area, color=(255, 0, 0))
img.draw_circle(closest_circle.x(), closest_circle.y(), closest_circle.r(), color=(255, 0, 0))
print("最终识别到的颜色={}, 距离={:.2f}".format(closest_color, closest_distance))
min_distance=50
print("{}轮检测耗时: {} ms".format(count,time.ticks_diff(time.ticks_ms(), start_time)))
start_time = time.ticks_ms()
count+=1
else:
if closest_distance<min_distance:
min_color=closest_color
min_distance=closest_distance
if time.ticks_diff(time.ticks_ms(), start_time) > 5000:
print("最终识别到的颜色={}, 距离={:.2f}".format(min_color, min_distance))
print("{}轮检测耗时: {} ms".format(count,time.ticks_diff(time.ticks_ms(), start_time)))
start_time = time.ticks_ms()
min_distance=50
count+=1
# 主函数调用
if __name__ == "__main__":
draw_circles()