OpenCV入门系列 —— cv::approxPolyDP 计算包围框

OpenCV入门系列 —— cv::approxPolyDP 计算包围框


前言

随着工业自动化、智能化的不断推进,机器视觉(2D/3D)在工业领域的应用和重要程度也同步激增(识别、定位、抓取、测量,缺陷检测等),而针对不同作业场景进行解决方案设计时,通常会借助PCL、OpenCV、Eigen等简单方便的开源算法库进行方案的快速验证和迭代以满足作业场景下的目标需求。

为了让对工业机器视觉方向感兴趣的同学能够少走一些弯路,故推出了此一系列简易入门教程示例,让初次使用者能够最简单直观地感受到当前所用算法模块的执行效果。

后续会逐步扩增与工业机器视觉相关的一些其它内容,如:

项目案例剖析场景数据分析基础算法模块相机评测 等;

如有兴趣可加入群聊(若入群二维码被屏蔽,则可以通过Q群(1032861997)或评论、私信博主“群聊”,邀请入群),与同道同学及圈内同行一起交流讨论。

在这里插入图片描述


程序说明

提取图像物体边缘并生成最小包围框;

输出结果

在这里插入图片描述

代码示例

/*
 * @File: approx_poly_dp.cpp
 * @Brief: opencv course
 * @Description: 展示提取图像物体边缘并生成包围框的效果
 * @Version: 0.0.1
 * @Author: MuYv
 */
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>




#define WINDOW_NAME1 "【原始图窗口】"        //为窗口标题定义的宏 
#define WINDOW_NAME2 "【效果图窗口】"        //为窗口标题定义的宏 

cv::Mat g_srcImage;
cv::Mat g_grayImage;
int g_nThresh = 50;//阈值
int g_nMaxThresh = 255;//阈值最大值
cv::RNG g_rng(12345);//随机数生成器


void on_ContoursChange(int, void* );


int main(int argc, char** argv)
{
	if(argc != 2){
        std::cout<<"Usage: exec img_file_path"<<std::endl;
        return -1;
    }
    const std::string kImgFilePath = argv[1];

    // 加载为 rgb 3通道彩色图数据
    g_srcImage = cv::imread(kImgFilePath, cv::IMREAD_COLOR);	// ../imgs/sea.jpg

	// 得到原图的灰度图像并进行平滑
	cv::cvtColor( g_srcImage, g_grayImage, cv::COLOR_BGR2GRAY );
	cv::blur( g_grayImage, g_grayImage, cv::Size(3,3) );

	// 创建原始图窗口并显示
	cv::namedWindow( WINDOW_NAME1, cv::WINDOW_AUTOSIZE );
	cv::imshow( WINDOW_NAME1, g_srcImage );

	// 设置滚动条并调用一次回调函数
	cv::createTrackbar(" 阈值:", WINDOW_NAME1, &g_nThresh, 
			g_nMaxThresh, on_ContoursChange );
	on_ContoursChange( 0, 0 );

	cv::waitKey(0);

	return(0);
}


void on_ContoursChange(int, void* )
{
	//定义一些参数
	cv::Mat threshold_output;
	std::vector<std::vector<cv::Point>> contours;
	std::vector<cv::Vec4i> hierarchy;

	// 使用Threshold检测边缘
	cv::threshold( g_grayImage, threshold_output, 
			g_nThresh, 255, cv::THRESH_BINARY );

	// 找出轮廓
	cv::findContours( threshold_output, contours, hierarchy, 
		cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );

	// 多边形逼近轮廓 + 获取矩形和圆形边界框
	std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
	std::vector<cv::Rect> boundRect( contours.size() );
	std::vector<cv::Point2f>center( contours.size() );
	std::vector<float>radius( contours.size() );

	// 一个循环,遍历所有部分,进行本程序最核心的操作
	for( unsigned int i = 0; i < contours.size(); i++ )
	{ 
		//用指定精度逼近多边形曲线
		cv::approxPolyDP( cv::Mat(contours[i]), contours_poly[i], 3, true ); 
		//计算点集的最外面(up-right)矩形边界
		boundRect[i] = cv::boundingRect( cv::Mat(contours_poly[i]) );
		//对给定的 2D点集,寻找最小面积的包围圆形
		cv::minEnclosingCircle( contours_poly[i], center[i], radius[i] ); 
	}

	// 绘制多边形轮廓 + 包围的矩形框 + 圆形框
	cv::Mat drawing = cv::Mat::zeros( threshold_output.size(), CV_8UC3 );
	for( int unsigned i = 0; i<contours.size( ); i++ )
	{
		//随机设置颜色
		cv::Scalar color = cv::Scalar( g_rng.uniform(0, 255), 
					g_rng.uniform(0,255), g_rng.uniform(0,255) );
		//绘制轮廓
		cv::drawContours( drawing, contours_poly, i, color, 
				1, 8, std::vector<cv::Vec4i>(), 0, cv::Point() );
		//绘制矩形
		cv::rectangle(drawing,boundRect[i].tl(),boundRect[i].br(),color,2,8,0);
		cv::circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 );//绘制圆
	}

	// 显示效果图窗口
	cv::namedWindow( WINDOW_NAME2, cv::WINDOW_AUTOSIZE );
	cv::imshow( WINDOW_NAME2, drawing );
}

注:部分测试所用图片数据来源于网络,如有侵权,请联系博主删除,谢谢。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值