OpenCV-清除小面积连通域

简介: OpenCV-清除小面积连通域

场景需求

      使用OpenCV,往往遇到这类场景:需要清除目标图像中比较小的噪声区,保留主要区域信息。


      特此分享自己写的一个简单的清除小面积连通域函数,逻辑比较简单,给大家留出了足够的发展空间,根据自身场景需求进行调整。


      原理可以简单归结为:搜索图像的连通区轮廓->遍历各个连通区->基于阈值删除面积较小的连通区


      运行速度方面,我没单独测试过这个单元,大家如果试过之后太慢可以评论告诉我哦~


      反正平常我工作跑那种2000*2000的图像,这个函数的耗时几乎忽略不计。。。

C++实现代码

/**
* @brief  Clear_MicroConnected_Areas         清除微小面积连通区函数
* @param  src                                输入图像矩阵
* @param  dst                                输出结果
* @return min_area                           设定的最小面积清除阈值
*/
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_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()) 
    {
      // 定位当前轮廓所在位置
      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++;
    }
  }
}

测试代码

#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)
{
  // 备份复制
  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_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()) 
    {
      // 定位当前轮廓所在位置
      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++;
    }
  }
}

测试效果

图1 处理前后图

      如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章
|
8月前
|
人工智能 算法 Ubuntu
【案例实战】 基于OpenCV实现鹿茸面积计算
有人询问如何计算鹿茸蜡皮面积占比。利用OpenCV实验大师工具软件,经过图像处理步骤(包括边缘检测、轮廓识别),成功计算出两个区域的面积,展示了一步到位的OpenCV解决方案。OEMTS软件旨在促进数字图像处理教学,助力成为合格的OpenCV开发者。详情见课程链接和OEMTS安装指南。
86 0
|
计算机视觉
OpenCV-计算轮廓面积cv::contourArea
OpenCV-计算轮廓面积cv::contourArea
301 0
|
9月前
|
存储 算法 数据可视化
|
9月前
|
计算机视觉
OpenCV(三十三):计算轮廓面积与轮廓长度
OpenCV(三十三):计算轮廓面积与轮廓长度
330 0
|
9月前
|
计算机视觉
OpenCV(二十八):连通域分割
OpenCV(二十八):连通域分割
378 0
|
4月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
922 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
5月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
76 4
|
5月前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
|
6月前
|
算法 计算机视觉 Python
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
该文章详细介绍了使用Python和OpenCV进行相机标定以获取畸变参数,并提供了修正图像畸变的全部代码,包括生成棋盘图、拍摄标定图像、标定过程和畸变矫正等步骤。
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
WK
|
6月前
|
编解码 计算机视觉 Python
如何在OpenCV中进行图像转换
在OpenCV中,图像转换涉及颜色空间变换、大小调整及类型转换等操作。常用函数如`cvtColor`可实现BGR到RGB、灰度图或HSV的转换;`resize`则用于调整图像分辨率。此外,通过`astype`或`convertScaleAbs`可改变图像数据类型。对于复杂的几何变换,如仿射或透视变换,则可利用`warpAffine`和`warpPerspective`函数实现。这些技术为图像处理提供了强大的工具。
WK
181 1