C++OpenCV系统学习(19)——轮廓周围绘制矩形和圆形框

1.轮廓周围绘制矩形和园

1.1绘制矩形和圆概述

在图像外侧绘制最小矩形。基于RDP算法实现,目的是减少多边形轮廓的点数,加快运算效率,对图像轮廓点拟合多边形;该函数用另一条曲线或具有较少顶点的多边形逼近曲线或多边形,使它们之间的距离小于或等于指定的精度;

1.2绘制矩形API

void approxPolyDP(InputArray curve,
    OutputArray approxCurve,
    double epsilon,
    bool closed)
第一个参数,InputArray curve,一般是由图像的轮廓点组成的点集;
第二个参数,OutputArray approxCurve,表示输出的多边形点集;
第一个参数,double epsilon,主要表示输出的精度;这是原始曲线与其近似之间的最大距离;
第二个参数,bool closed,表示输出的多边形是否封闭;true表示封闭,false表示不封闭;

1.3绘制不同的矩形API

  • cv::boundingRect(inputArray points)得到轮廓周围最小矩形左上交点坐标和右下交点坐标,绘制一个矩形
  • cv::minAreaRect(inputArray points)得到一个旋转的矩形,返回旋转矩形

1.4轮廓周围绘制圆和椭圆API

cv::minEnclosingCircle(inputArray points,//得到最小区域圆形

Pointsf& center,//圆心位置
float& radius//圆半径
)

cv::fitEllipse(inputArray points)//得到最小椭圆

1.5算法流程

  1. 首先将图像变为二值图像
  2. 发现轮廓找到图像轮廓
  3. 通过相关API在轮廓点上找到最小包含矩形和圆,旋转矩形与椭圆
  4. 绘制他们

2.案例分析

第一步:createTrabar调节二值化阈值得到二值化图像:

#include <opencv2 opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

Mat src, gray_src, drawImg;
int threshold_v = 170;
int threshold_max = 255;
const char* output_win = "rectangle-demo";
const char* source_win = "input_image";
RNG rng(12345);
void Contours_Callback(int, void*);

int main(int argc, const char* argv[])
{
    src = imread("F:/testImage/qiqiu.png");
    if (src.empty()) {
        printf("could not load image...\n");
        return -1;
    }
    //namedWindow("input", WINDOW_AUTOSIZE);
    //imshow("input", src);
    cvtColor(src, gray_src, COLOR_BGR2GRAY);
    blur(gray_src, gray_src, Size(3, 3), Point(-1, -1));
    namedWindow(source_win, WINDOW_AUTOSIZE);
    namedWindow(output_win, WINDOW_AUTOSIZE);
    imshow(source_win, src);

    createTrackbar("Threshold Value:", output_win, &threshold_v, threshold_max, Contours_Callback);
    Contours_Callback(0, 0);

    waitKey(0);
    return 0;
}

void Contours_Callback(int, void*)
{
    Mat binary_output;
    vector<vector<point>>contours;
    vector<vec4i>hierachy;
    threshold(gray_src, binary_output, threshold_v, threshold_max, THRESH_BINARY);
    imshow(output_win, binary_output);
    findContours(binary_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1));

}</vec4i></vector<point></iostream></opencv2>

C++OpenCV系统学习(19)——轮廓周围绘制矩形和圆形框

3.完整程序

#include<opencv2 opencv.hpp>
#include<iostream>
#include"myApi.h"
#include<math.h>

using namespace cv;
using namespace std;

Mat src, gray_src, drawImg;
int threshold_v = 170;
int threshold_max = 255;
const char* output_win = "rectangle_demo";
const char* source_win = "input_image";
RNG rng(12345);
void Contours_Callback(int, void*);

int main(int argc, char** argv)
{
    Mat src = imread("F:/testImage/qiqiu.png");
    if (!src.data)
    {
        cout << "&#x56FE;&#x7247;&#x6CA1;&#x6709;&#x627E;&#x5230;" << endl;
        return -1;
    }
    imshow("src", src);

    /*Mat gray;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    imshow("gray", gray);

    Mat precess_img = preprocessImg(gray);
    imshow("precess_img", precess_img);*/

    cvtColor(src, gray_src, COLOR_BGR2GRAY);
    blur(gray_src, gray_src, Size(3, 3), Point(-1, -1));
    namedWindow(source_win, WINDOW_AUTOSIZE);
    namedWindow(output_win, WINDOW_AUTOSIZE);
    imshow(source_win, src);

    createTrackbar("Threshold Value:", output_win, &threshold_v, threshold_max, Contours_Callback);
    Contours_Callback(0, 0);

    waitKey(0);
    return 0;
}

void Contours_Callback(int, void*)
{
    Mat binary_output;
    vector<vector<point>>contours;
    vector<vec4i>hierachy;
    threshold(gray_src, binary_output, threshold_v, threshold_max, THRESH_BINARY);
    //imshow(output_win, binary_output);
    findContours(binary_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1));

    // &#x627E;&#x5230;&#x4E0B;&#x9762;&#x53C2;&#x6570;
    vector<vector<point>> contour_ploy(contours.size());  //&#x627E;&#x5916;&#x63A5;&#x591A;&#x8FB9;&#x5F62;,(contours.size())&#x8868;&#x793A;&#x5BF9;&#x53C2;&#x6570;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;
    vector<rect> ploy_rects(contours.size());   //&#x627E;&#x5916;&#x63A5;&#x77E9;&#x5F62;
    vector<point2f> ccs(contours.size()); //&#x5706;&#x5FC3;
    vector<float> radius(contours.size());  //&#x534A;&#x5F84;

    vector<rotatedrect>minRects(contours.size());
    vector<rotatedrect>myeclipse(contours.size());
    for (size_t i = 0; i < contours.size(); i++)
    {
        approxPolyDP(Mat(contours[i]), contour_ploy[i], 3, true); //&#x591A;&#x8FB9;&#x5F62;&#x62DF;&#x5408;&#x66F2;&#x7EBF;
        ploy_rects[i] = boundingRect(contour_ploy[i]);
        minEnclosingCircle(contour_ploy[i], ccs[i], radius[i]);
        if (contour_ploy[i].size() > 5)
        {
            myeclipse[i] = fitEllipse(contour_ploy[i]);
            minAreaRect(contour_ploy[i]);
        }
    }

    //draw it
    Mat drawImg = Mat::zeros(src.size(), src.type());
    Point2f pts[4]; //&#x77E9;&#x5F62;&#x56DB;&#x4E2A;&#x70B9;
    for (size_t t = 0; t < contours.size(); t++)
    {
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        /*rectangle(drawImg, ploy_rects[t], color, 2, 8);
        circle(drawImg, ccs[t], radius[t], color, 2, 8);*/

        if (contour_ploy[t].size() > 5)
        {
            ellipse(drawImg, myeclipse[t], color, 1, 8);
            minRects[t].points(pts);
            for (int r = 0; r < 4; r++)
            {
                line(drawImg, pts[r], pts[(r + 1) % 4], color, 1, 8);
            }
        }
    }
    imshow(output_win, drawImg);
    return;
}

</rotatedrect></rotatedrect></float></point2f></rect></vector<point></vec4i></vector<point></math.h></iostream></opencv2>

C++OpenCV系统学习(19)——轮廓周围绘制矩形和圆形框

4.案例2

#include <opencv2 opencv.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

int main()
{
    system("color F0");  //&#x66F4;&#x6539;&#x8F93;&#x51FA;&#x754C;&#x9762;&#x989C;&#x8272;
    Mat img=imread("coins.jpeg");
    if(img.empty()){
        cout<<"请确认输入烦人图片路径是否正确"<<endl; return -1; } imshow("原图",img); mat gray,binary; cvtcolor(img,gray,color_bgr2gray); gaussianblur(gray,gray,size(9,9),2,2); 平滑滤波 threshold(gray,binary,170,255,thresh_binary|thresh_otsu); 自适应二值化 轮廓发现与绘制 vector<vector<point>>contours;//&#x8F6E;&#x5ED3;
    vector<vec4i>hierachy;//&#x5B58;&#x653E;&#x8F6E;&#x5ED3;&#x7ED3;&#x6784;&#x53D8;&#x91CF;
    findContours(binary,contours,hierachy,RETR_TREE,CHAIN_APPROX_SIMPLE);
    //&#x7ED8;&#x5236;&#x8F6E;&#x5ED3;
    for(int i=0;i<contours.size();++i){ drawcontours(img,contours,i,scalar(0,0,255),2,8); } 输出轮廓结构描述子 for(int i="0;i<hierachy.size();++i){" cout<<hierachy[i]<<endl; 显示结果 imshow("轮廓检测结果",img); waitkey(0); return 0; < code></contours.size();++i){></vec4i></"请确认输入烦人图片路径是否正确"<<endl;></vector></iostream></opencv2>

C++OpenCV系统学习(19)——轮廓周围绘制矩形和圆形框

C++OpenCV系统学习(19)——轮廓周围绘制矩形和圆形框
void cv::findContours(InputArray  image,
                      OutputArrayOfArrays  contours,
                      int  mode,
                      int  method,
                      Point  offset = Point()
                      )
  • image:输入图像,数据类型为CV_8U的单通道灰度图像或者二值化图像。
  • contours:检测到的轮廓,每个轮廓中存放着像素的坐标。
  • mode:轮廓检测模式标志,可以选择的参数在表7-2给出。
  • method:轮廓逼近方法标志,可以选择的参数在表7-3给出。
  • offset:每个轮廓点移动的可选偏移量。这个函数主要用在从ROI图像中找出轮廓并基于整个图像分析轮廓的场景中。

C++OpenCV系统学习(19)——轮廓周围绘制矩形和圆形框
void cv::drawContours(InputOutputArray  image,
                      InputArrayOfArrays  contours,
                      int   contourIdx,
                      const Scalar &  color,
                      int  thickness = 1,
                      int  lineType = LINE_8,
                      InputArray  hierarchy = noArray(),
                      int  maxLevel = INT_MAX,
                      Point  offset = Point()
                      )
  • image:绘制轮廓的目标图像。
  • contours:所有将要绘制的轮廓
  • contourIdx:要绘制的轮廓的数目,如果是负数,则绘制所有的轮廓。
  • color:绘制轮廓的颜色。
  • thickness:绘制轮廓的线条粗细,如果参数为负数,则绘制轮廓的内部,默认参数值为1.

  • lineType:边界线连接的类型,可以选择参数在表7-4给出,默认参数值为LINE_8。

  • hierarchy:可选的结构关系信息,默认值为noArray()。
  • maxLevel:表示用于绘制轮廓的最大等级,默认值为INT_MAX。
  • offset:可选的轮廓偏移参数,按指定的移动距离绘制所有的轮廓。

该函数用于绘制findContours()函数检测到的图像轮廓。
函数的第一个参数为绘制轮廓的图像,根据需求该参数可以是单通道的灰度图像或者三通道的彩色图像。
第二个参数是所有将要绘制的轮廓,数据类型为vector。
第三个参数是要绘制的轮廓数目,该参数的数值与第二个参数相对应,应小于所有轮廓的数目,如果该参数值为负数,则绘制所有的轮廓。
第四个参数是绘制轮廓的颜色,对于单通道的灰度图像用Scalar(x)赋值,对于三通道的彩色图像用Scalar(x,y,z)赋值。
第五个参数是边界线的连接类型,可以选择的参数在表7-4给出,默认参数值为LINE_8。
第六个参数是可选的结构关系信息,默认值为noArray()。
第七个参数表示绘制轮廓的最大等级,参数值如果为0,则仅绘制指定的轮廓;如果为1,则该函数绘制轮廓和所有嵌套轮廓;如果为2,则该函数绘制轮廓以及所有嵌套轮廓和所有嵌套到嵌套轮廓的轮廓,以此类推,默认值为INT_MAX。函数最后一个参数是可选的轮廓偏移参数,按指定的移动距离绘制所有的轮廓。

Original: https://blog.csdn.net/bigData1994pb/article/details/120391732
Author: AI炮灰
Title: C++OpenCV系统学习(19)——轮廓周围绘制矩形和圆形框

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/701546/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球