按面积选择区域 select_shape

二值化为了减少噪声的干扰,删除面积小的区域,代码中将连通区域面积(像素个数)不足100的区域认为是噪声点,并将其删除(即置为背景黑色)。

#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;
}

填充空洞 fill_up

有的时候,我们需要对图像进行孔洞填充,一般想到的方法都是,使用findcontours函数,查找最外层轮廓,然后画出找到的轮廓。

这确实是一种方法,但似乎不够高效。下面贴出一个函数,可以更好的实现这个功能。

void fillHole(const cv::Mat srcimage, cv::Mat &dstimage)
{Size m_Size = srcimage.size();Mat tempImage = Mat::zeros(m_Size.height + 2, m_Size.width + 2, srcimage.type());//延展图像  srcimage.copyTo(temimage(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)));floodFill(temimage, Point(0, 0), Scalar(255));Mat cutImg;//裁剪延展的图像  tempImage(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)).copyTo(cutImg);dstimage = srcimage | (~cutImg);
}


排序 sort_contour

按照x、y、面积排序

/**
* @brief 排序
* @param inputContours    输入轮廓
* @param outputContours   输出轮廓
* @param sortType   排序类型:0-按x排序,1-按y排序,2-按面积排序
* @param sortOrder   排序方式:true-升序,false-降序
*
* @return 返回说明
*     -<em>false</em> fail
*     -<em>true</em> succeed
*/
void  CTestCvDlg::SortContourPoint(vector<vector<Point>> inputContours, vector<vector<Point>> &outputContours, int sortType, bool sortOrder)
{vector<Point> tempContoursPoint;//计算轮廓矩  vector<Moments> mu(inputContours.size());//计算轮廓的质心    vector<Point2f> mc(inputContours.size());//计算轮廓的面积double area, area1;//2.2 定义Rect类型的vector容器roRect存放最小外接矩形,初始化大小为contours.size()即轮廓个数  vector<RotatedRect> roRect(inputContours.size());//计算轮廓最小外接矩形中心Point center, center1;for (int i = 0; i < inputContours.size(); i++){tempContoursPoint.clear();    //每次循环注意清空mu[i] = moments(inputContours[i], false); //轮廓矩mc[i] = Point2d(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00); //轮廓质心area = inputContours[i].size(); //轮廓点数area = contourArea(inputContours[i], false); //轮廓的面积//旋转矩形主要成员有center、size、 angle、points()roRect[i] = minAreaRect(Mat(inputContours[i]));center = roRect[i].center; //轮廓最小外接矩形中心//outputContours[0] = inputContours[1];}//冒泡法for (int i = 0; i < inputContours.size() - 1; i++)          //n个数要进行n-1趟比较{for (int j = 0; j < (inputContours.size() - 1) - i; j++)       //每趟比较n-i次  {mu[j] = moments(inputContours[j], false); //轮廓矩mu[j+1] = moments(inputContours[j+1], false); //轮廓矩mc[j] = Point2d(mu[j].m10 / mu[j].m00, mu[j].m01 / mu[j].m00); //轮廓质心mc[j+1] = Point2d(mu[j+1].m10 / mu[j+1].m00, mu[j+1].m01 / mu[j+1].m00); //轮廓质心area = inputContours[j].size(); //轮廓点数area = contourArea(inputContours[j], false); //轮廓的面积area1 = inputContours[j+1].size(); //轮廓点数area1 = contourArea(inputContours[j+1], false); //轮廓的面积//旋转矩形主要成员有center、size、 angle、points()roRect[j] = minAreaRect(Mat(inputContours[j]));center = roRect[j].center; //轮廓最小外接矩形中心roRect[j+1] = minAreaRect(Mat(inputContours[j+1]));center1 = roRect[j+1].center; //轮廓最小外接矩形中心if (mc[j].x > mc[j + 1].x)      //依次比较两个相邻的数,将小数放在前面,大数放在后面:升序{tempContoursPoint = inputContours[j];   //temp是局部变量inputContours[j] = inputContours[j + 1];inputContours[j + 1] = tempContoursPoint;}}}outputContours = inputContours;//for (int i = 0; i < inputContours.size(); i++)//{//  tempContoursPoint.clear();    //每次循环注意清空//  mu[i] = moments(inputContours[i], false); //轮廓矩//  mc[i] = Point2d(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00); //轮廓质心//    area = inputContours[i].size(); //轮廓点数//   area = contourArea(inputContours[i], false); //轮廓的面积// //旋转矩形主要成员有center、size、 angle、points()//    roRect[i] = minAreaRect(Mat(inputContours[i]));//  center = roRect[i].center; //轮廓最小外接矩形中心//  //outputContours[0] = inputContours[1];//}}

排序前:

排序后:

OpenCV二值化后 按面积选区域 填充孔洞 排序相关推荐

  1. opencv二值化找轮廓检测背景简单小物体

    一.前言 本篇主要是针对背景简单,且具有固定颜色的单类小物体,方法为在灰度化时选用图片的HSV中的S通道,再使用opencv 二值化找轮廓大法可将小物体框出. 原理很简单,图片->取S通道灰度化 ...

  2. opencv 二值化_Python-OpenCV获取图像轮廓的图像处理方法

    一.引言 在<OpenCV阈值处理函数threshold处理32位彩色图像的案例>介绍了threshold 函数,但threshold 的图像阈值处理对于某些光照不均的图像,这种全局阈值分 ...

  3. python opencv图像二值化函数_python opencv 二值化 计算白色像素点的实例

    python opencv 二值化 计算白色像素点的实例 贴部分代码 #! /usr/bin/env python # -*- coding: utf-8 -*- import cv2 import ...

  4. OpenCV+MFC学习笔记(二):OpenCV二值化处理图像并在Picture Control中并自适应显示

    在前面我们已经完成通过OpenCV读取图片在Picture Control中并自适应显示.下面我们很自然的需要对读取的图片进行处理,处理完之后很自然的想到要看看效果.所以今天的笔记是通过OpenCV灰 ...

  5. OpenCV二值化--cv2.threshold()函数、cv2.adaptiveThreshold()函数

    @[toc] 目录 1.cv2.threshold()函数 2.cv2.adaptiveThreshold()函数 3.3.什么时候用cv2.adaptiveThreshold()函数 一.cv2.t ...

  6. opencv 二值化 python_opencv-python图像二值化函数cv2.threshold函数详解及参数cv2.THRESH_OTSU使用...

    cv2.threshold()函数的作用是将一幅灰度图二值化,基本用法如下: #ret:暂时就认为是设定的thresh阈值,mask:二值化的图像 ret,mask = cv2.threshold(i ...

  7. opencv 二值化 matlab,opencv-python图像二值化函数cv2.threshold函数详解及参数cv2.THRESH...

    cv2.threshold()函数的作用是将一幅灰度图二值化,基本用法如下: #ret:暂时就认为是设定的thresh阈值,mask:二值化的图像 ret,mask = cv2.threshold(i ...

  8. opencv 车牌识别---新能源车牌处理(二值化后按位取反)

    场景: 在对车牌号进行识别时,不能识别出新能源车牌的车牌号. 问题原因:   因为我们的识别模板都是黑底白字,新能源的车牌进行二值化处理后都是白地黑字. 模板: 新能源车牌原图(部分): 新能源车牌二 ...

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

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

最新文章

  1. 基于VS+Qt Gui显示控制台用于调试
  2. MySQL Concurrency Problems
  3. metasploit 中 exploit模块check方法简介
  4. intel219网卡的linux驱动,ubuntu16.04安装I219-V网卡驱动问题解决方法(示例代码)
  5. mysql添加分区健_MySQL添加分区添加索引
  6. CVPR2021开源项目,带你傲游宇宙!
  7. 重置密码解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using passwor
  8. gps84转换gcj02公式_【测绘基础】关于投影坐标和坐标转换,这几点你不得不知道!...
  9. asp.net 安装element ui_vue入门003~vue项目引入element并创建一个登录页面
  10. 手机java jdk环境配置文件_JDK怎么安装与配置环境变量
  11. 058线性反馈移位寄存器产生m序列
  12. C语言考试知识点汇总(理论知识点)
  13. mysql 嵌套查询多表_MySql嵌套查询+关联查询+多表查询+对应案例 超详细,一看就会!!!...
  14. RadASM with Masm32
  15. 服务器内存型号的后缀字母,收藏!CPU型号20种后缀字母是什么意思?不再被坑!...
  16. 在html中dd 是什么列表,html中dt dd
  17. java常见的密码加密方式base64,Sha256,MD5
  18. python中factor函数_左手用R右手Python系列——因子变量与分类重编码
  19. 数据库原理——T-SQL、游标
  20. 使用计算机翻译功能吗,微信上怎么使用翻译功能 翻译功能设置教程

热门文章

  1. 研究生计算机学院换研究方向不换导师,南邮自杀研究生曾抱怨“导师不让毕业” 导师被停职...
  2. S32K148 CAN_PAL SDK_RTM300 PE配置
  3. 自己试用期还没过就开始带实习生是什么鬼?
  4. Developer Cloud -帮助和支持
  5. java毕业生设计学校食堂订餐管理计算机源码+系统+mysql+调试部署+lw
  6. 正则表达式记录,匹配字符串中第3个空格和第4个空格中间的字符
  7. MCGS_pro触摸屏组态实际案列
  8. 二分查找、快速排序对比和详解
  9. Android apk签名获取方法
  10. 冈萨雷斯《数字图像处理》第3版课后习题