轮廓逼近:指用越来越多的多边形对轮廓进行拟合,从而获得与轮廓近似的多边形,并获取多边形的形状。目的是为了减少编码点
拟合:生成最相似的圆或多边形。
API:
void cv::approxPolyDP ( InputArray curve, OutputArray approxCurve, double epsilon, bool closed )
epsilon——逼近精度,一般选4.
closed ——是否选用封闭轮廓
RotatedRect cv::fitEllipse ( InputArray points )
只能获取到多边形的边数,可以使用result.rows调用出边数。
获取拟合多边形的边数:
void QuickDemo::contour_neighbor(Mat& image)
{
GaussianBlur(image, image, Size(3,3),0);
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
Mat binary;
threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
namedWindow("THRESH_OTSU", WINDOW_FREERATIO);
imshow("THRESH_OTSU", binary);
vector> contours;
vector hierachy;
findContours(binary, contours, hierachy, RETR_EXTERNAL,CHAIN_APPROX_SIMPLE,Point());
cout << contours.size() << endl;
RNG rng(12345);
string word = "some::";
//多边形逼近
for (size_t t = 0; t < contours.size(); ++t) {
Mat result;
approxPolyDP(contours[t], result, 4, true);
cout << result.rows << "," << result.cols << endl;
//利用几何矩找到轮廓中心位置
Moments mm = moments(contours[t]);
double cx = mm.m10 / mm.m00;
double cy = mm.m01 / mm.m00;
circle(image, Point(cx, cy), 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8);
putText(image, word + (char)rng.uniform(65,90)+ (char)rng.uniform(65, 90), Point(cx-100, cy - 100), FONT_HERSHEY_PLAIN, 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, 8);
double area = contourArea(contours[t]);//面积
double clen = arcLength(contours[t],false);//周长
drawContours(image, contours, t, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8);
}
namedWindow("image", WINDOW_FREERATIO);
imshow("image", image);
}
拟合圆、椭圆:
void QuickDemo::image_fit(Mat& image)
{
GaussianBlur(image, image, Size(3, 3), 0);
Mat gray;
cvtColor(image, gray, COLOR_BGR2GRAY);
Mat binary;
threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
namedWindow("THRESH_OTSU", WINDOW_FREERATIO);
imshow("THRESH_OTSU", binary);
vector> contours;
vector hierachy;
findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
cout << contours.size() << endl;
RNG rng(12345);
string word = "some::";
//拟合圆/椭圆
for (size_t t = 0; t < contours.size(); ++t) {
drawContours(image, contours, t, Scalar(rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8);
RotatedRect rrt = fitEllipse(contours[t]);
float w = rrt.size.width;
float h = rrt.size.height;
Point center = rrt.center;
circle(image, center, 10, Scalar(rng.uniform(0, 255), rng.uniform(0, 255)), 3, 8);
ellipse(image, rrt, Scalar(rng.uniform(0, 255), rng.uniform(0, 255)), 2, 8);
}
namedWindow("fit result", WINDOW_FREERATIO);
imshow("fit result", image);
}