欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于OpenCV?差分法實(shí)現(xiàn)綠葉識(shí)別

 更新時(shí)間:2021年11月24日 15:16:24   作者:翟天保Steven  
物體識(shí)別是圖像處理學(xué)在現(xiàn)實(shí)生活中較多的應(yīng)用之一,本文提供了一種相對(duì)簡(jiǎn)單的思路來(lái)實(shí)現(xiàn)綠葉識(shí)別,適合初學(xué)圖像處理的新人研究參考。感興趣的同學(xué)可以關(guān)注一下

實(shí)現(xiàn)原理

物體識(shí)別是圖像處理學(xué)在現(xiàn)實(shí)生活中較多的應(yīng)用之一,目前最為流行的就是運(yùn)用AI、機(jī)器學(xué)習(xí)等技術(shù)結(jié)合圖像處理學(xué),大量訓(xùn)練數(shù)據(jù)集,以實(shí)現(xiàn)智能且精確的識(shí)別。說(shuō)到人工智能,很多人可能覺(jué)得它非常深?yuàn)W和復(fù)雜,其實(shí)說(shuō)白了它最底層的識(shí)別邏輯還是基于普通的圖像分析,像特征提取、輪廓分析、比對(duì)分析等等,再在龐大的數(shù)據(jù)集中按照相似程度,分析出一個(gè)最可能的結(jié)果。

本文提供了一種相對(duì)簡(jiǎn)單的思路來(lái)實(shí)現(xiàn)綠葉識(shí)別,適合初學(xué)圖像處理的新人研究參考。該方法為差分法:首先對(duì)圖像進(jìn)行高斯濾波處理預(yù)處理,平滑圖像數(shù)據(jù);其次,將圖像顏色通道按RGB拆分,因?yàn)樽R(shí)別物為綠葉,其最明顯的特征就是顏色;差分法,將綠色通道減去藍(lán)色通道,之所以選擇這兩個(gè)通道,是因?yàn)樗{(lán)色通道和綠葉的關(guān)系較遠(yuǎn),而紅色搭配綠色可是黃色哦,綠葉中存在黃色特征信息可是再正常不過(guò)了;之后,對(duì)差分圖進(jìn)行OTSU閾值處理,得到掩膜感興趣ROI區(qū)域;再后,就是對(duì)區(qū)域進(jìn)行閉運(yùn)算和孔洞閉合處理,保持區(qū)域完整性;最后,根據(jù)掩膜提取綠葉,完成。

功能函數(shù)代碼

1)識(shí)別綠葉函數(shù)。

// 識(shí)別綠葉
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);
 
	// 綠通道-藍(lán)通道,提取綠色區(qū)域
	Mat diff = c[1] - c[0];
	threshold(diff, mask, 0, 255, THRESH_OTSU);
 
	// 閉運(yùn)算封口
	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);
 
	// 識(shí)別區(qū)域標(biāo)記
	result = input.clone();
	result.setTo(Scalar(0, 0, 0), mask == 0);
	return result;
}

2)清除微小面積連通區(qū)函數(shù),用于孔洞閉合。具體介紹見(jiàn):

OpenCV-清除小面積連通域

/**
* @brief  Clear_MicroConnected_Areas         清除微小面積連通區(qū)函數(shù)
* @param  src                                輸入圖像矩陣
* @param  dst                                輸出結(jié)果
* @return min_area                           設(shè)定的最小面積清除閾值
*/
void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat &dst, double min_area)
{
	// 備份復(fù)制
	dst = src.clone();
	std::vector<std::vector<cv::Point> > contours;  // 創(chuàng)建輪廓容器
	std::vector<cv::Vec4i> 	hierarchy;
 
	// 尋找輪廓的函數(shù)
	// 第四個(gè)參數(shù)CV_RETR_EXTERNAL,表示尋找最外圍輪廓
	// 第五個(gè)參數(shù)CV_CHAIN_APPROX_NONE,表示保存物體邊界上所有連續(xù)的輪廓點(diǎn)到contours向量?jī)?nèi)
	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())
		{
			// 定位當(dāng)前輪廓所在位置
			cv::Rect rect = cv::boundingRect(cv::Mat(*itc));
			// contourArea函數(shù)計(jì)算連通區(qū)面積
			double area = contourArea(*itc);
			// 若面積小于設(shè)置的閾值
			if (area < min_area)
			{
				// 遍歷輪廓所在位置所有像素點(diǎn)
				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++)
					{
						// 將連通區(qū)的值置0
						if (output_data[j] == 255)
						{
							output_data[j] = 0;
						}
					}
				}
			}
			itc++;
		}
	}
}

C++測(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;
}
 
/**
* @brief  Clear_MicroConnected_Areas         清除微小面積連通區(qū)函數(shù)
* @param  src                                輸入圖像矩陣
* @param  dst                                輸出結(jié)果
* @return min_area                           設(shè)定的最小面積清除閾值
*/
void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat &dst, double min_area)
{
	// 備份復(fù)制
	dst = src.clone();
	std::vector<std::vector<cv::Point> > contours;  // 創(chuàng)建輪廓容器
	std::vector<cv::Vec4i> 	hierarchy;
 
	// 尋找輪廓的函數(shù)
	// 第四個(gè)參數(shù)CV_RETR_EXTERNAL,表示尋找最外圍輪廓
	// 第五個(gè)參數(shù)CV_CHAIN_APPROX_NONE,表示保存物體邊界上所有連續(xù)的輪廓點(diǎn)到contours向量?jī)?nèi)
	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())
		{
			// 定位當(dāng)前輪廓所在位置
			cv::Rect rect = cv::boundingRect(cv::Mat(*itc));
			// contourArea函數(shù)計(jì)算連通區(qū)面積
			double area = contourArea(*itc);
			// 若面積小于設(shè)置的閾值
			if (area < min_area)
			{
				// 遍歷輪廓所在位置所有像素點(diǎn)
				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++)
					{
						// 將連通區(qū)的值置0
						if (output_data[j] == 255)
						{
							output_data[j] = 0;
						}
					}
				}
			}
			itc++;
		}
	}
}
 
// 識(shí)別綠葉
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);
 
	// 綠通道-藍(lán)通道,提取綠色區(qū)域
	Mat diff = c[1] - c[0];
	threshold(diff, mask, 0, 255, THRESH_OTSU);
 
	// 閉運(yùn)算封口
	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);
 
	// 識(shí)別區(qū)域標(biāo)記
	result = input.clone();
	result.setTo(Scalar(0, 0, 0), mask == 0);
	return result;
}

測(cè)試效果

圖1 原圖1

圖2 效果圖1

圖3 原圖2

圖4 效果圖2

圖5 原圖3

圖6 效果圖3

本文只是提供了一種簡(jiǎn)單的識(shí)別思路,不可能滿足所有的場(chǎng)景。舉幾個(gè)例子,如圖6所示,因?yàn)榭锥撮]合的緣故,導(dǎo)致綠葉間的間隙也被涵蓋了;又或者,當(dāng)所識(shí)別的綠葉沒(méi)那么綠,有點(diǎn)偏暗時(shí),藍(lán)色通道的比例自然也提高了,此時(shí)用差分法效果就不會(huì)那么好了。

總而言之,不同的場(chǎng)景和需求還是需要結(jié)合實(shí)際進(jìn)行算法的設(shè)計(jì),天下沒(méi)有一種算法是可以解決一切問(wèn)題的,即便是人工智能也不可能,特殊問(wèn)題特殊對(duì)待,加油!

到此這篇關(guān)于基于OpenCV 差分法實(shí)現(xiàn)綠葉識(shí)別(圖像差分+顏色通道)的文章就介紹到這了,更多相關(guān)OpenCV 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)學(xué)生學(xué)籍管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)學(xué)生學(xué)籍管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)生學(xué)籍管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • VSstudio中scanf返回值被忽略的原因及解決方法(推薦)

    VSstudio中scanf返回值被忽略的原因及解決方法(推薦)

    這篇文章主要介紹了VSstudio中scanf返回值被忽略的原因及其解決方法,scanf返回值被忽略,接下來(lái)我就告訴大家該如何解決這個(gè)問(wèn)題,需要的朋友可以參考下
    2022-09-09
  • OpenMP 共享內(nèi)存的并行編程框架入門詳解

    OpenMP 共享內(nèi)存的并行編程框架入門詳解

    這篇文章主要為大家介紹了OpenMP 共享內(nèi)存的并行編程框架入門詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • qt中sokect斷開(kāi)的幾種情況

    qt中sokect斷開(kāi)的幾種情況

    本文主要介紹了qt中sokect斷開(kāi)的幾種情況,文中介紹了很多情況,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • C++ const關(guān)鍵字分析詳解

    C++ const關(guān)鍵字分析詳解

    C++中的const關(guān)鍵字的用法非常靈活,而使用const將大大改善程序的健壯性。這篇文章主要介紹了C/C++ 中const關(guān)鍵字的用法,需要的朋友可以參考下
    2021-08-08
  • QT5實(shí)現(xiàn)UDP通信的示例代碼

    QT5實(shí)現(xiàn)UDP通信的示例代碼

    本文主要介紹了QT5實(shí)現(xiàn)UDP通信的示例代碼,主要使用QUdpSocket類用于實(shí)現(xiàn)UDP通信,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • C++非遞歸遍歷磁盤文件和遞歸遍歷磁盤文件的程序示例

    C++非遞歸遍歷磁盤文件和遞歸遍歷磁盤文件的程序示例

    這篇文章主要介紹了C++非遞歸遍歷磁盤文件和遞歸遍歷磁盤文件的程序示例,大家可以參考使用二種方法
    2013-11-11
  • C++代碼實(shí)現(xiàn)逆波蘭式

    C++代碼實(shí)現(xiàn)逆波蘭式

    這篇文章主要為大家詳細(xì)介紹了C++代碼實(shí)現(xiàn)逆波蘭式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • 淺析C/C++中被人誤解的SIZEOF

    淺析C/C++中被人誤解的SIZEOF

    以下是對(duì)C/C++中的SIZEOF進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • 五個(gè)經(jīng)典鏈表OJ題帶你進(jìn)階C++鏈表篇

    五個(gè)經(jīng)典鏈表OJ題帶你進(jìn)階C++鏈表篇

    做題之前呢,小編想提醒下大家,要三思而后行,不要一上來(lái)就嘎嘎敲代碼,要先學(xué)會(huì)自己畫(huà)圖分析,把自己的思路捋清楚,不要到時(shí)候?qū)懘a五分鐘,調(diào)試兩小時(shí),記住,編程思路很重要
    2022-03-03

最新評(píng)論