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友情链接检查方法
Jul 08 Python
python列表操作之extend和append的区别实例分析
Jul 28 Python
详解Python多线程Selenium跨浏览器测试
Apr 01 Python
利用scrapy将爬到的数据保存到mysql(防止重复)
Mar 31 Python
Python向Excel中插入图片的简单实现方法
Apr 24 Python
python解析含有重复key的json方法
Jan 22 Python
pyqt5 使用label控件实时显示时间的实例
Jun 14 Python
Python3实现发送邮件和发送短信验证码功能
Jan 07 Python
NumPy排序的实现
Jan 21 Python
Python实现SMTP邮件发送
Jun 16 Python
python如何构建mock接口服务
Jan 28 Python
Python操作CSV格式文件的方法大全
Jul 15 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 和 MySQL 基础教程(三)
2006/10/09 PHP
PHP中图片等比缩放的实例
2013/03/24 PHP
PHP接收json 并将接收数据插入数据库的实现代码
2015/12/01 PHP
Zend Framework实现具有基本功能的留言本(附demo源码下载)
2016/03/22 PHP
PHP连续签到功能实现方法详解
2019/12/04 PHP
Thinkphp 框架基础之入口文件功能、定义与用法分析
2020/04/27 PHP
获取JavaScript用户自定义类的类名称的代码
2007/03/08 Javascript
FormValidate 表单验证功能代码更新并提供下载
2008/08/23 Javascript
将json当数据库一样操作的javascript lib
2013/10/28 Javascript
jQuery切换网页皮肤并保存到Cookie示例代码
2014/06/16 Javascript
如何在node的express中使用socket.io
2014/12/15 Javascript
JQuery实现带排序功能的权限选择实例
2015/05/18 Javascript
谈谈JavaScript中function多重理解
2015/08/28 Javascript
javascript正则表达式总结
2016/02/29 Javascript
jQuery实现简单的网页换肤效果示例
2016/09/18 Javascript
用headjs来管理和加载js 提高网站加载速度
2016/11/29 Javascript
详解Vue组件之间的数据通信实例
2017/06/17 Javascript
详解Angular-ui-BootStrap组件的解释以及使用
2018/07/13 Javascript
CryptoJS中AES实现前后端通用加解密技术
2018/12/18 Javascript
JavaScript实现的拼图算法分析
2019/02/13 Javascript
Node.js使用supervisor进行开发中调试的方法
2019/03/26 Javascript
element-ui上传一张图片后隐藏上传按钮功能
2019/05/22 Javascript
[01:01:29]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第一场
2018/04/05 DOTA
[46:12]完美世界DOTA2联赛循环赛 DM vs Matador BO2第一场 11.04
2020/11/04 DOTA
Python的Twisted框架中使用Deferred对象来管理回调函数
2016/05/25 Python
python模拟表单提交登录图书馆
2018/04/27 Python
Python判断一个三位数是否为水仙花数的示例
2018/11/13 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
2018/11/30 Python
python实现网站微信登录的示例代码
2019/09/18 Python
pandas分批读取大数据集教程
2020/06/06 Python
浅谈python出错时traceback的解读
2020/07/15 Python
CSS3+DIV实现漂亮的动画彩色标签
2016/06/16 HTML / CSS
一份全面的PHP面试问题考卷
2012/07/15 面试题
数学教师求职信范文
2015/03/20 职场文书
幼儿园安全管理制度
2015/08/05 职场文书
校运会班级霸气口号
2015/12/24 职场文书