- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
按指定的精度近似一个多边形曲线
cv::approxPolyDP 函数使用另一条曲线或多边形来近似一条曲线或多边形,新曲线或多边形的顶点数较少,且两者之间的距离小于或等于指定的精度。该函数使用 Douglas-Peucker 算法。
- Douglas-Peucker 算法:http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
函数原型
void cv::approxPolyDP
(
InputArray curve,
OutputArray approxCurve,
double epsilon,
bool closed
)
参数
- 参数curve 输入的二维点向量,可以存储在 std::vector 或 Mat 中。
- 参数approxCurve 近似的结果。其类型应当与输入曲线的类型一致。
- 参数epsilon 指定近似精度的参数,即原始曲线和近似曲线之间的最大允许距离。
- 参数closed 如果为真,则近似曲线是闭合的(其首尾顶点是相连的)。否则,它不是闭合的。
代码示例
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
// 加载一张图片
cv::Mat img = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/hawk.jpg", cv::IMREAD_COLOR );
if ( img.empty() )
{
std::cerr << "Error: Image cannot be loaded!" << std::endl;
return -1;
}
// 转换为灰度图
cv::Mat grayImg;
cv::cvtColor( img, grayImg, cv::COLOR_BGR2GRAY );
// 二值化处理
cv::Mat binaryImg;
cv::threshold( grayImg, binaryImg, 0, 255, cv::THRESH_BINARY_INV + cv::THRESH_OTSU );
// 查找轮廓
std::vector< std::vector< cv::Point > > contours;
cv::findContours( binaryImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE );
// 绘制原始轮廓
cv::Mat contourImg = cv::Mat::zeros( img.size(), CV_8UC3 );
cv::drawContours( contourImg, contours, -1, cv::Scalar( 0, 255, 0 ), 2 );
// 对每个轮廓进行近似
std::vector< std::vector< cv::Point > > approxContours( contours.size() );
for ( size_t i = 0; i < contours.size(); ++i )
{
// 计算轮廓的周长
double perimeter = cv::arcLength( contours[ i ], true );
// 近似轮廓
cv::approxPolyDP( contours[ i ], approxContours[ i ], 0.02 * perimeter, true );
// 绘制近似后的轮廓
cv::drawContours( contourImg, approxContours, static_cast< int >( i ), cv::Scalar( 255, 0, 0 ), 2 );
}
// 显示原始轮廓和近似后的轮廓
cv::imshow( "original Image", img );
cv::imshow( "Contour Image", contourImg );
// 等待按键,关闭窗口
cv::waitKey( 0 );
return !0;
}