检测PCB板上的走线宽度

对应示例程序:
measure_circuit_width_lines_gauss.hdev

目标:测量pcb板上的走线轨迹的宽度

思路为:
      1.读取图像
      2.根据图像特性,将R,G,B的三通道图像分成R,G,B的三幅单通道图像,单独处理G图像
      3.利用形态学的处理方法,膨胀,开操作等,取出待检测直线区域
      4.利用line_gauss算子,提取出ROI区域中的直线,并获取直线上的每个点的宽度
      5.将宽度的值与容许的阈值进行比较,并显示

例程相对简单,但是利用形态学的方法定位到ROI区域,以及寻找Tuple中的小于Min和Max的方法,值得学习。
tuple_find (min2(LineWidth,MaxTrackWidth), MaxTrackWidth, IndicesTooBroad)

图像:
在这里插入图片描述
在这里插入图片描述

代码:

//前期准备 开窗口 设置字体  读取图像
dev_update_off ()
dev_close_window ()
read_image (Image, 'pcb_color')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
dev_set_draw ('margin')
dev_set_color ('yellow')
* 
*设置宽度的最大、最小阈值  可以调整
* Define the minimum and maximum width of the pcb tracks
MaxTrackWidth := 6.0
MinTrackWidth := 4.0
* 
//根据先验知识,画个矩形子区域进行后续的测量
* Select a sub-region of the image
Rectangle := [271,285,528,718]
gen_rectangle1 (PcbPart, Rectangle[0], Rectangle[1], Rectangle[2], Rectangle[3])
dev_display (Image)
dev_display (PcbPart)
disp_message (WindowHandle, 'Measure the width of tracks using lines_gauss', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
//调整下窗口 把子区域进行显示  调整后的的窗口略大于之前画的矩形
dev_set_part (Rectangle[0] - 15, Rectangle[1] - 15, Rectangle[2] + 15, Rectangle[3] + 15)
dev_display (Image)
dev_display (PcbPart)
disp_message (WindowHandle, 'Exemplarily shown here for a part of the circuit board', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
//进行检测  主要是Blob分析 形态学处理 把PCB上的轨迹线部分抠出来  这个需要学习
* Extract the tracks
//根据图像可以发现,图像的绿色较多,因此把3通道的图像分成R,G,B三个通道图  再单独对G图像进行处理
decompose3 (Image, ImageR, ImageG, ImageB)   //把一个RGB三通道图像 分成R\G\B三个单通道图像
reduce_domain (ImageG, PcbPart, ImageReduced)  //根据矩形 从原图中抠ROI图像
threshold (ImageReduced, Region, 90, 255)      //阈值分割
dilation_circle (Region, RegionDilation, 3.5)   //圆形膨胀
opening_rectangle1 (Region, RegionOpening, 8, 8)  //矩形开操作
dilation_circle (RegionOpening, RegionDilation1, 3.5)  //圆膨胀
difference (Region, RegionDilation1, RegionDifference)  //求两个图像的差异  得到只剩下线的RegionDifference
difference (RegionDilation, RegionDilation1, RegionDifference)  //求两个图像的差异部分

connection (RegionDifference, ConnectedRegions)   //连通域分割
select_shape (ConnectedRegions, RegionSelected, 'area', 'and', 260, 4595)  //根据面积进行区域筛选
union1 (RegionSelected, RegionTracks)   //合并符合条件的区域
reduce_domain (ImageReduced, RegionTracks, ImageReducedTracks)  //抠图  把PCB上的线抠出来
* 
* Measure the position and the width of the tracks
lines_gauss (ImageReducedTracks, Lines, 1.5, 1, 8, 'light', 'true', 'bar-shaped', 'true') //检测图像中的线条及其宽度
select_shape_xld (Lines, SelectedXLD, 'contlength', 'and', 20, 99999)  //根据  线长 筛选直线
dev_display (Image)
dev_set_color ('yellow')
dev_display (PcbPart)
dev_set_color ('green')
dev_set_line_width (2)
dev_display (Lines)
disp_message (WindowHandle, 'Extracted tracks', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Compute the width of the tracks
//计算提取出的直线的宽度
count_obj (SelectedXLD, NumberL)
RowLine := []
ColLine := []
LineWidth := []
for IndexL := 1 to NumberL by 1
    select_obj (SelectedXLD, Line, IndexL)
    get_contour_xld (Line, Row, Column)  //获取每条直线上的点坐标
    get_contour_attrib_xld (Line, 'width_left', WidthL)   //得到线上每个点的属性 (直线区域上的上边缘到中心点的距离)
    get_contour_attrib_xld (Line, 'width_right', WidthR)  //直线区域上的下边缘到中线点的距离(待验证)
    RowLine := [RowLine,Row]   //两个Tuple进行合并 相当于把每个坐标都放在这个Tupe里面
    ColLine := [ColLine,Column]
    LineWidth := [LineWidth,WidthR + WidthL]  //直线的宽度就是两个距离的合
endfor
* 
* Detect the tracks with a wrong width
//找小于最小阈值 或者大于最大阈值的点 
//先把LineWidth中的数与最大阈值进行比较,如果比最大值大,那么这个值就被替换成了MaxTrackWidth,
   这时再从LineWidth中找等于MaxTrackWidth的点,那个点就是超过范围的点,记录它的ID,放到IndicesTooBroad中
   没找到符合条件的点就返回-1
tuple_find (min2(LineWidth,MaxTrackWidth), MaxTrackWidth, IndicesTooBroad)  
tuple_find (max2(LineWidth,MinTrackWidth), MinTrackWidth, IndicesTooNarrow)
if (IndicesTooBroad == -1)
    IndicesTooBroad := []   //没找到大于阈值的点 那么太宽的这个Tuple就设置为空
endif
if (IndicesTooNarrow == -1)
    IndicesTooNarrow := []
endif
//将单个像素存储为图像区域
//subset 选取数组t中的第i个元素
//根据上一步找出的太宽或者太窄点的ID,进行点  转变成  区域
gen_region_points (RegionTooBroad, subset(RowLine,IndicesTooBroad), subset(ColLine,IndicesTooBroad))
gen_region_points (RegionTooNarrow, subset(RowLine,IndicesTooNarrow), subset(ColLine,IndicesTooNarrow))
* 
//显示测量结果
* 处理太宽的区域
connection (RegionTooBroad, RegionTooBroad)  //将符合要求的区域进行连通域分割
gen_contours_skeleton_xld (RegionTooBroad, TracksTooBroad, 1, 'filter')  //区域转化成XLD轮廓
smallest_circle (RegionTooBroad, RowTooBroad, ColumnTooBroad, RadiusTooBroad)  //计算它的最小外接圆,用来定位展示
//创建与圆或圆弧相对应的XLD轮廓  其实就是把最小的外接圆 进行放大显示  便于观察
gen_circle_contour_xld (CircleTooBroad, RowTooBroad, ColumnTooBroad, min2(RadiusTooBroad + 10,20), 0, 6.28318, 'positive', 1)
*处理太窄的区域
connection (RegionTooNarrow, RegionTooNarrow)  //连通域分割
gen_contours_skeleton_xld (RegionTooNarrow, TracksTooNarrow, 1, 'filter')  //转化成XLD轮廓
smallest_circle (RegionTooNarrow, RowTooNarrow, ColumnTooNarrow, RadiusTooNarrow)  //最小外接圆
gen_circle_contour_xld (CircleTooNarrow, RowTooNarrow, ColumnTooNarrow, min2(RadiusTooNarrow + 10,20), 0, 6.28318, 'positive', 1)
dev_clear_window ()
dev_display (Image)
dev_display (ImageReduced)
dev_set_line_width (1)
dev_set_color ('green')
dev_display (Lines)
dev_set_line_width (2)
dev_set_color ('red')
dev_display (TracksTooBroad)  //显示太宽的线
dev_display (CircleTooBroad)  //用最小外接圆进行标记定位
dev_set_color ('magenta')
dev_display (CircleTooNarrow)  //显示太窄的线
dev_display (TracksTooNarrow)   //用最小外接圆进行标记定位
disp_message (WindowHandle, ['Extracted tracks',' - Too broad',' - Too narrow'], 'window', 12, 12, ['black','red','magenta'], 'true')

用到的几个算子:
      decompose3 --把一个RGB三通道图像 分成R\G\B三个单通道图像
      lines_gauss–检测图像中的线条
      gen_region_points – 将单个像素存储为图像区域
      subset --选取数组t中的第i个元素
      tuple_find–返回一个元组在另一个元组中所有出现的索引 (就是在一个Tuple中找等于另一个Tuple的值,返回它的ID)

参考资料:
[1].https://blog.csdn.net/douglax/article/details/38669941
[2].https://www.cnblogs.com/hu16683845/p/9181344.html

<think>好的,用户想了解PCB电源走线的设计要求和最佳实践。首先,我需要回忆之前关于PCB设计的知识,特别是电源部分的相关内容。记得电源设计在PCB中非常重要,涉及到稳定性和散热等问题。 根据引用[1],PCB设计包括电磁兼容分析和高速布线设计,这可能和电源走线的EMC有关。电源走线需要足够的宽度以减少阻抗,避免电压降过大,这可能是一个基本要求。同时引用[2]提到高速设计中的叠层设计和阻抗控制,电源层可能也需要考虑叠层结构,比如使用完整的平面层来提供低阻抗路径。 接下来,应该考虑电源走线宽度计算。用户可能需要知道如何根据电流大小计算走线宽度,避免过热。IPC标准有相关的公式或者表格,可能需要提到电流承载能力与铜厚、温升的关系。 另外,电源路径的布局也很关键。比如电源入口到各个器件的路径要尽量短,减少环路面积,这样有助于降低噪声和EMI。同时,去耦电容的放置位置很重要,应该靠近电源引脚,提供高频噪声的滤波。 分割电源平面时要注意不同电压域的隔离,防止干扰。比如数字和模拟电源的分割,避免串扰。但分割过多可能增加复杂性,需要平衡。 散热设计也是电源走线的一部分,大电流路径可能需要增加散热孔或铜箔面积,引用[1]中提到的散热设计部分应该相关。 还有EMC方面,比如避免锐角走线,使用圆弧或45度角,减少高频辐射。电源层与地层的靠近布置可以形成自然电容,帮助滤波。 用户可能还需要了解一些实际的最佳实践,比如星型拓扑布局、多层中使用完整平面层、测试点添加等。同时,验证部分如仿真和测试,引用[2]中提到的设计测试与验证需要涉及。 需要检查是否有遗漏点,比如过孔的数量和尺寸对电流的影响,热管理措施的具体方法,以及材料选择对电源完整性的影响。可能还需要提到电源完整性的仿真工具,如PI分析。 最后,生成相关问题时要围绕电源设计的其他方面,比如去耦电容的配置、多层设计、散热处理、EMI抑制方法等,帮助用户深入探索。</think>### PCB电源走线设计要求与最佳实践指南 #### 一、核心设计要求 1. **走线宽度与电流承载** 电源走线宽度需根据电流需求计算,避免过热或电压降过大。公式为: $$I = k \cdot \Delta T^{0.44} \cdot (W \cdot H)^{0.725}$$ 其中$I$为电流(A),$W$为走线宽度(mil),$H$为铜厚(oz),$k$为修正系数(外层取0.048,内层取0.024)[^1]。 2. **路径最短化与低阻抗** - 电源入口到负载路径应最短,优先采用平面层(如四层中单独分配电源层)[^2]。 - 关键器件(如CPU、FPGA)的电源引脚附近需放置去耦电容,距离不超过$5mm$[^1]。 3. **分层与参考平面** 电源层与相邻地层间距控制在$0.1mm$~$0.2mm$,利用层间电容抑制高频噪声[^2]。 #### 二、最佳实践方法 1. **拓扑结构优化** - 大电流路径采用**星型拓扑**,避免环路干扰(图1)。 ```plaintext [电源输入]───┬───[IC1] ├───[IC2] └───[IC3] ``` - 多电压系统使用**分割平面**,通过$20mil$以上间距隔离不同电源域[^1]。 2. **过孔与散热设计** - 每$1A$电流配置至少2个过孔(孔径≥$8mil$),并联降低阻抗。 - 大电流区域添加散热铜箔或散热焊盘,面积比常规走线扩大$50\%$[^1]。 3. **EMC防护措施** - 电源入口布置π型滤波电路($10μF$电解电容 + $100nF$陶瓷电容)。 - 敏感电源线采用**包地处理**,两侧布置地线并间隔$3W$($W$为走线宽度)[^2]。 #### 三、验证流程 1. **电源完整性仿真** 使用SI/PI工具验证电压波动(目标:≤$5\%$)和瞬态响应。 $$ΔV = I_{max} \cdot (R_{trace} + R_{via})$$ 要求$ΔV < 0.05V_{nominal}$[^2]。 2. **实物测试指标** - 红外热成像检测温升(允许值:铜箔≤$20℃$,焊点≤$35℃$) - 注入$100MHz$噪声信号时,纹波峰峰值<$50mV$[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值