一,利用openCV的findContours轮廓查找功能,用已知物体的尺寸(比如硬币)作为参考,根据实际尺寸与像素尺寸的比列,求出图片中物体的实际大小。存在的问题有两个:
二,流程
三,代码
#include "stdafx.h"
#include
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/background_segm.hpp"
#include "opencv2/highgui/highgui.hpp"
#include
#include
using namespace std;
using namespace cv;
Mat g_srcImage;
Mat g_grayImage;
const int g_dReferWidth=19;//mm
double g_dPixelsPerMetric;
vector> g_vContours;
vector g_vHierarchy;
bool g_bFirst=true;
static cv::Point2f midpoint(cv::Point2f& ptA, cv::Point2f& ptB);//求中点
static float getDistance(Point2f pointA, Point2f pointB);//求距离
static bool ContoursSortFun(vector contour1, vector contour2);//按照 x坐标 排序
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(int argc, const char** argv)
{
system("color 1F");
g_srcImage = imread("1.jpg", 1);
//灰度 降低计算量
cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);
//高斯滤波 降噪
GaussianBlur(g_grayImage, g_grayImage, Size(7, 7), 0);
imshow("高斯滤波", g_grayImage);
//边缘检测
Canny(g_grayImage, g_grayImage, 50,100);
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); //隔开物体
dilate(g_grayImage, g_grayImage, element);//膨胀
erode(g_grayImage, g_grayImage, element);//腐蚀
imshow("形态学", g_grayImage);
//寻找轮廓
findContours(g_grayImage, g_vContours, g_vHierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
std::sort(g_vContours.begin(),g_vContours.end(), ContoursSortFun);//按照从左到右 排序
for (unsigned i = 0; i < g_vContours.size(); i++) {
if (contourArea(g_vContours[i]) < 100)//面积太小 则忽略
continue;
RotatedRect box = minAreaRect(g_vContours[i]);
Point2f boxPoints[4];
box.points(boxPoints);
Point2f pointA = midpoint(boxPoints[0], boxPoints[1]);
Point2f pointB = midpoint(boxPoints[1], boxPoints[2]);
Point2f pointC = midpoint(boxPoints[2], boxPoints[3]);
Point2f pointD = midpoint(boxPoints[3], boxPoints[0]);
circle(g_srcImage, pointA, 2, Scalar(0, 0, 255));
circle(g_srcImage, pointB, 2, Scalar(0, 0, 255));
circle(g_srcImage, pointC, 2, Scalar(0, 0, 255));
circle(g_srcImage, pointD, 2, Scalar(0, 0, 255));
line(g_srcImage, pointA, pointC, Scalar(255, 0, 0));
line(g_srcImage, pointD, pointB, Scalar(255, 0, 0));
double dWidth = getDistance(pointA, pointC);
double dHeight = getDistance(pointD, pointB);
if (g_bFirst) {
g_dPixelsPerMetric = dWidth/g_dReferWidth; //计算像素与 实际大小的比列
cout << "pixelPerMetric:" << dWidth <<" "<< g_dReferWidth <<" "<< g_dPixelsPerMetric;
g_bFirst = false;
}
cout << "dWidth" << dWidth <<" "<< dHeight<< " "< contour1, vector contour2) {
return (contour1[0].x
四,效果
参考:https://blog.csdn.net/happyjacob/article/details/81055275