透明圆瓶内部特征怎样定位:折射追踪与近远相位分支

壹星(YIXING)技术笔记|东莞市壹星自动化设备有限公司

透明瓶内部特征在图像上偏了多少,不一定能唯一换算成一个周向相位。即使内外壁同心、折射率已知、特征位于已知半径上,同一条进入瓶内的视线也可能与该半径圆相交两次。先检查近、远分支,再讨论相位定位,比直接套一个反正弦公式更可靠。

本文给出二维同心圆壳的逆向光线追踪教学示例,只用于研究几何可辨识性,不表示任何圆瓶贴标机配备内部视觉定位,也不输出旋转轴补偿指令。

从像素到一条视线

取瓶心为原点,相机光心在负横坐标方向,光轴指向正横坐标。已经完成相机内部标定且校正镜头畸变后,横向像素偏移u与像素焦距f给出视线角α=arctan(u/f)。相机方向向量为(cosα,sinα)。这里u和f都使用像素,空间半径和相机距离则统一使用毫米。

已知起点o和单位方向d,光线为o+td。与半径R的圆相交时,解t²+2(o·d)t+o·o−R²=0,选择正向交点。判别式为负表示没有几何交点,与发生全反射是两种不同失败状态。

每次折射都使用当地法线

进入外壁和内腔时,法线均选择指向下一介质的方向。折射满足n₁sin i=n₂sin r,入射角和折射角相对当地法线定义,见OpenStax折射章节。在可逆几何光学假设下,可以沿相机到物体的方向追踪。

向量形式中,设η=n₁/n₂、q=d·N,切向分量乘η,法向分量为√1−η²(1−q²)。根号内为负时,没有本次透射解,需报告全反射;其条件见OpenStax全反射章节。不能用"没碰到内圆"替代这个判断。

已知特征半径仍有两个分支

光线进入内腔后,与特征所在的半径圆求交。两个正向交点分别对应近侧与远侧候选位置,不代表图像同时存在两个真实特征。若实际只检测到一个特征,仍需要额外的可见性、身份、时间连续性或多视角信息选择分支。

特别是中心视线:位于前侧与后侧的两个相反相位都可能投影到中心像素。这种歧义不会因为焦距更准确或计算小数更多而消失。如果内部吸管形状随姿态变化,特征回转半径本身也不能当作常量。

特征半径与瓶内半径是两个独立输入,不能因为内壁尺寸已知就用它替代特征位置。若特征半径未知,一条视线上可能存在连续多个位置候选,而不只是本例的两个交点。所谓唯一定位,必须明确是哪项额外信息消除了这些自由度。

离线追踪与分支输出

教学参数设相机距瓶心三百毫米,外半径三十、内半径二十七、特征半径二十毫米,折射率依次为一、一点五、一点三三。这些是理想介质参数,并非某种瓶材和填充液的认证数值。相位零点朝向相机,向上转为正。

复制代码
from math import sqrt, atan, atan2, cos, sin, degrees

def dot(a, b):
    return sum(x*y for x, y in zip(a, b))

def intersections(origin, direction, radius):
    b = dot(origin, direction)
    discriminant = b*b-dot(origin, origin)+radius*radius
    if discriminant < 0:
        return []
    roots = sorted((-b-sqrt(discriminant), -b+sqrt(discriminant)))
    return [tuple(origin[i]+t*direction[i] for i in range(2))
            for t in roots if t > 1e-9]

def refract(direction, point, radius, n1, n2):
    normal = tuple(-x/radius for x in point)
    q = dot(direction, normal)
    eta = n1/n2
    root = 1-eta*eta*(1-q*q)
    if root < 0:
        raise ValueError("total_internal_reflection")
    return tuple(eta*(direction[i]-q*normal[i])+sqrt(root)*normal[i] for i in range(2))

def phases(pixel, inside_index=1.33):
    angle = atan(pixel/2500.0)
    direction = (cos(angle), sin(angle))
    outer = intersections((-300.0, 0.0), direction, 30.0)
    if not outer:
        raise ValueError("miss_outer")
    direction = refract(direction, outer[0], 30.0, 1.0, 1.5)
    inner = intersections(outer[0], direction, 27.0)
    if not inner:
        raise ValueError("miss_inner")
    direction = refract(direction, inner[0], 27.0, 1.5, inside_index)
    candidates = intersections(inner[0], direction, 20.0)
    if not candidates:
        raise ValueError("miss_feature_radius")
    return [degrees(atan2(p[1], -p[0])) % 360 for p in candidates]

for pixel in (0, 30, 70):
    print(f"pixel={pixel} candidate_phases=" + ",".join(f"{x:.6f}" for x in phases(pixel)))
for pixel, index in ((300, 1.33), (240, 1.0)):
    try:
        phases(pixel, index)
    except ValueError as exc:
        print(f"pixel={pixel} inside_index={index:.2f}: {exc}")

输出为:

复制代码
pixel=0 candidate_phases=0.000000,180.000000
pixel=30 candidate_phases=8.739608,173.184365
pixel=70 candidate_phases=20.739997,163.937978
pixel=300 inside_index=1.33: miss_outer
pixel=240 inside_index=1.00: total_internal_reflection

输出保留两个候选,而没有把近侧解自动称为真实相位。后两行还区分了外圆未相交和内界面全反射。代码中的微小正距离仅用于排除数值上的起点重复,不代表光学测量精度。

复核追踪实现时,可以检查每个交点是否位于对应圆上、折射前后方向是否保持单位长度,以及切向分量是否符合折射定律。对已知特征相位,还应比较它的预测成像与保留图像;仅把同一反解公式重复调用一次,不是独立的成像验证。

当视线接近特征圆的切线时,两交点接近合并,较小的像素或几何误差可能带来较大的相位变化。此时应报告候选范围和敏感性,而非只输出固定小数位的角度。改变填充状态或瓶壁结构后,也要重新核对模型输入。

模型还遗漏哪些成像条件

瓶壁偏心、非圆截面、镜头有限孔径、反射亮斑和多路径成像都可能破坏这条理想视线模型。二维截面假设还要求光路与所选截面相容;不能把任意相机俯仰下的像素直接代入。

实际标定应保留已知相位的独立验证样本,检查近远分支是否可识别及残差是否随姿态变化。某处没有透射解,也不证明整幅图像在该姿态完全没有信息。只有分支、几何和特征身份都得到验证后,相位结果才可能成为后续定位的输入。

相关推荐
Dev_XH35 分钟前
【成品设计】基于物联网的配电箱智能防护系统设计
stm32·单片机·嵌入式硬件·物联网
BioTender1 小时前
Xaira 发布 X-Automate:将物理 AI 与智能体 AI 引入实验室自动化
运维·人工智能·自动化
Dev_XH2 小时前
【成品设计】基于单片机的工厂设备能耗监控与优化系统
stm32·单片机·嵌入式硬件·物联网
不脱发的程序猿3 小时前
STM32制作单手鼠标键盘
stm32·嵌入式硬件·计算机外设·usb·qmk
天远API15 小时前
零信任架构实战:基于天远运营商三要素详版V即时版构建自动化消费电子大促电商平台高价值权益秒杀与优惠券防羊毛高并发实名核验网关
运维·人工智能·架构·自动化
路上有只喵19 小时前
认识元器件 · 单片机(MCU/MPU/SOC) · 实战篇 11
单片机·嵌入式硬件
不昀19 小时前
开关电源电流互感器怎么选:匝比、采样电阻与复位的计算笔记
单片机·嵌入式硬件·电子元器件
小李不想当小白1 天前
WDG看门狗(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
木头左1 天前
【Python】不点浏览器发博客:逆向 CSDN 创作中心接口做 md-publish 技能
python·自动化·api