OpenCV删除面积小的区域 实现图像二值化分割 标记连通区域
   【尊重原创,转载请注明出处】http://blog.csdn.net/guyuealian/article/details/78142749
   之前本博客在Matlab实现了《Matlab形态学图像处理:二值图像分割 标记连通区域和重心位置 删除连通区域》http://blog.csdn.net/guyuealian/article/details/71440949,现在本人使用OpenCV实现这一功能:对图像进行二值化分割,并用“红色矩形”标记连通区域的面积,为了减少噪声的干扰,删除面积小的区域,代码中将连通区域面积(像素个数)不足100的区域认为是噪声点,并将其删除(即置为背景黑色)。本人制作了一个GIF动画图,以便大家观看效果图:

OpenCV参考代码如下:

#include "stdafx.h"
#include <iostream>
#include<vector>
#include<algorithm>
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;//轮廓按照面积大小升序排序
bool ascendSort(vector<Point> a, vector<Point> b) {return a.size() < b.size();}//轮廓按照面积大小降序排序
bool descendSort(vector<Point> a, vector<Point> b) {return a.size() > b.size();
}
int main() {Mat srcImage = imread("D:\\OpencvTest\\123.jpg");Mat thresholdImage;Mat grayImage;cvtColor(srcImage, grayImage, CV_BGR2GRAY);threshold(grayImage, thresholdImage, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);//Mat resultImage;//thresholdImage.copyTo(resultImage);vector< vector< Point> > contours;  //用于保存所有轮廓信息vector< vector< Point> > contours2; //用于保存面积不足100的轮廓vector<Point> tempV;              //暂存的轮廓findContours(thresholdImage, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);//cv::Mat labels;//int N = connectedComponents(resultImage, labels, 8, CV_16U);//findContours(labels, contours2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);//轮廓按照面积大小进行升序排序sort(contours.begin(), contours.end(), ascendSort);//升序排序vector<vector<Point> >::iterator itc = contours.begin();int i = 0;while (itc != contours.end()){//获得轮廓的矩形边界Rect rect = boundingRect(*itc);int x = rect.x;int y = rect.y;int w = rect.width;int h = rect.height;//绘制轮廓的矩形边界cv::rectangle(srcImage, rect, { 0, 0, 255 }, 1);//保存图片char str[10];sprintf(str, "%d.jpg", i++);cv::imshow("srcImage", srcImage);imwrite(str, srcImage);waitKey(1000);if (itc->size() < 100){//把轮廓面积不足100的区域,放到容器contours2中,tempV.push_back(Point(x, y));tempV.push_back(Point(x, y+h));tempV.push_back(Point(x+w, y+h));tempV.push_back(Point(x+w, y));contours2.push_back(tempV);/*也可以直接用:contours2.push_back(*itc);代替上面的5条语句*///contours2.push_back(*itc);//删除轮廓面积不足100的区域,即用黑色填充轮廓面积不足100的区域:cv::drawContours(srcImage, contours2, -1, Scalar(0,0,0), CV_FILLED);}//保存图片sprintf(str, "%d.jpg", i++);cv::imshow("srcImage", srcImage);imwrite(str, srcImage);cv::waitKey(100);tempV.clear();++itc;}return 0;
}

【2】findContours的用法:

using namespace std;
using namespace cv;
using namespace cv::xphoto;
#include "stdafx.h"
#include <iostream>
#include<vector>
#include<algorithm>
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;//轮廓按照面积大小升序排序
bool ascendSort(vector<Point> a, vector<Point> b) {return a.size() < b.size();}//轮廓按照面积大小降序排序
bool descendSort(vector<Point> a, vector<Point> b) {return a.size() > b.size();
}//自己实现的将灰度图像转为三通道的BGR图像
cv::Mat gray2BGR(cv::Mat grayImg) {if (grayImg.channels() == 3)return grayImg;cv::Mat bgrImg = cv::Mat::zeros(grayImg.size(), CV_8UC3);std::vector<cv::Mat> bgr_channels;cv::split(bgrImg, bgr_channels);bgr_channels.at(0) = grayImg;bgr_channels.at(1) = grayImg;bgr_channels.at(2) = grayImg;cv::merge(bgr_channels, bgrImg);return bgrImg;
}//自定义的drawImage函数的功能类似于OpenCV的drawContours函数
cv::Mat drawImage(cv::Mat image, vector< vector< Point> > pointV) {cv::Mat destImage=image.clone();if (destImage.channels()==1){destImage = gray2BGR(destImage);}for (size_t i=0;i<pointV.size();i++){for (size_t j = 0; j<pointV.at(i).size(); j++){cv::Point point = pointV.at(i).at(j);destImage.at<Vec3b>(point) = cv::Vec3b(0, 0, saturate_cast<uchar>(255-i*5));}}return destImage;
}
int main() {Mat srcImage = imread("D:\\OpencvTest\\mask5.jpg");cv::imshow("srcImage", srcImage);Mat thresholdImage;Mat grayImage;cvtColor(srcImage, grayImage, CV_BGR2GRAY);threshold(grayImage, thresholdImage, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);cv::Mat mask = thresholdImage.clone();//(1)CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLEvector< vector< Point> > contours1;findContours(mask, contours1, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);cv::Mat destImage = drawImage(mask, contours1);imshow("destImage", destImage);//(2)CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONEvector< vector< Point> > contours2; findContours(mask, contours2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);cv::Mat destImage2 = drawImage(mask, contours2);imshow("destImage2", destImage2);//(3)CV_RETR_LIST, CV_CHAIN_APPROX_NONEvector< vector< Point> > contours3; findContours(mask, contours3, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);cv::Mat destImage3 = drawImage(mask, contours3);imshow("destImage3", destImage3);//(4)CV_RETR_CCOMP, CV_CHAIN_APPROX_NONEvector< vector< Point> > contours4;findContours(mask, contours4, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);cv::Mat destImage4 = drawImage(mask, contours4);imshow("destImage4", destImage4);//cv::Mat imge2 = gray2BGR(mask);//drawContours(imge2, contours4, -1, cv::Scalar(0, 0, 255), 1);//cv::fillConvexPoly(mask, contours1.at(0), cv::Scalar(255, 255, 255));cv::waitKey(0);return 0;
}

如果你觉得该帖子帮到你,还望贵人多多支持,鄙人会再接再厉,继续努力的~

OpenCV删除面积小的区域 实现图像二值化分割 标记连通区域相关推荐

  1. 基于ImagePy工具的岩块图像二值化分割研究

    看到自己一年前在知乎提的问题了,忍不住回答下. 下面这个是论文录用后修改稿,文末有编辑的评语. 基于ImagePy工具的岩块图像二值化分割研究 摘 要:在岩块图像分析识别前的预处理工作中,为了平滑岩块 ...

  2. OTSU_图像二值化分割阈值的算法

    简介: 大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出.从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景 ...

  3. otsu阈值分割算法原理_OTSU_图像二值化分割阈值的算法

    简介: 大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出.从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景 ...

  4. 图像二值化分割阈值的算法——OTSU

    该算法叫做大津算法,由日本学者大津于1979年提出. 该算法的核心在于 前景与背景图像的类间方差最大 MATLAB代码 clear all clcI = imread('1.jpg'); I = rg ...

  5. 图像二值化(Image Binarization):平均值法、双峰法、大津算法(OTSU)

    图像二值化(Image Binarization):平均值法.双峰法.大津算法(OTSU) 编程实现图像的二值化,分析不同的阈值对二值化图像的影响. 问题描述 传统的机器视觉通常包括两个步骤:预处理和 ...

  6. OpenCV学习笔记(三)——图像像素(图像的最大(小)值、均值、标准差、比较运算、逻辑运算、图像二值化)

    目录 1 图像像素统计 1.1 图像像素的最大值和最小值 1.2 计算图像的均值和标准差 2 两图像间的像素操作 2.1 比较运算 2.2 逻辑运算 3 图像二值化 1 图像像素统计 数字图像可以用大 ...

  7. python opencv二值化图像_python opencv,读取彩色图像,提取三通道,图像二值化,提取图像的边缘...

    python opencv,读取彩色图像,提取三通道,图像二值化,提取图像的边缘 python opencv 1,读取图像 2,图像变矩阵 3,图像转灰度图像 4,彩色图像是3D数组 5,灰度图像是2 ...

  8. opencv进阶学习9:图像阈值大全,图像二值化,超大图像二值化

    基础版笔记链接: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 基础版二值化讲解 opencv ...

  9. Matlab形态学图像处理:二值图像分割 标记连通区域和重心位置 删除连通区域

    Matlab形态学图像处理:二值图像分割 标记连通区域和重心位置 删除连通区域 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/detail ...

最新文章

  1. 为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门)
  2. IEEE迎来首位华人主席,马里兰大学终身教授刘国瑞当选
  3. 解决报错:error: function declaration isn’t a prototype [-Werror=strict-prototypes]
  4. mysql 冷热数据分离_elasticsearch冷热数据读写分离
  5. 计算机操作系统:处理机的调度
  6. python对大量数据去重_Python对多属性的重复数据去重实例
  7. Intent七在属性之一:ComponentName
  8. wx.checkjsapi是写在config里面吗_用Python写一个程序,解密游戏内抽奖的秘密
  9. 天池在线编程 2020年9月26日 日常周赛题解
  10. 使用 加载 顺序_SpringBoot系列教程之Bean加载顺序之错误使用姿势辟谣
  11. Maven的核心笔记(2)原生:HelloWorldMaven
  12. 浅谈计算机教学论文,浅谈计算机在教学中的作用_优秀论文
  13. IntelliJ IDEA 2018.2.2及以下版本破解方法
  14. java读取视频时长
  15. 关于登录chkdsk的方法
  16. [转载] Python字典及基本操作(超级详细)
  17. 电脑全能工具箱,400+工具免费用
  18. 各种音视频编解码学习详解之 编解码学习笔记(七):微软Windows Media系列
  19. VB6实现网页自动化方法(chrome或360极速版)
  20. 三星s9刷android9,三星S9港版安卓9rom系统线刷包:TGY-G9600ZHU5CSG8-刷机之家

热门文章

  1. Spring Web MVC 随笔
  2. 部署承载于 Internet 信息服务中的 WCF 服务
  3. 现在已经到了考虑云计算的时候
  4. notepad++的NppFTP插件远程连接linux操作系统
  5. shell-grep命令详解(转)
  6. 华为OJ平台——放苹果(典型整数划分问题)
  7. Effective C# 原则50:了解ECMA标准(译)
  8. BeanUtils.copyProperties 需要getset方法支持
  9. Maven与IDEA结合
  10. AngularJS 无限滚动加载数据控件 ngInfiniteScroll