opencv 二值圖像剔除小連通區域


二值圖像剔除小面積連通區域在二值圖像連通區域分析時很有用,之前做的使用采用了for循環的形式,后來學習了c++標准庫,發現可以使用vector.erase(std::remove_if())的方法, 結合lambda表達式直接剔除。

統計二值圖像的連通區域通過cv::findcontours()實現,二值圖像輪廓的容器是std::vector。連通區域的面積可以由函數cv::contourArea()得到。

剔除小面積連通區域后,可以使用函數cv::drawContours()函數將輪廓畫出,將其第三個參數設置為-1為畫所有輪廓,將其第5個參數設置為cv::FILLED設置為填充。則可以得到剔除后小面積連通后的二值圖像。

#include <opencv2/opencv.hpp>
#include <vector>
#include <algorithm>

int main()
{
	cv::Mat img = cv::imread("data/000000000597.jpg");
	cv::Mat imgHSV(img.size(), img.type());
	cv::cvtColor(img, imgHSV, cv::COLOR_BGR2HSV);
	cv::Mat imgHSVMask(img.size(), CV_8UC1);
	// yellow color region
	cv::inRange(imgHSV, cv::Scalar(11, 43, 46), cv::Scalar(26, 255, 255), imgHSVMask);
	
	char *win1 = "original mask";	char *win2 = "after remove";
	cv::namedWindow(win1);	cv::moveWindow(win1, 10, 10);
	cv::namedWindow(win2);	cv::moveWindow(win2, 800, 10);
	
	cv::imshow(win1, imgHSVMask);	cv::waitKey(0); 	cv::destroyWindow(win1);	cv::imwrite("data/original.png", imgHSVMask);

	// 提取連通區域,並剔除小面積聯通區域
	std::vector<std::vector<cv::Point>> contours;
	cv::findContours(imgHSVMask, contours, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
	contours.erase(std::remove_if(contours.begin(), contours.end(), 
		[](const std::vector<cv::Point>& c){return cv::contourArea(c) < 30; }), contours.end());

	// 顯示圖像並保存
	imgHSVMask.setTo(0);
	cv::drawContours(imgHSVMask, contours, -1, cv::Scalar(255), cv::FILLED);
	cv::imshow(win2, imgHSVMask);	cv::waitKey(0);	cv::destroyWindow(win2);	cv::imwrite("data/remove.png", imgHSVMask);
	return 0;
}

原圖像為:

剔除前

剔除后


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM