广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >基于OpenCV 差分法实现绿叶识别
  • 396
分享到

基于OpenCV 差分法实现绿叶识别

2024-04-02 19:04:59 396人浏览 独家记忆
摘要

目录实现原理功能函数代码c++测试代码实现原理 物体识别是图像处理学在现实生活中较多的应用之一,目前最为流行的就是运用ai、机器学习等技术结合图像处理学,大量训练数据集,以实现智能且

实现原理

物体识别是图像处理学在现实生活中较多的应用之一,目前最为流行的就是运用ai机器学习等技术结合图像处理学,大量训练数据集,以实现智能且精确的识别。说到人工智能,很多人可能觉得它非常深奥和复杂,其实说白了它最底层的识别逻辑还是基于普通的图像分析,像特征提取、轮廓分析、比对分析等等,再在庞大的数据集中按照相似程度,分析出一个最可能的结果。

本文提供了一种相对简单的思路来实现绿叶识别,适合初学图像处理的新人研究参考。该方法为差分法:首先对图像进行高斯滤波处理预处理,平滑图像数据;其次,将图像颜色通道按RGB拆分,因为识别物为绿叶,其最明显的特征就是颜色;差分法,将绿色通道减去蓝色通道,之所以选择这两个通道,是因为蓝色通道和绿叶的关系较远,而红色搭配绿色可是黄色哦,绿叶中存在黄色特征信息可是再正常不过了;之后,对差分图进行OTSU阈值处理,得到掩膜感兴趣ROI区域;再后,就是对区域进行闭运算和孔洞闭合处理,保持区域完整性;最后,根据掩膜提取绿叶,完成。

功能函数代码

1)识别绿叶函数。


// 识别绿叶
Mat IdentifyLeaves(cv::Mat input)
{
	CV_Assert(input.channels() == 3);
	Mat temp, result, mask, hole;
	int row = input.rows;
	int col = input.cols;
 
	// 高斯滤波
	GaussianBlur(input, temp, Size(5, 5), 0);
 
	// 通道拆分
	vector<cv::Mat> c;
	split(temp, c);
 
	// 绿通道-蓝通道,提取绿色区域
	Mat diff = c[1] - c[0];
	threshold(diff, mask, 0, 255, THRESH_OTSU);
 
	// 闭运算封口
	cv::Mat element = getStructuringElement(MORPH_ELLIPSE, Size(9, 9));
	cv::morphologyEx(mask, mask, MORPH_CLOSE, element);
 
	// 孔洞闭合
	hole = 255 - mask;
	Clear_MicroConnected_Areas(hole, hole, row*col / 300);
	mask = 255 - hole;
	Clear_MicroConnected_Areas(mask, mask, row*col / 300);
 
	// 识别区域标记
	result = input.clone();
	result.setTo(Scalar(0, 0, 0), mask == 0);
	return result;
}

2)清除微小面积连通区函数,用于孔洞闭合。具体介绍见:

OpenCV-清除小面积连通域



void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat &dst, double min_area)
{
	// 备份复制
	dst = src.clone();
	std::vector<std::vector<cv::Point> > contours;  // 创建轮廓容器
	std::vector<cv::Vec4i> 	hierarchy;
 
	// 寻找轮廓的函数
	// 第四个参数CV_RETR_EXTERNAL,表示寻找最外围轮廓
	// 第五个参数CV_CHAIN_APPROX_NONE,表示保存物体边界上所有连续的轮廓点到contours向量内
	cv::findContours(src, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
 
	if (!contours.empty() && !hierarchy.empty())
	{
		std::vector<std::vector<cv::Point> >::const_iterator itc = contours.begin();
		// 遍历所有轮廓
		while (itc != contours.end())
		{
			// 定位当前轮廓所在位置
			cv::Rect rect = cv::boundingRect(cv::Mat(*itc));
			// contourArea函数计算连通区面积
			double area = contourArea(*itc);
			// 若面积小于设置的阈值
			if (area < min_area)
			{
				// 遍历轮廓所在位置所有像素点
				for (int i = rect.y; i < rect.y + rect.height; i++)
				{
					uchar *output_data = dst.ptr<uchar>(i);
					for (int j = rect.x; j < rect.x + rect.width; j++)
					{
						// 将连通区的值置0
						if (output_data[j] == 255)
						{
							output_data[j] = 0;
						}
					}
				}
			}
			itc++;
		}
	}
}

C++测试代码


#include <iOStream>
#include <opencv2/opencv.hpp>
 
using namespace std;
using namespace cv;
 
void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat &dst, double min_area);
Mat IdentifyLeaves(cv::Mat input);
 
int main()
{
	Mat src = imread("test1.png");
	Mat result = IdentifyLeaves(src);
 
	imshow("src", src);
	imshow("result", result);
	waiTKEy(0);
 
	return 0;
}
 

void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat &dst, double min_area)
{
	// 备份复制
	dst = src.clone();
	std::vector<std::vector<cv::Point> > contours;  // 创建轮廓容器
	std::vector<cv::Vec4i> 	hierarchy;
 
	// 寻找轮廓的函数
	// 第四个参数CV_RETR_EXTERNAL,表示寻找最外围轮廓
	// 第五个参数CV_CHAIN_APPROX_NONE,表示保存物体边界上所有连续的轮廓点到contours向量内
	cv::findContours(src, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
 
	if (!contours.empty() && !hierarchy.empty())
	{
		std::vector<std::vector<cv::Point> >::const_iterator itc = contours.begin();
		// 遍历所有轮廓
		while (itc != contours.end())
		{
			// 定位当前轮廓所在位置
			cv::Rect rect = cv::boundingRect(cv::Mat(*itc));
			// contourArea函数计算连通区面积
			double area = contourArea(*itc);
			// 若面积小于设置的阈值
			if (area < min_area)
			{
				// 遍历轮廓所在位置所有像素点
				for (int i = rect.y; i < rect.y + rect.height; i++)
				{
					uchar *output_data = dst.ptr<uchar>(i);
					for (int j = rect.x; j < rect.x + rect.width; j++)
					{
						// 将连通区的值置0
						if (output_data[j] == 255)
						{
							output_data[j] = 0;
						}
					}
				}
			}
			itc++;
		}
	}
}
 
// 识别绿叶
Mat IdentifyLeaves(cv::Mat input)
{
	CV_Assert(input.channels() == 3);
	Mat temp, result, mask, hole;
	int row = input.rows;
	int col = input.cols;
 
	// 高斯滤波
	GaussianBlur(input, temp, Size(5, 5), 0);
 
	// 通道拆分
	vector<cv::Mat> c;
	split(temp, c);
 
	// 绿通道-蓝通道,提取绿色区域
	Mat diff = c[1] - c[0];
	threshold(diff, mask, 0, 255, THRESH_OTSU);
 
	// 闭运算封口
	cv::Mat element = getStructuringElement(MORPH_ELLIPSE, Size(9, 9));
	cv::morphologyEx(mask, mask, MORPH_CLOSE, element);
 
	// 孔洞闭合
	hole = 255 - mask;
	Clear_MicroConnected_Areas(hole, hole, row*col / 300);
	mask = 255 - hole;
	Clear_MicroConnected_Areas(mask, mask, row*col / 300);
 
	// 识别区域标记
	result = input.clone();
	result.setTo(Scalar(0, 0, 0), mask == 0);
	return result;
}

测试效果

图1 原图1

图2 效果图1

图3 原图2

图4 效果图2

图5 原图3

图6 效果图3

本文只是提供了一种简单的识别思路,不可能满足所有的场景。举几个例子,如图6所示,因为孔洞闭合的缘故,导致绿叶间的间隙也被涵盖了;又或者,当所识别的绿叶没那么绿,有点偏暗时,蓝色通道的比例自然也提高了,此时用差分法效果就不会那么好了。

总而言之,不同的场景和需求还是需要结合实际进行算法的设计,天下没有一种算法是可以解决一切问题的,即便是人工智能也不可能,特殊问题特殊对待,加油!

到此这篇关于基于OpenCV 差分法实现绿叶识别(图像差分+颜色通道)的文章就介绍到这了,更多相关OpenCV 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 基于OpenCV 差分法实现绿叶识别

本文链接: https://www.lsjlt.com/news/158271.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 基于OpenCV 差分法实现绿叶识别
    目录实现原理功能函数代码C++测试代码实现原理 物体识别是图像处理学在现实生活中较多的应用之一,目前最为流行的就是运用AI、机器学习等技术结合图像处理学,大量训练数据集,以实现智能且...
    99+
    2022-11-12
  • 基于MatlabLBP实现植物叶片识别功能
    目录一、LBP简介1.1 课题的提出与研究意义1.2 国内外相关研究情况1.3 论文的主要研究工作1.4 论文结构二、部分源代码三、运行结果一、LBP简介 第一章 引言 植物在我们的...
    99+
    2022-11-13
  • Qt+OpenCV利用帧差法实现车辆识别
    目录一、目标二、使用Qt界面三、代码实现一、目标 Qt界面实现 点击 线程启动按钮播放视频 左边界面显示原视频 右边界面显示车辆识别视频 结果展示如下: 初始界面 点击线程启动后,...
    99+
    2022-11-13
    Qt OpenCV 帧差法 车辆识别 Qt OpenCV 车辆识别 Qt OpenCV 帧差法
  • 基于python3+OpenCV实现人脸和眼睛识别
    基于python3+OpenCV的人脸和眼睛识别,供大家参考,具体内容如下 一、OpenCV人脸检测的xml文件下载 人脸检测和眼睛检测要用到haarcascade_eye.xml和...
    99+
    2022-11-12
  • C++基于OpenCV实现手势识别的源码
    先给大家上效果图: 源码在下面 使用 RGB 值分割手部区域,即手部的 GB 值将与背景不同 或者使用边缘检测 或者 背景减法。  我这里使用了背景减法模型。OpenC...
    99+
    2022-11-12
  • Python+OpenCV实现基于颜色的目标识别
    目录任务主要代码效果展示学习了一点opencv的知识于是找了个小项目来实践一下。这里先说明一下,我的实现方法不见得是最好的(因为这只是一个用于练习的项目)仅作参考,也欢迎各位大佬指正...
    99+
    2022-11-12
  • Python中基于Opencv怎么实现人脸识别
    这篇文章主要讲解了“Python中基于Opencv怎么实现人脸识别”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python中基于Opencv怎么实现人脸识别”吧!检测人脸。这应该是最基本的...
    99+
    2023-06-02
  • 基于Opencv图像识别实现答题卡识别示例详解
    目录1. 项目分析2.项目实验3.项目结果总结在观看唐宇迪老师图像处理的课程中,其中有一个答题卡识别的小项目,在此结合自己理解做一个简单的总结。 1. 项目分析 首先在拿到项目时候,...
    99+
    2022-11-12
  • 如何基于opencv实现简单的数字识别
    目录前言要解决的问题解决问题的思路总结前言 由于自己学识尚浅,不能用python深度学习来识别这里的数字,所以就完全采用opencv来识别数字,然后在这里分享、记录一下自己在学习过程...
    99+
    2022-11-12
  • 基于opencv+java实现简单图形识别程序
    目录前言方法如下总结前言 OpenCV的 全称是:Open Source Computer Vision Library。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视...
    99+
    2022-11-13
  • 基于opencv和pillow实现人脸识别系统(附demo)
    目录一。人脸检测和数据收集二.训练识别器三.人脸识别和显示本文不涉及分类器、训练识别器等算法原理,仅包含对其应用(未来我也会写自己对机器学习算法原理的一些观点和了解) 首先我们需要知...
    99+
    2022-11-12
  • 基于opencv实现视频中的颜色识别功能
    目录颜色识别的原理opencv中的颜色模型颜色识别的实现(c++)颜色识别的原理 opencv中的颜色模型 RGB RGB具有三个通道其,分别表示红色通道®,绿色通道(G),...
    99+
    2022-11-13
  • 基于opencv和pillow怎么实现人脸识别系统
    这篇文章主要讲解了“基于opencv和pillow怎么实现人脸识别系统”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于opencv和pillow怎么实现人脸识别系统”吧!本文不涉及分类器、...
    99+
    2023-06-21
  • Python+OpenCV如何实现基于颜色的目标识别
    这篇文章给大家介绍Python+OpenCV如何实现基于颜色的目标识别,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。任务让摄像头识别到视野范围内的气球并返回每个气球的中心点坐标。因为场地固定,背景单一,所以省下来很多操...
    99+
    2023-06-22
  • opencv案例03 -基于OpenCV实现二维码生成,发现,定位,识别
    1.二维码的生成 废话不多说,直接上代码 # 生成二维码import qrcode# 二维码包含的示例数据data = "B0018"# 生成的二维码图片名称filename = "qrcode.png"# 生成二维码img = qrcod...
    99+
    2023-08-30
    opencv 人工智能 计算机视觉
  • Python基于opencv实现的人脸识别(适合初学者)
    目录一点背景知识一、人脸识别步骤 二、直接上代码(1)录入人脸.py(2)数据训练.py(3)进行识别.py三、运行过程及结果1、获取人脸照片于目标文件中2、进行数据训练,...
    99+
    2022-11-13
  • 基于OpenCV和Gradio实现简单的人脸识别详解
    目录环境配置实验原理程序设计1.上传图片2.人脸识别3.绘制方框4.保存预测结果5.最后运行gradio的lauch完整代码环境配置 gradio 安装 pip install gr...
    99+
    2023-05-14
    OpenCV Gradio实现人脸识别 OpenCV Gradio人脸识别 OpenCV Gradio
  • 基于OpenCV和Gradio怎么实现简单的人脸识别
    今天小编给大家分享一下基于OpenCV和Gradio怎么实现简单的人脸识别的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。环境...
    99+
    2023-07-05
  • OpenCV基于分水岭算法的图像分割怎么实现
    本文小编为大家详细介绍“OpenCV基于分水岭算法的图像分割怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“OpenCV基于分水岭算法的图像分割怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1. ...
    99+
    2023-07-05
  • 基于OpenCV(python)的实现文本分割之垂直投影法
    在我的上一篇博客中讲述了水平投影法取出文本行图像的实现,在这里将用垂直投影法对文本行的每个字符进行分割。下图是用水平投影法切割的文本行: 文本分割的原理如下,先用水平投影取出单一文...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作