OpenCV入门系列 —— cv::erode、cv::dilate 图像腐蚀和膨胀

OpenCV入门系列 —— cv::erode、cv::dilate 图像腐蚀和膨胀


前言

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

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

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

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

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

在这里插入图片描述


程序说明

展示图像腐蚀和膨胀的综合效果;

输出结果

在这里插入图片描述

代码示例

/*
 * @File: dilate_and_erode.cpp
 * @Brief: opencv course
 * @Description: 展示腐蚀和膨胀的综合效果
 * @Version: 0.0.1
 * @Author: MuYv
 */
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>



//-----------------------------------【全局变量声明部分】--------------------------------------
//		描述:全局变量声明
//-----------------------------------------------------------------------------------------------
cv::Mat g_srcImage, g_dstImage;//原始图和效果图
int g_nTrackbarNumer = 0;//0表示腐蚀erode, 1表示膨胀dilate
int g_nStructElementSize = 3; //结构元素(内核矩阵)的尺寸


//-----------------------------------【全局函数声明部分】--------------------------------------
//		描述:全局函数声明
//-----------------------------------------------------------------------------------------------
void Process();//膨胀和腐蚀的处理函数
void on_TrackbarNumChange(int, void *);//回调函数
void on_ElementSizeChange(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);
    
    // 显示原始图
	cv::namedWindow("【原始图】");
	cv::imshow("【原始图】", g_srcImage);

	// 进行初次腐蚀操作并显示效果图
	cv::namedWindow("【效果图】");
	// 获取自定义核
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, 
                    cv::Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),
                    cv::Point( g_nStructElementSize, g_nStructElementSize ));
	cv::erode(g_srcImage, g_dstImage, element);
	cv::imshow("【效果图】", g_dstImage);

	//创建轨迹条
	cv::createTrackbar("腐蚀/膨胀", "【效果图】", &g_nTrackbarNumer, 1, on_TrackbarNumChange);
	cv::createTrackbar("内核尺寸", "【效果图】", &g_nStructElementSize, 21, on_ElementSizeChange);

	//输出一些帮助信息
	std::cout<<std::endl<<"\t运行成功,请调整滚动条观察图像效果~\n\n"
		<<"\t按下“q”键时,程序退出。\n";

	//轮询获取按键信息,若下q键,程序退出
	while(char(cv::waitKey(1)) != 'q') {
    
    }

    return 0;
}
 
 
//-----------------------------【Process( )函数】------------------------------------
//		描述:进行自定义的腐蚀和膨胀操作
//-----------------------------------------------------------------------------------------
void Process() 
{
    
    
	//获取自定义核
	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, 
                    cv::Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),
                    cv::Point( g_nStructElementSize,g_nStructElementSize ));

	//进行腐蚀或膨胀操作
	if(g_nTrackbarNumer == 0) {
    
        
		cv::erode(g_srcImage, g_dstImage, element);
	}
	else {
    
    
		cv::dilate(g_srcImage, g_dstImage, element);
	}

	//显示效果图
	cv::imshow("【效果图】", g_dstImage);
}


//-----------------------------【on_TrackbarNumChange( )函数】------------------------------------
//		描述:腐蚀和膨胀之间切换开关的回调函数
//-----------------------------------------------------------------------------------------------------
void on_TrackbarNumChange(int, void *) 
{
    
    
	//腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,
	//使改变后的效果立即生效并显示出来
	Process();
}


//-----------------------------【on_ElementSizeChange( )函数】-------------------------------------
//		描述:腐蚀和膨胀操作内核改变时的回调函数
//-----------------------------------------------------------------------------------------------------
void on_ElementSizeChange(int, void *)
{
    
    
	//内核尺寸已改变,回调函数体内需调用一次Process函数,
	//使改变后的效果立即生效并显示出来
	Process();
}

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

猜你喜欢

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