Opencv——查找并绘制凸包、凸包与轮廓的关系

定义

给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型。
理解物体形状或轮廓的一 种比较有用的方法便是计算一个物体的凸包,然后计算其凸缺陷(convexity defects)。
凸包

检测凸包

opencv自带函数:convexHull()

参数解释:
参数解释

示例1:检测随机点群的凸包(只有一个凸包)

代码以及注释:

#include <opencv2/opencv.hpp>
#include <iostream>
#include "windows.h"
#include <stdio.h>
#include <time.h>using namespace cv;
using namespace std;//===========================凸包检测基础====================
//先随机生成3~103个坐标值随机的彩色点,然后利用convexHull,对链接起来的图形求凸包
int main()
{Mat image(600, 600, CV_8UC3);//RNG& rng = theRNG();		//返回一个当前线程的随机数生成器		RNG类可以产生多种类型的随机数,故使用时需要指定是哪种类型的RNG rng((unsigned)time(NULL));		//这样每次重新运行会产生不一样的随机数while (1){//参数初始化char key;int count = (unsigned)rng % 100 + 3;	//随机生成点的数量vector<Point> points;		//点值//随机生成点坐标for (int i = 0;i < count;i++){Point point;point.x = rng.uniform(image.cols / 4, image.cols * 3 / 4);point.y = rng.uniform(image.rows / 4, image.rows * 3 / 4);points.push_back(point);			//将此时生成的点数据送入	points数组的最后一个}//检测凸包(这里认为凸包只有一个)vector<int> hull;		//存储一个凸包的边的一维数组	convexHull(Mat(points),hull,true);//输入二维点集,输出找到的凸包//绘制出随机颜色的点image = Scalar::all(0);		//背景for (int i = 0;i < count;i++){circle(image,points[i],3,Scalar(rng.uniform(0,255), rng.uniform(0, 255), rng.uniform(0, 255)),FILLED,LINE_AA);}//准备参数int hullcount = (int)hull.size();		//凸包的边数(因为只有一个凸包,而凸包是由边构成的序列,所以返回序列长度,应该返回的是边的个数)Point point0 = points[hull[hullcount - 1]];		//连接凸包边的坐标点		最后一条边的坐标点//绘制凸包的边for (int i = 0;i < hullcount;i++){Point point = points[hull[i]];		//points[hull[i]]表示构成凸包边的某点(因为凸包是一个点集合最外面的点连接起来的区域)line(image, point0, point, Scalar(255, 255, 255), 2, LINE_AA);point0 = point;}//显示效果图imshow("凸包检测示例",image);//按下ESC程序退出//key = (char)waitKey();//if (key == 27) break;waitKey(1000);		//每秒显示一次}return 0;
}

演示效果:
示例

示例2:动态检测并绘制轮廓和凸包(一个轮廓对应一个凸包)

//===========================动态检测绘制图形的轮廓和凸包====================//=================全局变量声明=================
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh = 50;
int g_nThresh_max = 255;
RNG g_rng(12345);
Mat srcImage_copy = g_srcImage.clone();
Mat g_thresholdMat_output;
vector<vector<Point>> g_vContours;
vector<Vec4i> g_vHierarchy;//=============全局函数声明===============
void on_ThreshChange(int,void*);
int main()
{// Read image 读取图像SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);		//字体为绿色//载入原图g_srcImage = imread("D:\\opencv_picture_test\\lena.jpg",1);//Mat srcImage = imread("D:\\opencv_picture_test\\形态学操作\\孔洞.png", 0);	//读取灰度图//转换成灰度并且模糊化降噪cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);blur(g_grayImage, g_grayImage, Size(3, 3));//创建窗口namedWindow("原始图窗口", WINDOW_AUTOSIZE);imshow("原始图窗口", g_srcImage);//创建滑动条并初始化createTrackbar("阈值", "原始图窗口", &g_nThresh,g_nThresh_max, on_ThreshChange);on_ThreshChange(0,0);waitKey(0);return 0;
}
void on_ThreshChange(int, void*)
{//用Canny算子检测边缘Canny(g_grayImage, g_thresholdMat_output, g_nThresh, g_nThresh * 2, 3);//寻找轮廓.findContours(g_thresholdMat_output, g_vContours, g_vHierarchy,RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));//遍历每个轮廓,寻找其凸包vector<vector<Point> > hull( g_vContours.size());		//轮廓、凸包、点,构成三维数组	凸包的数组的大小等于轮廓的大小for (unsigned int i = 0;i<g_vContours.size();i++){convexHull(Mat (g_vContours[i]), hull[i],false);		//在轮廓数组中寻找凸包,存入对应的hull中}//绘出轮廓及其凸包Mat drawing = Mat::zeros(g_thresholdMat_output.size(), CV_8UC3);for (int i = 0; i < g_vContours.size(); i++){Scalar color = Scalar(g_rng.uniform(0, 255),g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值//绘制轮廓drawContours(drawing, g_vContours, i, color, 1, 8, g_vHierarchy,0, Point());//绘制凸包drawContours(drawing, hull, i, color, 1, 8, g_vHierarchy,0, Point());}//显示效果图imshow("效果图",drawing);
}

演示效果:
1、仅绘制凸包:
仅绘制凸包
2、仅绘制轮廓:
仅绘制轮廓
3、既绘制轮廓也绘制凸包:
既绘制轮廓也绘制凸包
更加凸显出轮廓与凸包的关系。
总结:
学到的凸包知识点:检测并绘制凸包;轮廓、凸包、凸包连接点的结构关系。
学到的c++语法知识点:随机数生成器RNG的用法;vector的push_back()操作。

参考链接:
C++RNG类与毛星云寻找凸包例程的理解
C++ push方法与push_back方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/378627.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java接口并发衡量_java 后端设计高并发接口总结

如何设置高并发接口一、并发队列的选择二、请求接口的合理设计三、高并发下的数据安全3.1 超发的原因3.2 悲观锁思路3.3 FIFO队列思路3.4 乐观锁思路一、并发队列的选择Java的并发包提供了三个常用的并发队列实现&#xff0c;分别是&#xff1a;ArrayBlockingQueue、Concurrent…

JAVA 取得当前目录的路径

在写java程序时不可避免要获取文件的路径...总结一下,遗漏的随时补上 1.可以在servlet的init方法里 String path getServletContext().getRealPath("/"); 这将获取web项目的全路径 例如 :E:/eclipseM9/workspace/tree/ tree是我web项目的根目录 2.你也可以随时在任意…

02.1-元素定位(find)

常用的一些方法 一、导包 from selenium import webdriver二、打开火狐&#xff08;空白页&#xff09; b webdriver.Firefox()三、跳转到指定的网站 b.get(https://www.baidu.com/)四、将浏览器页面最大化 b.maximize_window()五、通过F12可查看当前的贴吧为超链接形式 …

快速傅里叶变换(FFT)——按时间抽取DIT的基

目录【1】前言1、DIF计算量2、利用性质改善【2】公式推导1、N 到 2*N/2a、分解原序列b、分解后的DFT变换c、一系列化简操作之后d、蝶形信号流e、计算量总结2、N/2 到 2*N/4a、分解X2(k)序列b、蝶形信号流&#xff08;2列&#xff09;3、N/4 到 2*N/8a、蝶形信号流&#xff08;3…

快速傅里叶变换(FFT)——按频率抽取DIF的基

目录【1】回顾DIT【2】算法原理【3】运算特点【1】回顾DIT https://blog.csdn.net/qq_42604176/article/details/105559756 【2】算法原理 设序列点数&#xff1a;N2^M,M为正整数。将输入序列按照前一半、后一半分开。&#xff08;并非按照奇偶分&#xff09; 由于&#xf…

莫比乌斯函数---C++

【问题描述】 莫比乌斯函数&#xff0c;数论函数&#xff0c;由德国数学家和天文学家莫比乌斯(Mobius&#xff0c;1790-1868)提出。梅滕斯(Mertens)首先使用μ(n)作为莫比乌斯函数的记号。而据说&#xff0c;高斯(Gauss)比莫比乌斯早三十年就曾考虑过这个函数。莫比乌斯函数在数…

Opencv——findContours函数再探(由轮廓联想连通域)

目录关于调参的一些思考分析图像的一些角度面积、周长、矩形度、圆形度、宽长比例1&#xff1a;找出汽车轮毂圆孔&#xff08;从轮廓和连通域两个角度&#xff09;例2&#xff1a;找出芯片中间正方形物体例3&#xff1a;桌面上橘色物体总结关于调参的一些思考 合理的参数设置&…

modelsim 编译 xilinx库

1.为单个工程加入库 在某一个目录建立工程 然后 vlib unisim vcom -work unsim *.vhd 然后就加入了unisim库 如果是windows的话&#xff0c;工程文件mpf应该是记录了这个库的信息&#xff0c;所以重新打开这个工程时&#xff0c;依然有这个库 linux&#xff0c;不用gui界面…

php 载入css就可以显示,如何在进度条加载后显示页面

1.思路&#xff1a;加入很多图片&#xff0c;以延迟加载时间&#xff0c;实现加载完后显示图片。定义一个外层p&#xff0c;覆盖住图片&#xff0c;在内层p中引入加载时显示的图片&#xff0c;让内层p居中在页面上&#xff0c;利用setInterval定时器设置3秒后将外层p隐藏&#…

如何获取轮廓(连通域)的面积、周长、矩形度、圆形度、宽长比、周径比等形状描述符?

博主联系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里会有往届的smarters和电赛选手&#xff0c;群里也会不时分享一些有用的资料&#xff0c;有问题可以在群里多问问。 目录前言1、轮廓面积获取函数2、轮廓周长获取函数3、轮廓圆形度计算4、矩形度计算…

01-基础部分

一、tensorflow和opencv测试 import tensorflow as tf import cv2hello tf.constant(hello tensorflow) session tf.Session() print(session.run(hello))print(hello opencv)运行效果如下&#xff1a; 二、基础部分 1、opencv基础 代码三部曲&#xff1a; 1、引入Open…

网络和通信 - Silverlight 中的 HTTP 通信和安全

Silverlight 支持几种使用 HTTP/HTTPS 的方案。虽然可以使用多种方式和技术执行 HTTP 调用&#xff0c;但是下表描述的是针对这些 HTTP 通信方案的建议方法 执行 HTTP 调用的选项 确定应由浏览器还是客户端来执行应用程序的 HTTP 处理后&#xff0c;应在创建任何 Web 请求之前指…

WT2605C高品质音频蓝牙语音芯片:外接功放实现双声道DAC输出的优势

在音频处理领域&#xff0c;双声道DAC输出能够提供更为清晰、逼真的音效&#xff0c;增强用户的听觉体验。针对这一需求&#xff0c;唯创知音的WT2605C高品质音频蓝牙语音芯片&#xff0c;通过外接功放实现双声道DAC输出&#xff0c;展现出独特的应用优势。 一、高品质音频处理…

角点检测(Harris角点检测法)

博主联系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里会有往届的smarters和电赛选手&#xff0c;群里也会不时分享一些有用的资料&#xff0c;有问题可以在群里多问问。 目录原理讲解【1】为何选取角点作为特征&#xff1f;【2】角点的定义&#xff1a;…

02-图像的几何变换

一、图片缩放 imageInfo&#xff1a;图片宽、高、通道个数等 缩放&#xff1a; 等比例缩放&#xff1a;宽高比不变 任意比例缩放&#xff1a;图片拉伸、非拉伸 窗体大小 实现步骤&#xff1a; 1&#xff0c;完成图像的加载&#xff0c;拿到图像的数据信息 2&#xff0c;图片的宽…

微机原理——8086中断类型以及中断向量表、中断响应、中断返回

博主联系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里会有往届的smarters和电赛选手&#xff0c;群里也会不时分享一些有用的资料&#xff0c;有问题可以在群里多问问。 目录先验知识回顾控制寄存器回顾1、8086中断类型1、外部可屏蔽中断2、外部不可屏蔽…

资料整理-工具篇

* 代码利器 Resharper 作为一个C#er&#xff0c;非常感谢有Resharper这样的代码利器。在VS系列的IDE中&#xff0c;使用Resharper后&#xff0c;你会发现&#xff0c;原来写代码也可以是一种享受&#xff01; 1. 首先&#xff0c;下载Resharper。下载地址&#xff1a;http://ww…

企业级php第三方支付平台,ThinkPHP新版企业级php第三方api第四方支付平台程序源码商业版 带接口文件等 某宝售价3000元...

本帖最后由 商业源码网 于 2017-12-21 11:23 编辑7 h$ . , C u0 R3 R y$ z! ] q( D D$ s( Y源码说明&#xff1a;) G: y; R# G0 0 g N. ; \0 w, A9 {5 # P今天黑锐给大家分享给好东西&#xff01;很不错的支付系统&#xff01;喜欢研究支付接口的朋友别错过&#xff01;ThinkP…

OpenCV实战【2】HOG+SVM实现行人检测

目录HOG是什么&#xff1f;HOG vs SIFTHOG步骤HOG在检测行人中的方式Opencv实现HOGDescriptor的构造函数&#xff1a;行人检测HOGSVM步骤简化版的HOG计算HOG是什么&#xff1f; 方向梯度直方图( Histogram of Oriented Gradient, HOG )特征是一种在计算机视觉和图像处理中用来进…

03-图像特效

一、灰度处理 方法一&#xff1a;imread方法 彩色图的颜色通道为3&#xff0c;即RGB&#xff1b;而灰度图只有一个颜色通道。 import cv2 img0 cv2.imread(E:\Jupyter_workspace\study\data/cat.png,0) img1 cv2.imread(E:\Jupyter_workspace\study\data/cat.png,1) print…