OpenCV结构分析与形状描述符(9)检测轮廓相对于其凸包的凹陷缺陷函数convexityDefects()的使用
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
查找一个轮廓的凸性缺陷。
下图显示了一个手部轮廓的凸性缺陷:
convexityDefects 是 OpenCV 库中的一个函数,用于检测轮廓相对于其凸包的凹陷缺陷。这个函数可以帮助识别轮廓中的凹进去的部分,通常被用来分析手部或其他物体的形状特征。
函数原型
void cv::convexityDefects
(
InputArray contour,
InputArray convexhull,
OutputArray convexityDefects
)
参数
- 参数contour 输入的轮廓。
- 参数convexhull 使用 convexHull 获得的凸包,应包含构成凸包的轮廓点的索引。
- 参数convexityDefects 凸性缺陷的输出向量。在 C++ 和新的 Python/Java 接口中,每个凸性缺陷表示为一个四元素整数向量(即 Vec4i):(start_index, end_index, farthest_pt_index, fixpt_depth),其中索引是原始轮廓中凸性缺陷起始点、终点和最远点的 0 基础索引,而 fixpt_depth 是最远轮廓点与凸包之间距离的定点近似值(带有 8 位小数部分)。也就是说,要获得深度的浮点数值,需要将 fixpt_depth 除以 256.0。
代码示例
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
// 加载一张图像
Mat img = imread( "/media/dingxin/data/study/OpenCV/sources/images/hand2.png", IMREAD_GRAYSCALE );
if ( img.empty() )
{
cerr << "Error: Image not found." << endl;
return -1;
}
// 二值化处理
Mat binImg;
threshold( img, binImg, 48, 255, THRESH_BINARY_INV );
//imshow( "er zhi", binImg );
// 寻找轮廓
vector< vector< Point > > contours;
findContours( binImg, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE );
// 假设我们只处理第一个最大的轮廓
vector< Point > contour = contours[ 0 ];
// 计算凸包
vector< int > hull;
convexHull( contour, hull );
// 计算凹陷缺陷
vector< Vec4i > defects;
convexityDefects( contour, hull, defects );
// 在原图上绘制凸包和凹陷缺陷
Mat drawing = Mat::zeros( img.size(), CV_8UC3 );
drawContours( drawing, contours, 0, Scalar( 255, 0, 0 ), 2 ); // 绘制轮廓
//imshow( "Convexity ", drawing );
// 绘制凹陷缺陷
for ( size_t i = 0; i < defects.size(); i++ )
{
Vec4i defect = defects[ i ];
Point start = contour[ defect[ 0 ] ];
Point end = contour[ defect[ 1 ] ];
Point farthest = contour[ defect[ 2 ] ];
line( drawing, start, end, Scalar( 0, 255, 0 ), 1 ); // 绘制凹陷缺陷的边缘
circle( drawing, farthest, 5, Scalar( 0, 0, 255 ), -1 ); // 绘制凹陷缺陷的最远点
}
// 显示结果
imshow( "Original image", img );
imshow( "Convexity Defects", drawing );
waitKey( 0 );
return 0;
}