一张大PCB图像对每个小引脚通过亮度和RGB进行定位引脚头和尾部

要求描述:

  • 通过亮度和颜色的设定标示出引脚根部(本体) 部分
  • 通过亮度和颜色的设定标示出引脚部分
  • 通过亮度和颜色的设定标示出焊锡部分

原图为:

选取的ROI区域:

灰度图:

 通过亮度和颜色的设定标示出引脚根部(本体) 部分

 通过亮度和颜色的设定标示出引脚部分

 通过亮度和颜色的设定标示出焊锡部分(引脚的头和尾)

思想是;把要处理的roi区域复制为两个图像,一个用来处理打掩模,以及满足一定的条件做一些操作,然后在把他加到原有没有处理的ROI图像上。

 代码:

主函数test.cpp为:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<fstream>
#include<quickopencv.h>
using namespace cv;
using namespace std;


Mat roi_select(Mat& image, Point sp, Point ep) {
	int dx = ep.x - sp.x;
	int dy = ep.y - sp.y;
	Rect box(sp.x, sp.y, dx, dy);//ROI区域大小
	Mat new_img = image(box);
	/*QuickDemo qd;
	Mat ROI_his = qd.histogram_grayImage(new_img);
	namedWindow("ROI_his", WINDOW_FREERATIO);
	imshow("ROI_his", ROI_his);*/
	return new_img;
}


int main() {
	Mat src = imread("C:\\Users\\Administrator\\Documents\\WXWork\\1688850162194623\\Cache\\File\\2021-08\\0015.bmp");
	if (src.empty())
	{
		printf("could not load image...");
		return -1;
	}
	//namedWindow("input_image", WINDOW_FREERATIO);
	//imshow("input_image", src);
	Mat roi_src = roi_select(src, Point(672, 1571), Point(2007, 1724));
	namedWindow("roi_src", WINDOW_AUTOSIZE);
	imshow("roi_src", roi_src);


	Mat gray_roi_src;
	cvtColor(roi_src, gray_roi_src, COLOR_BGR2GRAY);
	imshow("gray_roi_src", gray_roi_src);

	QuickDemo qd;

	//引脚根部搜索:通过亮度和颜色的设定标示出引脚本体部分
	Mat mask_img = qd.lead_mask(roi_src, gray_roi_src);

	//通过亮度和颜色的设定标示出引脚部分
	Mat after_mask = qd.sub_lead_mask(mask_img, gray_roi_src);
	imshow("after_mask", after_mask);

	//通过亮度和颜色的设定标焊锡部分(引脚的头和尾)
	Mat box_label = qd.min_box(roi_src, after_mask);
	imshow("box_label", box_label);

	waitKey(0);
	return 0;
}

 源函数为:

// 打掩模
Mat QuickDemo::lead_mask(Mat& image,Mat &gray_image)
{
	int height = image.rows;
	int width = image.cols;
	Mat dstImg = image.clone();// 新图像(寄存图像,输出就是这张图像)
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			if (image.at<Vec3b>(i, j)[0] < 150
				&& image.at<Vec3b>(i, j)[1] < 133 
				&& image.at<Vec3b>(i, j)[2] < 150)
			{
				dstImg.at<Vec3b>(i, j)[0] = 245;
				dstImg.at<Vec3b>(i, j)[1] = 4;
				dstImg.at<Vec3b>(i, j)[2] = 251;
			}
		}
	}
	namedWindow("lead_mask", WINDOW_AUTOSIZE);
	imshow("lead_mask", dstImg);
	return dstImg;
}

Mat QuickDemo::sub_lead_mask(Mat& image, Mat& gray_image)
{
	int height = gray_image.rows;
	int width = gray_image.cols;
	int threshold_value = 100;
	int threshold_max = 255;
	vector<Point> points;
	for (int row = 0; row < height; row++)
	{
		for (int col = 0; col < width; col++)
		{
			if (image.at<Vec3b>(row, col)[0] > 20 
				&& image.at<Vec3b>(row, col)[1] > 20 
				&& image.at<Vec3b>(row, col)[2] > 20
				&& gray_image.at<uchar>(row, col) > 20)
			{
				image.at<Vec3b>(row, col)[0] = 0;
				image.at<Vec3b>(row, col)[1] = 0;
				image.at<Vec3b>(row, col)[2] = 0;
			}
		}
	}
	//imshow("output", image);
	return image;

}

		
Mat QuickDemo::min_box(Mat& rgb_image, Mat& after_mask)
{
	Mat src_g;
	cvtColor(rgb_image, src_g, COLOR_BGR2GRAY);

	Mat dstImg = after_mask.clone();

	Mat binary_src;
	threshold(src_g, binary_src, 80, 255, THRESH_BINARY);

	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(binary_src, contours, hierarchy,
		RETR_EXTERNAL, CHAIN_APPROX_NONE);

	vector<Rect> boundRect(contours.size());  //定义外接矩形集合
	Point2f rect[4];
	for (int i = 0; i < contours.size(); i++)
	{
		boundRect[i] = boundingRect(Mat(contours[i]));
		rectangle(dstImg, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
	}
	return dstImg;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI炮灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值