triangle algo refind
This commit is contained in:
@@ -221,4 +221,56 @@ Why it works:
|
||||
MIPSEND enters prompt mode (>) — after the >, the AT parser treats ALL bytes as data, including CR/LF
|
||||
We construct the complete HTTP request ourselves (headers + Content-Length + multipart body) with real CRLF bytes
|
||||
|
||||
Key bug found during integration: _send_chunk() wrapped calls in self.at._cmd_lock, but self.at.send() also acquires the same lock internally — threading.Lock() is not reentrant, causing deadlock. Fixed by removing the outer lock (the network_manager.get_uart_lock() already provides thread safety).Trade-off: UART is locked during the entire upload, so heartbeats pause. For small JPEG files (~2-80KB), this is 5-20 seconds — acceptable if server heartbeat timeout is generous
|
||||
Key bug found during integration: _send_chunk() wrapped calls in self.at._cmd_lock, but self.at.send() also acquires the same lock internally — threading.Lock() is not reentrant, causing deadlock. Fixed by removing the outer lock (the network_manager.get_uart_lock() already provides thread safety).Trade-off: UART is locked during the entire upload, so heartbeats pause. For small JPEG files (~2-80KB), this is 5-20 seconds — acceptable if server heartbeat timeout is generous
|
||||
|
||||
|
||||
13. 算环数算法1:「黄心 + 红心」椭圆/圆:主要在 vision.py 的 detect_circle_v3() 里完成:颜色先用 HSV 做掩码,再在轮廓上做面积、圆度筛选,黄圈用椭圆拟合,红圈预先筛成候选,最后用几何关系配对。
|
||||
|
||||
1. 黄色怎么判、范围是什么?
|
||||
图像先转 HSV(cv2.COLOR_RGB2HSV,注意输入是 RGB)。
|
||||
饱和度 S 整体乘 1.1 并限制在 0–255(让黄色更「显」一点)。
|
||||
黄色 inRange(OpenCV HSV,H 多为 0–179):
|
||||
通道 下限 上限
|
||||
H 7 32
|
||||
S 80 255
|
||||
V 0 255
|
||||
在黄掩码上找轮廓后,还要满足:面积 > 50,圆度 > 0.7(circularity = 4π·面积/周长²),且点数 ≥5 才 fitEllipse 当黄心椭圆。
|
||||
|
||||
2. 红色怎么判、范围是什么?
|
||||
红色在 HSV 里跨 0°,所以用 两段 H 做并集:
|
||||
两段分别是:
|
||||
H 0–10,S 80–255,V 0–255
|
||||
H 170–180,S 80–255,V 0–255
|
||||
红轮廓候选:面积 > 50,圆度 > 0.6(比黄略松),再拟合椭圆或最小外接圆得到圆心和半径。
|
||||
|
||||
3. 「黄心」和「红心」怎样算一对?(几何范围)
|
||||
对每个黄圈,在红色候选里找第一个满足:
|
||||
|
||||
两圆心距离 dist_centers < yellow_radius * 1.5
|
||||
红半径 red_radius > yellow_radius * 0.8(红在外圈、略大)
|
||||
dist_centers = math.hypot(ddx, ddy)
|
||||
if dist_centers < yellow_radius * 1.5 and rc["radius"] > yellow_radius * 0.8:
|
||||
小结:黄色 = HSV H∈[7,32]、S≥80(且 S 放大 1.1)+ 形态学闭运算 + 面积/圆度;红色 = 两段 H(0–10 与 170–180)、S≥80 + 闭运算 + 面积/圆度;配对用 同心/包含 的距离与半径比例阈值。若你还关心 laser_manager.py 里「激光红点」的另一套阈值(LASER_*),那是另一条链路,和靶心黄/红 HSV 可以分开看。
|
||||
|
||||
14. 算环数算法2:
|
||||
使用单应性矩阵计算:镜头中心点(照片中心像素)到虚拟平面的转换。它不需要知道相机在 3D 空间中的具体位置,直接通过单应性矩阵 H的逆运算,将 2D 像素“翻译”成虚拟平面上的 2D 坐标。
|
||||
|
||||
一、转换的本质:2D 到 2D 的“查字典”
|
||||
单应性变换(Homography)是平面到平面的映射。它不处理 3D 空间中的“投影线”,而是直接建立图像像素 (u,v) 与虚拟平面坐标 (x,y) 的一一对应关系。
|
||||
你可以把单应性矩阵 H想象成一本“翻译字典”:
|
||||
正变换 H:已知靶纸上的真实位置 (x,y),查字典得到它在照片上哪个像素 (u,v)。
|
||||
逆变换 H−1:已知照片上的像素 (u,v)(如镜头中心点),查字典反推它在靶纸上的真实位置 (x,y)。
|
||||
这个“虚拟平面”就是你的靶纸平面(Z=0 的世界坐标系)。算法没有在物理上移动任何点,只是在做坐标系的换算。
|
||||
|
||||
二、详细步骤:镜头中心点如何“落地”
|
||||
|
||||
相机分辨率是 640x480,镜头中心点(光轴与图像的交点)通常是 (u0,v0)=(320,240)。
|
||||
1. 输入:镜头中心点(像素)
|
||||
2. 核心运算:乘以逆矩阵
|
||||
通过 4 个黑色三角形的角点(已知真实坐标)计算出了单应性矩阵 H。现在使用它的逆矩阵 H−1
|
||||
3. 输出:虚拟平面上的落点(物理坐标)
|
||||
计算后,你会得到:(xhit,yhit)
|
||||
这就是镜头中心点对应的靶纸上的真实位置(单位:毫米)。
|
||||
4. 计算环数
|
||||
由于虚拟平面原点 (0,0)就是靶纸圆心,直接计算欧氏距离。
|
||||
这个 d就是箭着点偏离圆心的真实物理距离,直接用于环数判定。
|
||||
Reference in New Issue
Block a user