OpenCV清除小面積連通域的實(shí)現(xiàn)方法
場景需求
使用OpenCV,往往遇到這類場景:需要清除目標(biāo)圖像中比較小的噪聲區(qū),保留主要區(qū)域信息。
特此分享自己寫的一個(gè)簡單的清除小面積連通域函數(shù),邏輯比較簡單,給大家留出了足夠的發(fā)展空間,根據(jù)自身場景需求進(jìn)行調(diào)整。
原理可以簡單歸結(jié)為:搜索圖像的連通區(qū)輪廓->遍歷各個(gè)連通區(qū)->基于閾值刪除面積較小的連通區(qū)
運(yùn)行速度方面,我沒單獨(dú)測試過這個(gè)單元,大家如果試過之后太慢可以評論告訴我哦~
反正平常我工作跑那種2000*2000的圖像,這個(gè)函數(shù)的耗時(shí)幾乎忽略不計(jì)。。。
C++實(shí)現(xiàn)代碼
/**
* @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向量內(nèi)
cv::findContours(src, contours, hierarchy, cv::RETR_EXTERNAL, 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++;
}
}
}
測試代碼
#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);
int main(void)
{
Mat A = Mat::zeros(500, 500, CV_8UC1);
circle(A, Point2i(100, 100), 50, 255, -1);
circle(A, Point2i(300, 400), 15, 255, -1);
Mat B;
Clear_MicroConnected_Areas(A, B, 1000);
imshow("before:A", A);
imshow("after:B", B);
waitKey(0);
system("pause");
return 0;
}
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向量內(nèi)
cv::findContours(src, contours, hierarchy, cv::RETR_EXTERNAL, 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++;
}
}
}
測試效果
圖1 處理前后圖
到此這篇關(guān)于OpenCV-清除小面積連通域的文章就介紹到這了,更多相關(guān)OpenCV-清除小面積連通域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python創(chuàng)造虛擬環(huán)境方法總結(jié)
在本篇內(nèi)容里我們給大家整理了關(guān)于python創(chuàng)造虛擬環(huán)境的詳細(xì)方法和步驟,需要的朋友們學(xué)習(xí)下。2019-03-03
python實(shí)現(xiàn)屏保計(jì)時(shí)器的示例代碼
這篇文章主要介紹了python實(shí)現(xiàn)屏保計(jì)時(shí)器的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
Python異步與定時(shí)任務(wù)提高程序并發(fā)性和定時(shí)執(zhí)行效率
Python異步與定時(shí)任務(wù)是Python編程中常用的兩種技術(shù),異步任務(wù)可用于高效處理I/O密集型任務(wù),提高程序并發(fā)性;定時(shí)任務(wù)可用于定時(shí)執(zhí)行計(jì)劃任務(wù),提高程序的執(zhí)行效率。這兩種技術(shù)的應(yīng)用有助于提升Python程序的性能和效率2023-05-05
在Python下使用Txt2Html實(shí)現(xiàn)網(wǎng)頁過濾代理的教程
這篇文章主要介紹了在Python下使用Txt2Html實(shí)現(xiàn)網(wǎng)頁過濾代理的教程,來自IBM官方開發(fā)者技術(shù)文檔,需要的朋友可以參考下2015-04-04
Python?中的?Counter?模塊及使用詳解(搞定重復(fù)計(jì)數(shù))
Counter 是一個(gè)簡單的計(jì)數(shù)器,用于統(tǒng)計(jì)某些可哈希對象的數(shù)量。它以字典的形式存儲(chǔ)元素和它們的計(jì)數(shù),這篇文章主要介紹了Python?中的?Counter?模塊及使用詳解(搞定重復(fù)計(jì)數(shù)),需要的朋友可以參考下2023-04-04

