API

基于RDP算法实现,目的是减少多边形轮廓点数

  • approxPolyDP( //减少多边形轮廓点数
    InputArray curve, //一般是由图像的轮廓点组成的点集 Mat(vector)
    OutputArray approxCurve, //表示输出的多边形点集
    double epsilon, //主要表示输出的精度,就是两个轮廓点之间最大距离数,5,6,7,,8,,,,
    bool closed //表示输出的多边形是否封闭

RDP算法
1. 判断起始点(当前点)与终点的距离是否小于 epsilon, 若小于,结束,不小于执行2
2. 选取起始点(当前点)A的后两个位置的点C,判断它们之间的距离是否小于 epsilon, 若小于,点C与它们的中间点B都舍弃,若不小于,执行3
3. 判断A与B,B与C的距离,若有一者小于 epsilon,则点B舍弃,否则保留。然后点C作为起始点(当前点)重复 1 2 3 步骤,直到终点(这里得出的是一系列符合要求的点)

轮廓周围绘制矩形 -API

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

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

  • cv::minEnclosingCircle(// 得到轮廓周围最小椭圆
    InputArray points, //得到最小区域圆形
    Point2f& center, // 圆心位置 输出参数
    float& radius// 圆的半径 输出参数
    )
  • cv::fitEllipse(InputArray points) // 得到最小椭圆,若points的点数size小于5,会报错

演示代码-步骤

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

程序代码

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>using namespace std;
using namespace cv;
Mat src, gray_src, drawImg;
int threshold_v = 170;
int threshold_max = 255;
const char* output_win = "rectangle-demo";
RNG rng(12345);
void Contours_Callback(int, void*);int main(int argc, char** argv) {// 载入原图像, 返回3通道图像src = imread("E:/Experiment/OpenCV/Pictures/NumberTest.jpg");if (!src.data) {printf("could not load image...\n");return -1;}// 转化成灰度图像并进行平滑cvtColor(src, gray_src, CV_BGR2GRAY);blur(gray_src, gray_src, Size(3, 3), Point(-1, -1));// 创建窗口const char* source_win = "input image";namedWindow(source_win, CV_WINDOW_AUTOSIZE);namedWindow(output_win, CV_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检测边缘,二值化操作threshold(gray_src, binary_output, threshold_v, threshold_max, THRESH_BINARY);//阈值二值化//imshow("binary image", binary_output);// 找到轮廓findContours(binary_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1));//发现轮廓// 多边形逼近轮廓 + 获取矩形和圆形边界框vector<vector<Point>> contours_ploy(contours.size());//减少点数后的轮廓的集合,定义图像输出的多边形点集vector<Rect> ploy_rects(contours.size());//轮廓点形成的矩形vector<Point2f> ccs(contours.size());//定义圆心坐标vector<float> radius(contours.size());//定义圆的半径vector<RotatedRect> minRects(contours.size());//每个轮廓最终形成的最小的旋转的矩形vector<RotatedRect> myellipse(contours.size());//每个轮廓最终形成的最小椭圆for (size_t i = 0; i < contours.size(); i++) {approxPolyDP(Mat(contours[i]), contours_ploy[i], 3, true);//减少轮廓点数,为后面的算法提高效率ploy_rects[i] = boundingRect(contours_ploy[i]);//得到轮廓周围最小矩形minEnclosingCircle(contours_ploy[i], ccs[i], radius[i]);//得到轮廓周围最小椭圆if (contours_ploy[i].size() > 5) {myellipse[i] = fitEllipse(contours_ploy[i]);// 得到最小椭圆,若contours_ploy[i]的点数size小于5会报错minRects[i] = minAreaRect(contours_ploy[i]);// 得到一个旋转的矩形,返回旋转矩形}}// 画多边形轮廓 + 包围的矩形框 + 圆形框  draw itdrawImg = Mat::zeros(src.size(), src.type());Point2f pts[4];//画直线需要4个点for (size_t t = 0; t < contours.size(); t++) { // contours_ploy[i]的点数size小于5的,不处理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 (contours_ploy[t].size() > 5) {ellipse(drawImg, myellipse[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;
}

运行截图

参考博客

  1. https://blog.csdn.net/qq_31647835/article/details/81055711
  2. https://blog.csdn.net/huanghuangjin/article/details/81188001
  3. https://blog.csdn.net/LYKymy/article/details/83210437
  4. https://blog.csdn.net/Daker_Huang/article/details/83826674

OpenCV-图像处理(30、轮廓周围绘制矩形框和圆形框)相关推荐

  1. Opencv(六)模板匹配、轮廓检测、轮廓周围绘制矩形框和圆形框

    模板匹配介绍 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域. 所以模板匹配首先需要一个模板图像T(给定的子图像) 另外需要一个待检测的图像-源图像S 工作方法,在带检测图像上,从左到右,从 ...

  2. Java OpenCV 图像处理30 视频分析和对象跟踪 视频读取

    Java OpenCV 图像处理30 视频分析和对象跟踪 视频读取 Java OpenCV-4.0.0 图像处理 视频分析和对象跟踪 视频读取 package com.xu.opencv.video; ...

  3. 【学习OpenCV】给轮廓画出矩形和圆形边界

    OpenCV支持大量的轮廓.边缘.边界的相关函数,相应的函数有moments.HuMoments.findContours.drawContours.approxPolyDP.arcLength.bo ...

  4. OPENCV图像处理基础(五)鼠标事件画个框

    在GUI编程中会涉及到鼠标事件,通过鼠标事件可以使得人和机器的交互更为便捷.opencv中提供了一种以回调函数实现的鼠标事件机制. 下面是一个例子,通过鼠标在一张图片上画出任意大小的矩形框. 效果如下 ...

  5. opencv图像处理之轮廓外背景颜色改变

    自行学习弄得简单代码,使用了图像中的轮廓发现以及提取,再绘制出来,改变轮廓外的像素 首先,头文件,写的比较多,没用的可以自己去除 #include <opencv2/core/core.hpp& ...

  6. python+OpenCV图像处理(三)绘制简单的几何图形、显示文字

    绘制简单的几何图形.显示文字 (一)绘制直线和矩形 img = np.zeros([512, 512, 3]) # line函数用来画直线,第一个参数可以理解为画布矩阵, # 第二个参数pt1是直线的 ...

  7. OpenCV学习(30) 轮廓defects

    https://www.cnblogs.com/mikewolf2002/p/3426652.html 上一篇教程中,我们学习了如何计算轮廓的凸包,其实对一个轮廓而言,可能它的凸包和它本身是重合的,也 ...

  8. openCV专栏(八):图像轮廓:绘制轮廓

    OPENCV基础操作 提示:本专栏所用版本仅供参考,其他版本也可 库 版本 python Python 3.9.3 opencv 4.5.5 matplotlib 3.4.3 numpy 1.19.5 ...

  9. OpenCV图像处理基础(C++版)

    目录 OpenCV环境搭建 加载 修改 保存图像 矩阵的掩膜操作 Mat对象 图像操作 图像混合 调整图像亮度与对比度 绘制形状与文字 模糊图像一 模糊图像二 膨胀与腐蚀 形态学操作 形态学操作应用- ...

  10. OpenCV 图像处理编程学习笔记

    <OpenCV编程实例代码>各章重点知识点简述 第一章 OpenCv环境配置 第二章 图像及视频的基本操作 第二部分 图像处理技术 第三章 图像灰度变换技术 第四章 图像平滑技术 第五章 ...

最新文章

  1. 报名 | 2019清华大数据系统软件峰会
  2. swift和python语法区别_Swift 基本语法
  3. tableau2020.2版本可视化数据分析 新功能介绍
  4. MySQL案例分析--QueryCache
  5. 欧几里得gcd/extend_gcd
  6. 北妈每日一学:ES6 之 模块化-重要!
  7. mysql所以字段_MySQL|mysql-索引
  8. 本地项目添加到远程仓库
  9. 知乎cookies的介绍_Requestium = Requests + Selenium
  10. ROS(ROUTEROS) 端口映射
  11. 视频黑屏画面检测 blackframe
  12. 计算机检索系统功能,文学多功能计算机自动检索系统研究
  13. iphone图片编辑画笔_iPhone手机怎么编辑图片?还不知道的话真的要了解一波了~...
  14. 服务器维护表格,服务器维护表格
  15. 浅谈Attention机制
  16. 单片机性能测试基准CoreMark是什么
  17. Prompt Engineering 入门(二)
  18. 转;三宫九观二十四坊——摘自苏州热线
  19. c 语言 批量更改文件名,rename 批量修改文件名
  20. WeLink可以发邮件吗?

热门文章

  1. grep awk 搜索日志常用命令
  2. Hadoop AWS Word Count 样例
  3. 手把手教你逆向分析 Android 程序
  4. Office 365系列(1)------Office 365邮箱申请及初步配置说明
  5. 网页素材精品:一组五彩缤纷的免费矢量背景素材
  6. jquery学习系列1(Ready)
  7. 容器和泛型 容器重点掌握
  8. android 加载过程,Android View (2) View的加载过程
  9. c语言如何输出10个空格,新人提问:如何将输出时每行最后一个空格删除
  10. dual mysql 获取序列_如何获取 MySQL 插入数据的自增 ID