背景:在我们生活中常常需要我们用肉眼来计算某些物品的数量,如果通过人工操作会产生:①.效率低下;②.长时间的工作会导致眼睛疲劳导致错误的计算;为此,我们可以使用图像处理来检测方便我们.
代码如下:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat srcImage; //源图
Mat dstImage; //目标图
Mat grayImage;//灰度图
int Coin = 0; //硬币个数
string intToString(int number)
{
ostringstream ss;
ss << number;
return ss.str();
}
int main()
{
//载图
srcImage = imread("D:/photoes/coin.png");
if (srcImage.empty())
{
cout << "fail to read the Image!" << endl;
return -1;
}
//色彩空间转换
cvtColor(srcImage, grayImage,COLOR_BGR2GRAY);
//平滑滤波降噪
blur(grayImage, dstImage,Size(3,3));
// imshow("平滑降噪",dstImage);
//使用大津法阈值分割前景与背景
threshold(dstImage,dstImage,0,255,THRESH_OTSU);
// imshow("阈值分割",dstImage);
//孔洞填充
//floodFill(dstImage,Point(0,0),Scalar(255));
//imshow("空洞填充",dstImage);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(dstImage,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
vector<vector<Point>> contours_poly(contours.size());
for (int i = 0; i < contours.size(); i++)
{
approxPolyDP(contours[i], contours_poly[i], 3, true);
//drawContours(dstImage, contours_poly, i, Scalar(255));
Point2f center;
float radius;
minEnclosingCircle(contours_poly[i], center, radius);
if (radius < 20)
continue;
circle(dstImage,center,radius,Scalar(255),4);
circle(srcImage, center, radius, Scalar(0,0,255), 1);
Coin++;
}
//imshow("找轮廓填轮廓",dstImage);
string text = "detected coin's number:" + intToString(Coin);
int fontFace = FONT_HERSHEY_COMPLEX;
double fontScale = 1;
int thickness = 1;
Size textSize = getTextSize(text, fontFace, fontScale, thickness, 0);
Point org = Point(0, textSize.height);
putText(srcImage, text, org, fontFace, fontScale, Scalar(0,0,255), 1, 8);
imshow("原始图", srcImage);
waitKey(0);
}
效果图: