OpenCV-图像处理(30、轮廓周围绘制矩形框和圆形框)
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,会报错
演示代码-步骤
- 首先将图像变为二值图像
- 发现轮廓,找到图像轮廓
- 通过相关API在轮廓点上找到最小包含矩形和圆,旋转矩形与椭圆。
- 绘制它们。
程序代码
#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;
}
运行截图
参考博客
- https://blog.csdn.net/qq_31647835/article/details/81055711
- https://blog.csdn.net/huanghuangjin/article/details/81188001
- https://blog.csdn.net/LYKymy/article/details/83210437
- https://blog.csdn.net/Daker_Huang/article/details/83826674
OpenCV-图像处理(30、轮廓周围绘制矩形框和圆形框)相关推荐
- Opencv(六)模板匹配、轮廓检测、轮廓周围绘制矩形框和圆形框
模板匹配介绍 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域. 所以模板匹配首先需要一个模板图像T(给定的子图像) 另外需要一个待检测的图像-源图像S 工作方法,在带检测图像上,从左到右,从 ...
- Java OpenCV 图像处理30 视频分析和对象跟踪 视频读取
Java OpenCV 图像处理30 视频分析和对象跟踪 视频读取 Java OpenCV-4.0.0 图像处理 视频分析和对象跟踪 视频读取 package com.xu.opencv.video; ...
- 【学习OpenCV】给轮廓画出矩形和圆形边界
OpenCV支持大量的轮廓.边缘.边界的相关函数,相应的函数有moments.HuMoments.findContours.drawContours.approxPolyDP.arcLength.bo ...
- OPENCV图像处理基础(五)鼠标事件画个框
在GUI编程中会涉及到鼠标事件,通过鼠标事件可以使得人和机器的交互更为便捷.opencv中提供了一种以回调函数实现的鼠标事件机制. 下面是一个例子,通过鼠标在一张图片上画出任意大小的矩形框. 效果如下 ...
- opencv图像处理之轮廓外背景颜色改变
自行学习弄得简单代码,使用了图像中的轮廓发现以及提取,再绘制出来,改变轮廓外的像素 首先,头文件,写的比较多,没用的可以自己去除 #include <opencv2/core/core.hpp& ...
- python+OpenCV图像处理(三)绘制简单的几何图形、显示文字
绘制简单的几何图形.显示文字 (一)绘制直线和矩形 img = np.zeros([512, 512, 3]) # line函数用来画直线,第一个参数可以理解为画布矩阵, # 第二个参数pt1是直线的 ...
- OpenCV学习(30) 轮廓defects
https://www.cnblogs.com/mikewolf2002/p/3426652.html 上一篇教程中,我们学习了如何计算轮廓的凸包,其实对一个轮廓而言,可能它的凸包和它本身是重合的,也 ...
- openCV专栏(八):图像轮廓:绘制轮廓
OPENCV基础操作 提示:本专栏所用版本仅供参考,其他版本也可 库 版本 python Python 3.9.3 opencv 4.5.5 matplotlib 3.4.3 numpy 1.19.5 ...
- OpenCV图像处理基础(C++版)
目录 OpenCV环境搭建 加载 修改 保存图像 矩阵的掩膜操作 Mat对象 图像操作 图像混合 调整图像亮度与对比度 绘制形状与文字 模糊图像一 模糊图像二 膨胀与腐蚀 形态学操作 形态学操作应用- ...
- OpenCV 图像处理编程学习笔记
<OpenCV编程实例代码>各章重点知识点简述 第一章 OpenCv环境配置 第二章 图像及视频的基本操作 第二部分 图像处理技术 第三章 图像灰度变换技术 第四章 图像平滑技术 第五章 ...
最新文章
- 报名 | 2019清华大数据系统软件峰会
- swift和python语法区别_Swift 基本语法
- tableau2020.2版本可视化数据分析 新功能介绍
- MySQL案例分析--QueryCache
- 欧几里得gcd/extend_gcd
- 北妈每日一学:ES6 之 模块化-重要!
- mysql所以字段_MySQL|mysql-索引
- 本地项目添加到远程仓库
- 知乎cookies的介绍_Requestium = Requests + Selenium
- ROS(ROUTEROS) 端口映射
- 视频黑屏画面检测 blackframe
- 计算机检索系统功能,文学多功能计算机自动检索系统研究
- iphone图片编辑画笔_iPhone手机怎么编辑图片?还不知道的话真的要了解一波了~...
- 服务器维护表格,服务器维护表格
- 浅谈Attention机制
- 单片机性能测试基准CoreMark是什么
- Prompt Engineering 入门(二)
- 转;三宫九观二十四坊——摘自苏州热线
- c 语言 批量更改文件名,rename 批量修改文件名
- WeLink可以发邮件吗?
热门文章
- grep awk 搜索日志常用命令
- Hadoop AWS Word Count 样例
- 手把手教你逆向分析 Android 程序
- Office 365系列(1)------Office 365邮箱申请及初步配置说明
- 网页素材精品:一组五彩缤纷的免费矢量背景素材
- jquery学习系列1(Ready)
- 容器和泛型 容器重点掌握
- android 加载过程,Android View (2) View的加载过程
- c语言如何输出10个空格,新人提问:如何将输出时每行最后一个空格删除
- dual mysql 获取序列_如何获取 MySQL 插入数据的自增 ID