首先感谢陈广锋同学的论文,若侵权,请联系删除。
论文里面提出利用区域生长法获取引脚的总数及各个引脚主体部分的形心坐标及面积。通过与实际引脚总数进行对比, 判断是否存在引脚缺失的缺陷, 并和实际引脚的间距、面积的设定值进行对比, 当测定值超过设定值一定范围时, 认为该芯片存在引脚位置偏移以及高度偏移等缺陷。
与作者不同之处在于我使用提取轮廓,构建掩膜图像的方式获取引脚的主体部分,其余部分均按照论文思路判别缺陷。
步骤:
- 图像预处理;
- 提取轮廓,构建掩膜图像,获取引脚主体;
- 引脚分割为4个ROI,排序,获取引脚质心;
- 通过引脚数目 ,面积,质心间距指标分别判别缺脚,高度偏移,位置偏移;
- 通过拟合4个ROI内引脚质心,获取4线方程,从而获取芯片中心坐标,即可获得相对参考坐标的偏移量;
- 选择上下两线的斜率平均值,即可获取芯片的旋转量。
主要代码:
void find(Mat &src, vector<vector<Point>>con_new) {
int num = con_new.size();
cout << "num = " << num << endl;
//缺脚判断
vector<Moments>mu(con_new.size());
vector<Point2f>mc(con_new.size());
double area = 0;
if (num == 12) {
//偏移判断
for (int i = 0; i < con_new.size(); i++) {
area = contourArea(con_new[i]);
//cout << " area=" << area << endl;
//上下判断
if (area > 19) {
cout << "上偏" << endl;
Rect box = boundingRect(con_new[i]);
rectangle(src, box, Scalar(0, 0, 255), 1, 8);
}
else
if (area < 7) {
cout << "下偏" << endl;
Rect box = boundingRect(con_new[i]);
rectangle(src, box, Scalar(0, 0, 255), 1, 8);
}
mu[i] = moments(con_new[i], false);
mc[i] = Point(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
}
//判断质心之间的距离
for (int i = 1; i < mc.size(); i++) {
double dis = sqrt((mc[i].x - mc[i - 1].x)*(mc[i].x - mc[i - 1].x) + (mc[i].y - mc[i - 1].y)*(mc[i].y - mc[i - 1].y));
// cout <<" dis="<< dis << endl;
if (5 > dis || dis > 9) {
cout << "水平偏移" << endl;
rectangle(src, Rect(mc[i - 1].x - 5, mc[i - 1].y - 5, 15, 15), Scalar(0, 0, 255), 1, 8);
}
}
}
else {
cout << "缺脚" << endl;
putText(src, "quejiao", Point(50, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2, 8);
}
}
void sortCon_topAndbot(vector<vector<Point>>&sortTopAndBot) {
vector<Point>temp_x;
vector<int>box_x;
for (int i = 0; i < sortTopAndBot.size(); i++) {
Rect box = boundingRect(sortTopAndBot[i]);
box_x.push_back(box.x);
}
//轮廓排序
for (int i = 0; i < sortTopAndBot.size(); i++) {
for (int j = i + 1; j < sortTopAndBot.size(); j++) {
if (box_x[j] < box_x[i]) {
temp_x = sortTopAndBot[j];
sortTopAndBot[j] = sortTopAndBot[i];
sortTopAndBot[i] = temp_x;
}
}
}
//for (int i = 0; i < sortTopAndBot.size(); i++) {
// Rect box = boundingRect(sortTopAndBot[i]);
// cout << box.x << endl;
//}
}
部分结果:
如图是高度上偏和水平间距大,此图为论文中截图,质量不是很好,导致检测误差较大,但实现过程应该没问题。说明了定位思路,没有继续写代码。