OpenCV入门系列 —— findContours、drawContours查找轮廓并随机着色可视化

OpenCV入门系列 —— findContours、drawContours查找轮廓并随机着色可视化


前言

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

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

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

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


程序说明

查找图片中的轮廓,并对各个轮廓线进行随机着色;

输出结果

在这里插入图片描述

代码示例

/*
 * @File: find_and_draw_contours.cpp
 * @Brief: opencv course
 * @Description: 展示查找并绘制轮廓检测效果
 * @Version: 0.0.1
 * @Author: MuYv
 */
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>




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


//-----------------------------------【全局变量声明部分】--------------------------------------
//		描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
cv::Mat g_srcImage; 
cv::Mat g_grayImage;
int g_nThresh = 80;
int g_nThresh_max = 255;
cv::RNG g_rng(12345);
cv::Mat g_cannyMat_output;
std::vector<std::vector<cv::Point>> g_vContours;
std::vector<cv::Vec4i> g_vHierarchy;



void on_ThreshChange(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];   // "../imgs/can.jpg"

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

    // 转成灰度并模糊化降噪
	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( "canny阈值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange );
	on_ThreshChange( 0, 0 );

	// 等待n毫秒后关闭窗口,0代表一直开启,直到任意按键触发关闭窗口
    cv::waitKey(0);

    return 0;
}
void on_ThreshChange(int, void* ){
    
    
	// 用Canny算子检测边缘
	cv::Canny( g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh*2, 3 );

	// 寻找轮廓
	cv::findContours(g_cannyMat_output, g_vContours, g_vHierarchy, 
					 cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );

	// 绘出轮廓
	cv::Mat drawing = cv::Mat::zeros( g_cannyMat_output.size(), CV_8UC3 );
	for( int i = 0; i< g_vContours.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, g_vContours, i, color, 2, 8, g_vHierarchy, 0, cv::Point() );
	}

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

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

猜你喜欢

转载自blog.csdn.net/memorynode/article/details/125193511