opencv 查找连通区域 最大面积实例


Posted in Python onJune 04, 2020

今天在弄一个查找连通的最大面积的问题。

要把图像弄成黑底,白字,这样才可以正确找到。

然后调用下边的方法:

RETR_CCOMP:提取所有轮廓,并将轮廓组织成双层结构(two-level hierarchy),顶层为连通域的外围边界,次层位内层边界

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
 
using namespace cv;
using namespace std;
 
int main( int argc, char** argv )
{
  Mat src = imread( argv[1] );
 
  int largest_area=0;
  int largest_contour_index=0;
  Rect bounding_rect;
 
  Mat thr;
  cvtColor( src, thr, COLOR_BGR2GRAY ); //Convert to gray
  threshold( thr, thr, 125, 255, THRESH_BINARY ); //Threshold the gray
  bitwise_not(thr,thr); //这里先变反转颜色
 
  vector<vector<Point> > contours; // Vector for storing contours
 
  findContours( thr, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE ); // Find the contours in the image
 
  for( size_t i = 0; i< contours.size(); i++ ) // iterate through each contour.
  {
    double area = contourArea( contours[i] ); // Find the area of contour
 
    if( area > largest_area )
    {
      largest_area = area;
      largest_contour_index = i;        //Store the index of largest contour
      bounding_rect = boundingRect( contours[i] ); // Find the bounding rectangle for biggest contour
    }
  }
 
  drawContours( src, contours,largest_contour_index, Scalar( 0, 255, 0 ), 2 ); // Draw the largest contour using previously stored index.
 
  imshow( "result", src );
  waitKey();
  return 0;
}

方法二: connectedComponentsWithStats

std::pair< int , int > MaxAreaFromSource(Mat srcImage, Mat &dstImage, int index)
{
  /*
  vector<vector<cv::Point> > contours; // Vector for storing contours
  
  int largest_area=0;
  size_t largest_contour_index=0;
  Rect bounding_rect;
  
  findContours( srcImage, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE ); // Find the contours in the image
  
  for( size_t i = 0; i< contours.size(); i++ ) // iterate through each contour.
  {
    double area = contourArea( contours[i] ); // Find the area of contour
    
    if( area > largest_area )
    {
      largest_area = area;
      largest_contour_index = i;        //Store the index of largest contour
      bounding_rect = boundingRect( contours[i] ); // Find the bounding rectangle for biggest contour
    }
  }
  
  Mat dst;
  cvtColor(srcImage, dst, CV_GRAY2RGB);
  drawContours( dst, contours,largest_contour_index, Scalar( 0, 255, 0 ), 2 ); // Draw the largest contour using previously stored index.
  imshow( "result", dst );
  waitKey();
  
  printf("%%%%%%%%%%%max area:%d\n", largest_area);
  return make_pair( largest_area, index);
  */
  
  cv::Mat img_bool, labels, stats, centroids, img_color, img_gray;
  
  //连通域计算
  int nccomps = cv::connectedComponentsWithStats (
                          srcImage, //二值图像
                          labels,   //和原图一样大的标记图
                          stats, //nccomps×5的矩阵 表示每个连通区域的外接矩形和面积(pixel)
                          centroids //nccomps×2的矩阵 表示每个连通区域的质心
                          );
  //cv::imshow("labels", labels);
  //cv::waitKey();
  
  vector<cv::Vec3b> colors(nccomps);
  colors[0] = cv::Vec3b(0,0,0); // background pixels remain black.
  
   printf( "index:%d==================\n",index );
  
  vector< int >vec_width,vec_area,vec_height;
  
  for(int label = 1; label < nccomps; ++label)
  {
    colors[label] = cv::Vec3b( (std::rand()&255), (std::rand()&255), (std::rand()&255) );
    std::cout << "Component "<< label << std::endl;
    std::cout << "CC_STAT_LEFT  = " << stats.at<int>(label,cv::CC_STAT_LEFT) << std::endl;
    std::cout << "CC_STAT_TOP  = " << stats.at<int>(label,cv::CC_STAT_TOP) << std::endl;
    std::cout << "CC_STAT_WIDTH = " << stats.at<int>(label,cv::CC_STAT_WIDTH) << std::endl;
    std::cout << "CC_STAT_HEIGHT = " << stats.at<int>(label,cv::CC_STAT_HEIGHT) << std::endl;
    std::cout << "CC_STAT_AREA  = " << stats.at<int>(label,cv::CC_STAT_AREA) << std::endl;
    std::cout << "CENTER  = (" << centroids.at<double>(label, 0) <<","<< centroids.at<double>(label, 1) << ")"<< std::endl << std::endl;
    
    int area = stats.at<int>(label,cv::CC_STAT_AREA);
    int left = stats.at<int>(label,cv::CC_STAT_LEFT);
    int top = stats.at<int>(label,cv::CC_STAT_TOP);
    int width = stats.at<int>(label,cv::CC_STAT_WIDTH);
    int height = stats.at<int>(label,cv::CC_STAT_HEIGHT);
    
    vec_area.push_back(area);
    vec_width.push_back(width);
    vec_height.push_back(height);
  }
  
  vector<int>::iterator bigwidth = std::max_element(std::begin(vec_width), std::end(vec_width));
  vector<int>::iterator bigheight = std::max_element(std::begin(vec_height), std::end(vec_height));
  vector<int>::iterator bigarea = std::max_element(std::begin(vec_area), std::end(vec_area));
  
  //printf( "area:%d------------width:%d height:%d \n", *bigarea, *bigwidth, *bigheight );
  
  //按照label值,对不同的连通域进行着色
  img_color = cv::Mat::zeros(srcImage.size(), CV_8UC3);
  for( int y = 0; y < img_color.rows; y++ )
    for( int x = 0; x < img_color.cols; x++ )
    {
      int label = labels.at<int>(y, x);
      CV_Assert(0 <= label && label <= nccomps);
      img_color.at<cv::Vec3b>(y, x) = colors[label];
    }
  
  cv::imshow("color", img_color);
  cv::waitKey();
   
  return make_pair( *bigarea , index );
}

我先用这个函数实现了一下,效果正确,还是opencv demo 是正确的,网上找了个例子,害死我了。

说明一下:方法一 比 第二种方法 运行速度快很多哦! 这一点很重要。

以上这篇opencv 查找连通区域 最大面积实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python使用Flask框架同时上传多个文件的方法
Mar 21 Python
Django框架下在视图中使用模版的方法
Jul 16 Python
Python实现获取照片拍摄日期并重命名的方法
Sep 30 Python
Python3 Random模块代码详解
Dec 04 Python
Python cookbook(数据结构与算法)筛选及提取序列中元素的方法
Mar 19 Python
我喜欢你 抖音表白程序python版
Apr 07 Python
Python微信操控itchat的方法
May 31 Python
Python获取当前脚本文件夹(Script)的绝对路径方法代码
Aug 27 Python
TensorFlow实现checkpoint文件转换为pb文件
Feb 10 Python
Django实现列表页商品数据返回教程
Apr 03 Python
浅谈Python里面None True False之间的区别
Jul 09 Python
python 两种方法删除空文件夹
Sep 29 Python
Python中的Cookie模块如何使用
Jun 04 #Python
Python爬虫获取页面所有URL链接过程详解
Jun 04 #Python
Python中的全局变量如何理解
Jun 04 #Python
使用OpenCV获取图片连通域数量,并用不同颜色标记函
Jun 04 #Python
Python urllib2运行过程原理解析
Jun 04 #Python
Python如何生成xml文件
Jun 04 #Python
基于python代码批量处理图片resize
Jun 04 #Python
You might like
php htmlentities和htmlspecialchars 的区别
2008/08/18 PHP
PHP 截取字符串专题集合
2010/08/19 PHP
用来解析.htgroup文件的PHP类
2012/09/05 PHP
php采集自中央气象台范围覆盖全国的天气预报代码实例
2015/01/04 PHP
PHP中array_keys和array_unique函数源码的分析
2016/02/26 PHP
Laravel框架执行原生SQL语句及使用paginate分页的方法
2018/08/17 PHP
详解PHP神奇又有用的Trait
2019/03/25 PHP
Yii框架Session与Cookie使用方法示例
2019/10/14 PHP
jQuery的Ajax的自动完成功能控件简要说明
2013/02/22 Javascript
jQuery实现页面顶部显示的进度条效果完整实例
2015/12/09 Javascript
更高效的使用JQuery 这里总结了8个小技巧
2016/04/13 Javascript
nodejs简单实现操作arduino
2016/09/25 NodeJs
jquery网页日历显示控件calendar3.1使用详解
2016/11/24 Javascript
详解微信小程序开发之下拉刷新 上拉加载
2016/11/24 Javascript
AngularJS 在同一个界面启动多个ng-app应用模块详解
2016/12/20 Javascript
js replace()去除代码中空格的实例
2017/02/14 Javascript
jQuery实现简单日期格式化功能示例
2017/09/19 jQuery
vue进行图片的预加载watch用法实例讲解
2018/02/07 Javascript
深入了解query和params的使用区别
2019/06/24 Javascript
[01:06:43]完美世界DOTA2联赛PWL S3 PXG vs GXR 第二场 12.19
2020/12/24 DOTA
详解Python中where()函数的用法
2018/03/27 Python
python 反编译exe文件为py文件的实例代码
2019/06/27 Python
Python Django实现layui风格+django分页功能的例子
2019/08/29 Python
ipython jupyter notebook中显示图像和数学公式实例
2020/04/15 Python
python实现发送邮件
2021/03/02 Python
简历的自我评价
2014/02/03 职场文书
《蒲公英》教学反思
2014/02/28 职场文书
个人社会实践自我鉴定
2014/03/24 职场文书
环保宣传标语
2014/06/12 职场文书
质量保证书格式
2015/02/27 职场文书
2015年综治维稳工作总结
2015/04/07 职场文书
2015年环境整治工作总结
2015/05/22 职场文书
使用pandas模块实现数据的标准化操作
2021/05/14 Python
解析高可用Redis服务架构分析与搭建方案
2021/06/20 Redis
PYTHON 使用 Pandas 删除某列指定值所在的行
2022/04/28 Python
JS中forEach()、map()、every()、some()和filter()的用法
2022/05/11 Javascript