废话不多说,直接上栗子!
1.边缘检测、轮廓查找、轮廓筛选、绘制最小外接矩、尺寸测量和标注尺寸,代码如下:
//开发环境:VS2015+OPENCV3.2
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
#define PHY_LEN 72.0 //参照物较长边边长的物理长度
//文本绘制
void PaintText(Mat& img, char* text, Point origin)
{
int fontface = CV_FONT_HERSHEY_SIMPLEX; //字体
double fontscale = 0.5; //尺寸因子,值越大文字越大
Scalar textcolor = Scalar(0, 0, 255); //文本颜色
int thickness = 2; //线宽
int linetype = 8; //线型
//int baseline;
////获取文本框的长宽
//Size text_size = getTextSize(text, fontface, fontscale, thickness, &baseline);
putText(img, text, origin, fontface, fontscale, textcolor, thickness, linetype);
}
void fineMinAreaRect(Mat &threshold_output, Mat &src)
{
bool flag = false; //查找比例尺标志
double pp = 0.0; //比例因子:每像素代表的实际物理尺寸
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
//寻找轮廓,输入必须为二值图像
findContours(threshold_output, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point(0, 0)); //CV_CHAIN_APPROX_SIMPLE
//第一轮筛选:移除过短的轮廓
int cmin = 100; //最小轮廓长度
int cmax = 5000; //最大轮廓长度
vector<vector<Point>>::const_iterator itc = contours.begin();
while (itc != contours.end())
{
if (itc->size() < cmin || itc->size() > cmax)
itc = contours.erase(itc);
else
++itc;
}
//第二轮筛选:剔除面积小于指定阈值的轮廓
//计算轮廓的面积
for (int i = 0; i < (int)contours.size(); i++)
{
double g_dConArea = fabs(contourArea(contours[i], true));
cout << "轮廓面积: " << g_dConArea << endl;
}
//剔除小面积轮廓
//vector <vector<Point>>::const_iterator itc = contours.begin();
itc = contours.begin();
for (; itc != contours.end();)
{
double g_dConArea = contourArea(*itc);
if (g_dConArea < 200)
{
itc = contours.erase(itc);
}
else
{
++itc;
}
}
//对每个找到的轮廓创建可倾斜的边界框
vector<RotatedRect> minRect(contours.size());
for (int i = 0; i < contours.size(); i++)
{
minRect[i] = minAreaRect(Mat(contours[i]));
}
//绘出轮廓及其可倾斜的边界框
//Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
//先遍历寻找参照物,计算出比例因子
for (int i = 0; i < contours.size(); i++)
{
Point2f rect_points[4];
minRect[i].points(rect_points);
//寻找比例尺,四顶点均位于左半图
if (!flag && rect_points[0].x < src.cols / 2 && rect_points[1].x < src.cols / 2 && rect_p