一、原理:
opencv学习笔记13-opencv连通组件标记实现硬币计数
二、不同情况思路:
当焊点为背景时,进行反色处理(二值化后若焊点为背景,转化为前景)。
三、示例代码:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
//原图像转化为灰度图
Mat srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\spot.JPG",0);
//判断读取图片是否失败
if (srcMat.empty()) {
cout << "fail to read pic!" << endl;
return;
}
Mat stats;
Mat centroids;
Mat labels;
Mat image_thresh;
Mat image_erode;
Mat Inverse;
//大津法处理图像
threshold(srcMat, image_thresh, 100, 255, THRESH_OTSU);
//反色,二值化后若焊点为背景,转化为前景
//Inverse = 255 - image_thresh;
Mat element = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
//对图像进行腐蚀处理,只保留要求的点(白色为前景,黑色为背景,腐蚀前景)
erode(image_thresh, image_erode, element, Point(-1, -1), 2);
//反色后操作
//erode(Inverse, image_erode, element, Point(-1, -1), 2);
//进行连通域标记
int nComp = connectedComponentsWithStats(image_erode, labels, stats, centroids, 8, CV_32S);
//对识别出的连通域加最小外接边框
for (int i = 1; i < nComp; i++)
{
//定义Rect类
Rect frame;
frame.x = stats.at<int>(i, 0);
frame.y = stats.at<int>(i, 1);
frame.width = stats.at<int>(i, 2);
frame.height = stats.at<int>(i, 3);
rectangle(image_erode, frame, 255, 1, 8, 0);
}
//减去背景,并输出个数
cout << "焊点个数为:" << nComp - 1 << endl;
imshow("image_thresh", image_thresh);
imshow("image_erode", image_erode);//只保留需要的点的图像
waitKey(0);
return 0;
}