背景:在我们生活中常常需要我们用肉眼来计算某些物品的数量,如果通过人工操作会产生:①.效率低下;②.长时间的工作会导致眼睛疲劳导致错误的计算;为此,我们可以使用图像处理来检测方便我们.
代码如下:
#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); }?? ? ?
效果图:
|