用opencv检测convexity defects
一 概念:
Convexity hull, Convexity defects
如上图所示,黑色的轮廓线为convexity hull, 而convexity hull与手掌之间的部分为convexity defects. 每个convexity defect区域有四个特征量:起始点(startPoint),结束点(endPoint),距离convexity hull最远点(farPoint),最远点到convexity hull的距离(depth)。
二.OpenCV中的相关函数
void convexityDefects(InputArray contour, InputArray convexhull, OutputArrayconvexityDefects)
参数:
coutour: 输入参数,检测到的轮廓,可以调用findContours函数得到;
convexhull: 输入参数,检测到的凸包,可以调用convexHull函数得到。注意,convexHull函数可以得到vector<vector<Point>>和vector<vector<int>>两种类型结果,这里的convexhull应该为vector<vector<int>>类型,否则通不过ASSERT检查;
convexityDefects:输出参数,检测到的最终结果,应为vector<vector<Vec4i>>类型,Vec4i存储了起始点(startPoint),结束点(endPoint),距离convexity hull最远点(farPoint)以及最远点到convexity hull的距离(depth)
三.代码
//http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/hull/hull.html
//http://www.codeproject.com/Articles/782602/Beginners-guide-to-understand-Fingertips-counting#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 = 100;int max_thresh = 255;RNG rng(12345);/// Function headervoid thresh_callback(int, void* );/** @function main */
int main( int argc, char** argv ){/// Load source image and convert it to graysrc = imread( argv[1], 1 );/// Convert image to gray and blur itcvtColor( src, src_gray, CV_BGR2GRAY );blur( src_gray, src_gray, Size(3,3) );/// Create Windowchar* 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 src_copy = src.clone();Mat threshold_output;vector<vector<Point> > contours;vector<Vec4i> hierarchy;/// Detect edges using Thresholdthreshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );/// Find contoursfindContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );/// Find the convex hull object for each contourvector<vector<Point> >hull( contours.size() );// Int type hullvector<vector<int>> hullsI( contours.size() );// Convexity defectsvector<vector<Vec4i>> defects( contours.size() );for( size_t i = 0; i < contours.size(); i++ ){ convexHull( Mat(contours[i]), hull[i], false ); // find int type hullconvexHull( Mat(contours[i]), hullsI[i], false ); // get convexity defectsconvexityDefects(Mat(contours[i]),hullsI[i], defects[i]);}/// Draw contours + hull resultsMat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );for( size_t i = 0; i< contours.size(); i++ ){Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );drawContours( drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point() );// draw defectssize_t count = contours[i].size();std::cout<<"Count : "<<count<<std::endl;if( count < 300 )continue;vector<Vec4i>::iterator d =defects[i].begin();while( d!=defects[i].end() ) {Vec4i& v=(*d);//if(IndexOfBiggestContour == i){int startidx=v[0]; Point ptStart( contours[i][startidx] ); // point of the contour where the defect beginsint endidx=v[1]; Point ptEnd( contours[i][endidx] ); // point of the contour where the defect endsint faridx=v[2]; Point ptFar( contours[i][faridx] );// the farthest from the convex hull point within the defectint depth = v[3] / 256; // distance between the farthest point and the convex hullif(depth > 20 && depth < 80){line( drawing, ptStart, ptFar, CV_RGB(0,255,0), 2 );line( drawing, ptEnd, ptFar, CV_RGB(0,255,0), 2 );circle( drawing, ptStart, 4, Scalar(255,0,100), 2 );circle( drawing, ptEnd, 4, Scalar(255,0,100), 2 );circle( drawing, ptFar, 4, Scalar(100,0,255), 2 );}/*printf("start(%d,%d) end(%d,%d), far(%d,%d)\n",ptStart.x, ptStart.y, ptEnd.x, ptEnd.y, ptFar.x, ptFar.y);*/}d++;}}/// Show in a windownamedWindow( "Hull demo", CV_WINDOW_AUTOSIZE );imshow( "Hull demo", drawing );//imwrite("convexity_defects.jpg", drawing);}
四.结果
原图
Convexity defects图,蓝色点是convexity defects的起始点和结束点,红色点是最远点。(为什么有的起始点和结束点中间没有最远点呢?因为只画出了depth范围在20到80之间的convexity defects的起始点、结束点和最远点)
五.参考
[1] Gary Bradski, Adrian Kaehler. Learning OpenCV: Computer Vision with the OpenCV Library. Page258~259.
[2] http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/hull/hull.html
[3] http://www.codeproject.com/Articles/782602/Beginners-guide-to-understand-Fingertips-counting
用opencv检测convexity defects相关推荐
- OpenCV检测手指个数
软硬件环境 windows 10 64bit anaconda with python 3.7 nvidia gtx 1066 opencv 4.4.0 基本原理 我们先来看余弦定理,它是检测手指个数 ...
- 使用Python,OpenCV检测摄像机到标记对象的距离
使用Python,OpenCV检测摄像机到标记对象的距离 1. 效果图 2. 三角形相似性是什么? 3. 三角形相似性检测距离原理 4. 使用Python,OpenCV检测标记对象 5. 源码 参考 ...
- 使用Python和OpenCV检测图像中的条形码
使用Python和OpenCV检测图像中的条形码 1. 效果图 2. 算法的步骤 3. 源码 参考 这篇博客将介绍使用计算机视觉和图像处理技术进行条形码检测的必要步骤,并演示使用Python编程语言和 ...
- OpenCV检测图像轮廓
轮廓只不过是图像中连接的曲线,或者图像中连通部分的边界,轮廓通常以图像中的边缘来计算,但是,边缘和轮廓的区别在于轮廓是闭合的,而边缘可以是任意的.边缘的概念局限于点及其邻域像素,轮廓将目标作为整体进行 ...
- opencv检测矩形
参考:使用OpenCV检测图像中的矩形_知来者逆的博客-CSDN博客_opencv检测图像中的矩形 1.得到原始图像之后,代码处理的步骤是: (1)滤波增强边缘. (2)分离图像通道,并检测边缘. ( ...
- python opencv 检测特定颜色
python opencv 检测特定颜色 import cv2 import numpy as npcap = cv2.VideoCapture(0)# set blue thresh 设置HSV中蓝 ...
- python opencv检测人脸
python opencv检测人脸 文章目录: 一.opencv检测一张图片 二.opencv摄像头实时检测人脸 一.opencv检测一张图片 opencv检测人脸分成三部分: 1.图片转换成灰色(降 ...
- 使用Python和OpenCV检测图片上的条形码
这篇博文的目的是应用计算机视觉和图像处理技术,展示一个条形码检测的基本实现.我所实现的算法本质上基于StackOverflow 上的这个问题,浏览代码之后,我提供了一些对原始算法的更新和改进. 首先需 ...
- OpenCV检测拐角detecting corners的实例(附完整代码)
OpenCV检测拐角detecting corners的实例 OpenCV检测拐角detecting corners的实例 OpenCV检测拐角detecting corners的实例 #includ ...
- OpenCV检测计算并匹配BRISK和AORB KAZE描述的实例(附完整代码)
OpenCV检测计算并匹配BRISK和AORB KAZE描述的实例 OpenCV检测计算并匹配BRISK和AORB KAZE描述的实例 OpenCV检测计算并匹配BRISK和AORB KAZE描述的实 ...
最新文章
- 仓库货位卡标识牌_仓储管理中的货位与标识管理
- Python3通过汉字输出拼音
- 一年成为emacs高手
- POJ C程序设计进阶 编程题#3:运算符判定
- 网络整合营销概念2015
- RocketMQ 高可用性
- 如何使用Python处理丢失的数据
- 榴莲肉多到流出来!引爆全国吃货的榴莲千层终于杀到来!100%好评
- Java隐含对象实验报告,JSP隐含对象response实现文件下载
- 【Shiro】六、Apache Shiro Session管理
- sql server 入门_SQL Server中的数据挖掘入门
- Linux系统启动过程分析 -转
- LeetCode(59):螺旋矩阵 II
- 小知识--Windows语音效果
- apicloud中阿里云推送使用
- 随机效应与固定效应面板数据回归
- 手机找不到大话西游新开服务器,大话西游手游新区冲级具体步骤
- c语言程序设计西华大学,知到C语言程序设计(西华大学)章节答案
- 如何使WooCommerce产品属性更加突出
- 经典励志文章:一碗阳春面
热门文章
- 未来5年互联网,运营将成比产品更加有前途的职业?
- phalcon 自动加载_Phalcon自动加载(PHP自动加载),phalcon加载php_PHP教程
- Android实现圆形头像
- 【odoo15】自定义一个kanban视图
- C++迷宫最短路径问题BFS
- 【关于听任大佬的讲话的深刻感悟】
- 常见出血性疾病的实验诊断题库【1】
- 计算机sci转让,紧急转让的环境sci,一共四十个选题,2020年上半年出版,包SCI检索...
- 20211218:口罩数据汇总
- 计算机成瘾的危险英语对话,英语作文:论孩子们对电脑游戏上瘾