#include "stdafx.h" #include "StructuralAnalysisAndShapeDescriptors.h" using namespace cv; StructuralAnalysisAndShapeDescriptors::StructuralAnalysisAndShapeDescriptors() { } StructuralAnalysisAndShapeDescriptors::~StructuralAnalysisAndShapeDescriptors() { } void StructuralAnalysisAndShapeDescriptors::OpenCV_approxPolyDP(Mat &src) { // 用指点的精度近似一个多边形 // epsilon 的值越大,越接近多边形,越小越接近于圆 Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<std::vector<Point>> contoursDst; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_SIMPLE); contoursDst.resize(contours.size()); int k = 0; for (; k < contours.size(); k++) { approxPolyDP(Mat(contours[k]), contoursDst[k], 0.1, true); } for (k = 0; k < contoursDst.size(); k++) { drawContours(src, contoursDst, k, Scalar(0, 255, 0), 1, LineTypes::LINE_8, hierarchy); } imwrite("polylines.jpg", src); } void StructuralAnalysisAndShapeDescriptors::OpenCV_arcLength(Mat &src) { Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_NONE); for (int k = 0; k < contours.size(); k++) { polylines(src, contours[k], false, Scalar(0, 0, 255)); } imwrite("polylines.jpg", src); } void StructuralAnalysisAndShapeDescriptors::OpenCV_boundingRect(Mat &src) { // 获取最大外接矩形 // points 输入的点 std::vector<Point> pt(10); for (int i = 0; i < 10; i++) { pt[i] = (Point((rand() &600), (rand() & 500))); drawMarker(src, pt[i], Scalar(255, 255, 255), MarkerTypes::MARKER_CROSS, 20, 5); } //Rect rect = boundingRect(Mat(pt)); Rect rect = boundingRect(pt); rectangle(src, rect, Scalar(0, 0, 255)); imwrite("OpenCV_boundingRect.jpg", src); } void StructuralAnalysisAndShapeDescriptors::OpenCV_boxPoints(Mat &src) { // 绘制旋转矩形 RotatedRect rRect = RotatedRect(Point2f(300, 300), Size2f(100, 200), 30); //ellipse(src, rRect, Scalar(0, 255, 0)); Mat mat; Point2f pt[4]; rRect.points(pt); // boxPoints 这个函数封装有错误,这里直接调用 rRect.points(pt)就可以得到旋转矩形的四个顶点 // 然后通过画首尾相连的线就可以绘制出旋转矩形了 for (int r = 0; r < 4; r++) { line(src, pt[r], pt[(r + 1)%4], Scalar(0, 0, 255)); } imwrite("boxPoints_Rect.jpg", src); } void StructuralAnalysisAndShapeDescriptors::OpenCV_connectedComponents(Mat &src) { Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; int iNum = connectedComponents(edgeMat, labels, 8, CV_32S); normalize(labels, labels, 255); imwrite("normalize.jpg", labels); printf("%d", iNum); std::vector<Vec3b>colors(iNum); colors[0] = Vec3b(0, 0, 0); // 背景颜色 // 生成随机颜色表,用来标记每个连通域 for (int i = 1; i < iNum; i++) { colors[i] = Vec3b((rand() & 255), (rand() & 255), (rand() & 255)); } Mat dst = Mat(src.size(), CV_8UC3); for (int r = 0; r < dst.rows; r++) { for (int c = 0; c < dst.cols; c++) { int label = labels.at<int>(r, c); Vec3b &pix = dst.at<Vec3b>(r, c); pix = colors[label]; } } imwrite("boxPoints_Rect.jpg", dst); } void StructuralAnalysisAndShapeDescriptors::OpenCV_connectedComponentsWithStats() { } void StructuralAnalysisAndShapeDescriptors::OpenCV_contourArea(Mat &src) { Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_NONE); for (int k = 0; k < contours.size(); k++) { double dArea = contourArea(contours[k]); printf("%lf\r\n", dArea); } } void StructuralAnalysisAndShapeDescriptors::OpenCV_convexHull(Mat &src) { Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_NONE); std::vector<Point> hull; for (int k = 0; k < contours.size(); k++) { double dArea = contourArea(contours[k]); convexHull(contours[k], hull); int iNum = (int)hull.size(); for (int i =0; i < iNum; i++) { if (i %3 == 0) { line(src, hull[i], hull[(i + 1) % iNum], Scalar(0, 255, 0)); } } imwrite("OpenCV_convexHull.jpg", src); } } void StructuralAnalysisAndShapeDescriptors::OpenCV_convexityDefects(Mat &src) { Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_NONE); std::vector<std::vector<Point> >hull(contours.size()); // Int type hull std::vector<std::vector<int>> hullsI(contours.size()); // Convexity defects std::vector<std::vector<Vec4i>> defects(contours.size()); for (size_t i = 0; i < contours.size(); i++) { convexHull(Mat(contours[i]), hull[i], false); // find int type hull convexHull(Mat(contours[i]), hullsI[i], false); // get convexity defects convexityDefects(Mat(contours[i]), hullsI[i], defects[i]); } } void StructuralAnalysisAndShapeDescriptors::OpenCV_findContours(Mat src, Mat &dst) { Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat,labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_NONE); for (int k = 0; k >= 0; k= hierarchy[k][3]) { drawContours(src, contours, k, Scalar(0, 255, 0), FILLED, LineTypes::LINE_4, hierarchy); //rectangle(_src, boundingRect(contours[k]), Scalar(0, 0, 255)); } dst = src; imwrite("rect.jpg", src); imshow("drawContours", src); } void StructuralAnalysisAndShapeDescriptors::OpenCV_fitEllipse(Mat &src) { std::vector<Point> pt(10); for (int i =0; i < 10; i++) { pt[i] = Point(rand()&200,rand()&300); } RotatedRect rRect = fitEllipse(pt); ellipse(src, rRect, Scalar(0, 255, 0),2); imwrite("fitEllipse.jpg", src); } void StructuralAnalysisAndShapeDescriptors::OpenCV_fitLine(Mat &src) { std::vector<Point> pt(10); Vec4f vec; for (int i = 0; i < 10; i++) { pt[i] = Point(rand() & 400, rand() & 200); } for (int j = 0; j < 10; j++) { drawMarker(src, pt[j], Scalar(0, 0, 255)); } fitLine(pt, vec,DistanceTypes::DIST_L2,0,10,0.01); Point ptOri; ptOri.x = vec[2]; ptOri.y = vec[3]; double K = vec[1] / vec[0]; Point pt1, pt2; pt1.x = 0; pt1.y = K *(pt1.x - ptOri.x) + ptOri.y; pt2.x = src.cols; pt2.y = K *(pt2.x - ptOri.x) + ptOri.y; line(src, pt1, pt2, Scalar(0, 0, 255),2); imwrite("fitLine.jpg", src); } void StructuralAnalysisAndShapeDescriptors::OpenCV_HuMoments(Mat &src) { // 通过hu矩,可以计算轮廓的相似度,hu矩的第一个值越接近,相似度越高。 Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_NONE); double hu[7]; for (int k = 0; k < contours.size(); k++) { Moments mem = moments(contours[k]); //HuMoments(mem, hu); printf(" mem.m00: %lf,\r\n mem.m10: %lf,\r\n mem.m01: %lf,\r\n mem.m20: %lf,\r\n mem.m11: %lf,\r\n mem.m02: %lf, mem.m30: %lf,\r\n mem.m21: %lf,\r\n mem.m12: %lf,\r\n mem.m03: %lf\r\n", mem.m00, mem.m10, mem.m01, mem.m20, mem.m11, mem.m02, mem.m30, mem.m21, mem.m12, mem.m03); double dArea = contourArea(contours[k]); printf(" Area: %lf\r\n", dArea); HuMoments(mem, hu); printf(" hu[0]: %lf,\r\n hu[1]: %lf,\r\n hu[2]: %lf,\r\n hu[3]: %lf,\r\n hu[4]: %lf,\r\n hu[5]: %lf,\r\n hu[6]: %lf,\r\n", hu[0], hu[1], hu[2], hu[3], hu[4], hu[5], hu[6]); //for (int i = 0; i < 7; i++) //{ // //} getchar(); } } void StructuralAnalysisAndShapeDescriptors::OpenCV_intersectConvexConvex(Mat &src) { std::vector<Point> pt1(4), pt2(4), pt12; pt1[0] = Point(80, 150); pt1[1] = Point(200, 150); pt1[3] = Point(80, 300); pt1[2] = Point(200, 300); pt2[0] = Point(80, 150); pt2[1] = Point(200, 150); pt2[3] = Point(80,300); pt2[2] = Point(200, 300); // 这里的返回值 i 就代表交集区域轮廓的周长 float i = intersectConvexConvex(pt1, pt2, pt12); for (int j = 0; j < pt1.size(); j++) { line(src, pt1[j], pt1[(j + 1) % 4], Scalar(0, 255, 0)); } for (int j = 0; j < pt2.size(); j++) { line(src, pt2[j], pt2[(j + 1) % 4], Scalar(255, 0, 0)); } for (int j =0; j < pt12.size(); j++) { line(src, pt12[j], pt12[(j + 1) % 4], Scalar(0, 0, 255)); printf("x: %d, y: %d\r\n", pt12[j].x, pt12[j].y); } imwrite("intersectConvexConvex.jpg", src); getchar(); } void StructuralAnalysisAndShapeDescriptors::OpenCV_isContourConvex(Mat &src) { std::vector<Point> pt1(4), pt2(4), pt12; pt1[0] = Point(80, 150); pt1[1] = Point(200, 150); pt1[3] = Point(80, 300); pt1[2] = Point(200, 300); pt2[0] = Point(80, 150); pt2[1] = Point(200, 150); pt2[3] = Point(80, 300); pt2[2] = Point(200, 300); // 这里的返回值 i 就代表交集区域轮廓的周长 float i = intersectConvexConvex(pt1, pt2, pt12); for (int j = 0; j < pt1.size(); j++) { line(src, pt1[j], pt1[(j + 1) % 4], Scalar(0, 255, 0)); } for (int j = 0; j < pt2.size(); j++) { line(src, pt2[j], pt2[(j + 1) % 4], Scalar(255, 0, 0)); } bool b = isContourConvex(pt12); if (b) { printf("Is Contour Convex"); } imwrite("intersectConvexConvex.jpg", src); getchar(); } void StructuralAnalysisAndShapeDescriptors::OpenCV_matchShapes(Mat &src) { std::vector<Point> pt1(4), pt2(4), pt12; pt1[0] = Point(60, 60); pt1[1] = Point(200, 60); pt1[2] = Point(200, 300); pt1[3] = Point(200, 300); pt2[0] = Point(80, 150); pt2[1] = Point(200, 150); pt2[3] = Point(80, 300); pt2[2] = Point(200, 300); // 这里的返回值 i 就代表交集区域轮廓的周长 float i = intersectConvexConvex(pt1, pt2, pt12); for (int j = 0; j < pt1.size(); j++) { line(src, pt1[j], pt1[(j + 1) % 4], Scalar(0, 255, 0)); } for (int j = 0; j < pt2.size(); j++) { line(src, pt2[j], pt2[(j + 1) % 4], Scalar(255, 0, 0)); } for (int j = 0; j < pt12.size(); j++) { line(src, pt12[j], pt12[(j + 1) % pt12.size()], Scalar(0, 0, 255)); printf("x: %d, y: %d\r\n", pt12[j].x, pt12[j].y); } // 返回值越大,说明两个轮廓的相似度越低 double d = matchShapes(pt1, pt2, ShapeMatchModes::CONTOURS_MATCH_I1, 0); imwrite("intersectConvexConvex.jpg", src); printf("d: %lf", d); getchar(); } void StructuralAnalysisAndShapeDescriptors::OpenCV_minAreaRect(Mat &src) { std::vector<Point> pt1(4), pt2(4), pt12; pt1[0] = Point(60, 60); pt1[1] = Point(200, 60); pt1[2] = Point(200, 300); pt1[3] = Point(200, 300); pt2[0] = Point(80, 150); pt2[1] = Point(200, 150); pt2[3] = Point(80, 300); pt2[2] = Point(200, 300); // 这里的返回值 i 就代表交集区域轮廓的周长 float i = intersectConvexConvex(pt1, pt2, pt12); for (int j = 0; j < pt1.size(); j++) { line(src, pt1[j], pt1[(j + 1) % 4], Scalar(0, 255, 0)); } for (int j = 0; j < pt2.size(); j++) { line(src, pt2[j], pt2[(j + 1) % 4], Scalar(255, 0, 0)); } for (int j = 0; j < pt12.size(); j++) { line(src, pt12[j], pt12[(j + 1) % pt12.size()], Scalar(0, 0, 255)); printf("x: %d, y: %d\r\n", pt12[j].x, pt12[j].y); } RotatedRect rRect = minAreaRect(pt12); Point2f pt[4]; rRect.points(pt); for (int j = 0; j < 4; j++) { line(src, pt[j], pt[(j + 1) % 4], Scalar(0, 0, 255)); printf("x: %lf, y: %lf\r\n", pt[j].x, pt[j].y); } imwrite("intersectConvexConvex.jpg", src); getchar(); } void StructuralAnalysisAndShapeDescriptors::OpenCV_minEnclosingCircle(Mat &src) { std::vector<Point> pt1(4), pt2(4), pt12; pt1[0] = Point(60, 60); pt1[1] = Point(200, 60); pt1[2] = Point(200, 300); pt1[3] = Point(200, 300); pt2[0] = Point(80, 150); pt2[1] = Point(200, 150); pt2[3] = Point(80, 300); pt2[2] = Point(200, 300); // 这里的返回值 i 就代表交集区域轮廓的周长 float i = intersectConvexConvex(pt1, pt2, pt12); for (int j = 0; j < pt1.size(); j++) { line(src, pt1[j], pt1[(j + 1) % 4], Scalar(0, 255, 0)); } for (int j = 0; j < pt2.size(); j++) { line(src, pt2[j], pt2[(j + 1) % 4], Scalar(255, 0, 0)); } for (int j = 0; j < pt12.size(); j++) { line(src, pt12[j], pt12[(j + 1) % pt12.size()], Scalar(0, 0, 255)); printf("x: %d, y: %d\r\n", pt12[j].x, pt12[j].y); } Point2f pCenter; float r; // 获取点集的外接圆圆心和半径 minEnclosingCircle(pt12, pCenter, r); circle(src, pCenter, r, Scalar(255, 0, 255)); printf("x: %f, y: %f, R: %f\r\n", pCenter.x, pCenter.y, r); imwrite("intersectConvexConvex.jpg", src); getchar(); } void StructuralAnalysisAndShapeDescriptors::OpenCV_minEnclosingTriangle(Mat &src) { std::vector<Point> pt1(4), pt2(4), pt12; pt1[0] = Point(60, 60); pt1[1] = Point(200, 60); pt1[2] = Point(200, 300); pt1[3] = Point(200, 300); pt2[0] = Point(80, 150); pt2[1] = Point(200, 150); pt2[3] = Point(80, 300); pt2[2] = Point(200, 300); // 这里的返回值 i 就代表交集区域轮廓的周长 float i = intersectConvexConvex(pt1, pt2, pt12); for (int j = 0; j < pt1.size(); j++) { line(src, pt1[j], pt1[(j + 1) % 4], Scalar(0, 255, 0)); } for (int j = 0; j < pt2.size(); j++) { line(src, pt2[j], pt2[(j + 1) % 4], Scalar(255, 0, 0)); } for (int j = 0; j < pt12.size(); j++) { line(src, pt12[j], pt12[(j + 1) % pt12.size()], Scalar(0, 0, 255)); printf("x: %d, y: %d\r\n", pt12[j].x, pt12[j].y); } std::vector<Point> ptTriangle; // 获取外接三角形的三个顶点 minEnclosingTriangle(pt12, ptTriangle); for (int j = 0; j < ptTriangle.size(); j++) { line(src, ptTriangle[j], ptTriangle[(j + 1) % ptTriangle.size()], Scalar(255, 255, 255)); printf("x: %d, y: %d\r\n", ptTriangle[j].x, ptTriangle[j].y); } imwrite("intersectConvexConvex.jpg", src); getchar(); } void StructuralAnalysisAndShapeDescriptors::OpenCV_moments(Mat &src) { // 通过矩,可以计算轮廓的中心、面积等信息。 Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_NONE); double hu[7]; for (int k = 0; k < contours.size(); k++) { Moments mem = moments(contours[k]); //HuMoments(mem, hu); printf(" mem.m00: %lf,\r\n mem.m10: %lf,\r\n mem.m01: %lf,\r\n mem.m20: %lf,\r\n mem.m11: %lf,\r\n mem.m02: %lf, mem.m30: %lf,\r\n mem.m21: %lf,\r\n mem.m12: %lf,\r\n mem.m03: %lf\r\n", mem.m00, mem.m10, mem.m01, mem.m20, mem.m11, mem.m02, mem.m30, mem.m21, mem.m12, mem.m03); double dArea = contourArea(contours[k]); printf(" Area: %lf\r\n", dArea); getchar(); } } void StructuralAnalysisAndShapeDescriptors::OpenCV_pointPolygonTest(Mat &src) { Mat _src; cvtColor(src, _src, CV_BGR2GRAY); Mat blurMat, edgeMat, labels; GaussianBlur(_src, blurMat, Size(3, 3), 0.8); Canny(blurMat, edgeMat, 70, 155); std::vector<std::vector<Point>> contours; std::vector<Vec4i>hierarchy; findContours(edgeMat, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_NONE); Point2f pCenter(_src.cols / 2,_src.rows/2); for (int k = 0; k < contours.size(); k++) { // 返回值 0 代表在轮廓上 // -1 代表在轮廓外 // 1 代表在轮廓内 double d = pointPolygonTest(contours[k], pCenter, false); printf("d: %lf\r\n", d); getchar(); } imwrite("intersectConvexConvex.jpg", src); } void StructuralAnalysisAndShapeDescriptors::OpenCV_rotatedRectangleIntersection(Mat &src) { // 返回两个旋转矩形的的所有交点 // 如果只是返回两个旋转矩形的所有交点,不绘制相交区域,可以调用函数 // rotatedRectangleIntersection 得到交点坐标。 // 返回值代表相交区域的个数 // 如果要绘制相交区域,建议使用intersectConvexConvex函数, // 得到有序的交点坐标,便于标记相交区域 RotatedRect rRect1 = RotatedRect(Point2f(200, 200), Size2f(100, 100), 30); RotatedRect rRect2 = RotatedRect(Point2f(250, 250), Size2f(200, 200), 90); std::vector vectorpt1(4), vectorpt2(4), pt,ptApproch; Point2f pt1[4]; rRect1.points(pt1); for (int j = 0; j < 4; j++) { vectorpt1[j] = pt1[j]; line(src, pt1[j], pt1[(j + 1) % 4], Scalar(0, 255, 0)); } Point2f pt2[4]; rRect2.points(pt2); for (int j = 0; j < 4; j++) { vectorpt2[j] = pt2[j]; line(src, pt2[j], pt2[(j + 1) % 4], Scalar(255, 0, 0)); } float f = intersectConvexConvex(vectorpt1, vectorpt2, pt); for (int j =0; j < pt.size(); j++) { line(src, pt[j], pt[(j + 1) % pt.size()], Scalar(125, 125, 255)); } imwrite("intersectConvexConvex.jpg", src); printf("f: %f\r\n", f); getchar(); }
Opencv moment contours PointTest
最新推荐文章于 2024-09-10 17:47:11 发布
本文详细介绍了OpenCV库中用于轮廓检测、矩计算的相关函数,包括approxPolyDP、arcLength、boundingRect、boxPoints、connectedComponents等,通过实例展示了如何使用这些函数进行图像分析和形状描述。
摘要由CSDN通过智能技术生成