【opencv3.4.1基本图像轮廓提取与描述备忘录】

经典博文:https://www.jianshu.com/p/ef5ca683c005

                  https://www.cnblogs.com/mikewolf2002/p/3427079.html

                  https://blog.csdn.net/qq_18343569/article/details/48000179 

 http://blog.sina.com.cn/s/blog_8fc98fe501017ypb.html

                  https://blog.csdn.net/yansmile1/article/details/50261527   

终极参考链接:https://blog.csdn.net/dcrmg/article/details/51987348#comments 与

  • //rectPoint变量中得到了矩形的四个顶点坐标

  • RotatedRect rectPoint = minAreaRect(points);

  • //定义一个存储以上四个点的坐标的变量

  • Point2f fourPoint2f[4];

  • //将rectPoint变量中存储的坐标值放到 fourPoint的数组中

  • rectPoint.points(fourPoint2f);

  • https://blog.csdn.net/qq_23880193/article/details/49257529?utm_source=copy(个人认是迄今见到最为深入浅出全面的一个帖子-必看)

在OpenCV中,能够很方便的求轮廓包围盒。包括矩形,圆形,椭圆形以及倾斜的矩形(包围面积最小)集中包围盒。用到的四个函数是:

1. Rect boundingRect(InputArray points)

2. void minEnclosingCircle(InputArray points, Point2f& center, float& radius)

3. RotatedRect minAreaRect(InputArray points)

4. RotatedRect fitEllipse(InputArray points)

这四个函数比较容易混淆,这里对其进行总结:


OpenCV求包覆矩形

Rect boundingRect(InputArray points)

  • points:輸入資訊,可以為包含點的容器(vector)或是Mat。
  • 返回包覆輸入資訊的最小正矩形。

OpenCV求包覆矩形

RotatedRect minAreaRect(InputArray points)

  • points:輸入資訊,可以為包含點的容器(vector)或是Mat。
  • 返回包覆輸入資訊的最小斜矩形

OpenCV求包覆圓形

void minEnclosingCircle(InputArray points, Point2f& center, float& radius)

  • points:輸入資訊,可以為包含點的容器(vector)或是Mat。
  • center:包覆圓形的圓心。
  • radius:包覆圓形的半徑。

boundingRect()函数的使用方法

Calculates the up-right bounding rectangle of a point set.

C++: Rect boundingRect(InputArray points)

Parameters: points – Input 2D point set, stored in std::vector or Mat.    

注意:(boundingRect读入的参数必须是vector或者Mat点集)

使用例程:

for( size_t k = 0; k < contours.size(); k++ )

    {

    Rect ret1=boundingRect(Mat(contours[k]));//计算右上点集的边界矩形

    avgX = (ret1.x + ret1.x + ret1.width)/2; //运动物体的矩形的中点X位置

    avgY = (ret1.y + ret1.y + ret1.height)/2;//运动物体的矩形的中点Y位置

    cout<<"x:"<<avgX<<"y:"<<avgY<<endl;

     }

RotatedRect

class RotatedRect

class CV_EXPORTS RotatedRect
{
public:
    //! various constructors
    RotatedRect();
    RotatedRect(const Point2f& center, const Size2f& size, float angle);
    RotatedRect(const CvBox2D& box);

    //! returns 4 vertices of the rectangle
    void points(Point2f pts[]) const;
    //! returns the minimal up-right rectangle containing the rotated rectangle
    Rect boundingRect() const;
    //! conversion to the old-style CvBox2D structure
    operator CvBox2D() const;

    Point2f center; //< the rectangle mass center
    Size2f size;    //< width and height of the rectangle
    float angle;    //< the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
};

The class represents rotated (i.e. not up-right) rectangles on a plane. Each rectangle is specified by the center point (mass center), length of each side (represented by cv::Size2f structure) and the rotation angle in degrees.

C++: RotatedRect::RotatedRect()

C++: RotatedRect::RotatedRect(const Point2f& center, const Size2f& size, float angle)

C++: RotatedRect::RotatedRect(const CvBox2D& box)

Parameters:
  • center – The rectangle mass center.
  • size – Width and height of the rectangle.
  • angle – The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
  • box – The rotated rectangle parameters as the obsolete CvBox2D structure.

C++: void RotatedRect::points(Point2f pts[]) const //! returns 4 vertices of the rectangle

C++: Rect RotatedRect::boundingRect() const

C++: RotatedRect::operator CvBox2D() const

Parameters:
  • pts – The points array for storing rectangle vertices.
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

Mat src; Mat src_gray;
int thresh = 221;
int max_thresh = 255;
RNG rng(12345);

/// Function header
void thresh_callback(int, void*);

/** @function main */
int main(int argc, char** argv)
{
	/// 加载源图像
	src = imread("123.jpg", 1);
	resize(src, src, Size(512, 512));
	/// 转为灰度图并模糊化
	cvtColor(src, src_gray, CV_BGR2GRAY);
	blur(src_gray, src_gray, Size(3, 3));

	/// 创建窗体
	char* source_window = "Source";
	namedWindow(source_window, CV_WINDOW_AUTOSIZE);
	imshow(source_window, src);

	createTrackbar(" Threshold:", "Source", &thresh, max_thresh, thresh_callback);
	thresh_callback(0, 0);

	waitKey(0);
	return(0);
}

/** @function thresh_callback */
void thresh_callback(int, void*)
{
	Mat threshold_output;
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;

	/// 阈值化检测边界
	threshold(src_gray, threshold_output, thresh, 255, THRESH_BINARY);
	/// 寻找轮廓
	findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

	/// 对每个找到的轮廓创建可倾斜的边界框和椭圆
	vector<RotatedRect> minRect(contours.size());
	//vector<RotatedRect> minEllipse(contours.size());

	for (int i = 0; i < contours.size(); i++)
	{
		minRect[i] = minAreaRect(Mat(contours[i]));
		/*if (contours[i].size() > 5)
		{
			minEllipse[i] = fitEllipse(Mat(contours[i]));
		}*/
	}
	
	/// 绘出轮廓及其可倾斜的边界框和边界椭圆
	Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
	for (int i = 0; i< contours.size(); i++)
	{

        //rectPoint变量中得到了矩形的四个顶点坐标	
     	//RotatedRect rectPoint = minAreaRect(points);//定义一个存储以上四个点的坐标的变量		
        // Point2f fourPoint2f[4];	
     	//将rectPoint变量中存储的坐标值放到 fourPoint的数组中		
       // rectPoint.points(fourPoint2f);

		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		// contour
		drawContours(drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point());
	
		
		// rotated rectangle
		Point2f rect_points[4]; minRect[i].points(rect_points);
		for (int j = 0; j < 4; j++) {
			line(drawing, rect_points[j], rect_points[(j + 1) % 4], color, 1, 8);
			cout << rect_points[j].x <<" "<< rect_points[j].y << endl;
		}

	}

	/// 结果在窗体中显示
	namedWindow("Contours", CV_WINDOW_AUTOSIZE);
	imshow("Contours", drawing);
}

最终结果:

猜你喜欢

转载自blog.csdn.net/qq_35054151/article/details/82563074