Mat findMaxContours(Mat src)
{
Mat bw; src.copyTo(bw);
//查找最大连通区域
vector<vector<Point>>contours; //每个轮廓中的点
vector<Vec4i>hierarchy; //轮廓的索引
findContours(bw, contours, hierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
double max_area = 0;
int index = 0;
for (int i = 0; i < contours.size(); i++)
{
if (contourArea(contours[i]) > max_area)
{
max_area = contourArea(contours[i]);
index = i;
}
}
Mat dstImage = Mat::zeros(src.rows, src.cols, CV_8UC1);
if (contours.size()>0)
{
drawContours(dstImage, contours, index, Scalar(255), -1);
}
contours.clear();
hierarchy.clear();
contours.swap(vector<vector<Point>>(contours));
hierarchy.swap(vector<Vec4i>(hierarchy));
return dstImage;
}
//不带统计信息的API:
int cv::connectedComponents(
InputArray image, // 输入二值图像
OutputArray labels, // 输出的标记图像,背景index=0
int connectivity = 8, // 连通域,默认是8连通
int ltype = CV_32S // 输出的labels类型,默认是CV_32S
)
//带有统计信息的API:
int cv::connectedComponentsWithStats(
InputArray image, // 输入二值图像
OutputArray labels, // 输出的标记图像,背景index=0
OutputArray stats, // 统计信息,包括每个组件的位置、宽、高与面积
OutputArray centroids, // 每个组件的中心位置坐标cx, cy
int connectivity, // 连通域,默认是8连通
int ltype, // 输出的labels类型,默认是CV_32S
int ccltype // 连通组件算法
)
//其中stats包括以下枚举类型数据信息:
CC_STAT_LEFT 组件的左上角点像素点坐标的X位置
CC_STAT_TOP 组件的左上角点像素点坐标的Y位置
CC_STAT_WIDTH 组件外接矩形的宽度
CC_STAT_HEIGHT 组件外接矩形的高度
CC_STAT_AREA 当前连通组件的面积(像素单位)
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/core/mat.hpp"
#include "opencv2/imgproc/imgproc_c.h"
//#include "opencv2/core/private.hpp"
//#include "opencv2/core/ocl.hpp"
//#include "opencv2/core/hal/hal.hpp"
//#include "opencv2/imgproc/hal/hal.hpp"
//#include "hal_replacement.hpp"
#include <math.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <float.h>
#ifdef HAVE_TEGRA_OPTIMIZATION
#include "opencv2/imgproc/imgproc_tegra.hpp"
#else
#define GET_OPTIMIZED(func) (func)
#endif
enum ConnectedComponentsTypes {
CC_STAT_LEFT = 0, //!< The leftmost (x) coordinate which is the inclusive start of the bounding
//!< box in the horizontal direction.
CC_STAT_TOP = 1, //!< The topmost (y) coordinate which is the inclusive start of the bounding
//!< box in the vertical direction.
CC_STAT_WIDTH = 2, //!< The horizontal size of the bounding box
CC_STAT_HEIGHT = 3, //!< The vertical size of the bounding box
CC_STAT_AREA = 4, //!< The total area (in pixels) of the connected component
#ifndef CV_DOXYGEN
CC_STAT_MAX = 5 //!< Max enumeration value. Used internally only for memory allocation
#endif
};
//! connected components algorithm
enum ConnectedComponentsAlgorithmsTypes {
CCL_WU = 0, //!< SAUF algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
CCL_DEFAULT = -1, //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
CCL_GRANA = 1 //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity
};
/* helper tables */
extern const uchar icvSaturate8u_cv[];
#define CV_FAST_CAST_8U(t) ( (-256 <= (t) && (t) <= 512) ? icvSaturate8u_cv[(t)+256] : 0 )
#define CV_CALC_MIN_8U(a,b) (a) -= CV_FAST_CAST_8U((a) - (b))
#define CV_CALC_MAX_8U(a,b) (a) += CV_FAST_CAST_8U((b) - (a))
// -256.f ... 511.f
extern const float icv8x32fTab_cv[];
#define CV_8TO32F(x) icv8x32fTab_cv[(x)+256]
// (-128.f)^2 ... (255.f)^2
extern const float icv8x32fSqrTab[];
#define CV_8TO32F_SQR(x) icv8x32fSqrTab[(x)+128]
#define CV_COPY( dst, src, len, idx ) \
for( (idx) = 0; (idx) < (len); (idx)++) (dst)[idx] = (src)[idx]
#define CV_SET( dst, val, len, idx ) \
for( (idx) = 0; (idx) < (len); (idx)++) (dst)[idx] = (val)
#undef CV_CALC_MIN
#define CV_CALC_MIN(a, b) if((a) > (b)) (a) = (b)
#undef CV_CALC_MAX
#define CV_CALC_MAX(a, b) if((a) < (b)) (a) = (b)
#ifdef HAVE_IPP
static inline IppiInterpolationType ippiGetInterpolation(int inter)
{
inter &= cv::INTER_MAX;
return inter == cv::INTER_NEAREST ? ippNearest :
inter == cv::INTER_LINEAR ? ippLinear :
inter == cv::INTER_CUBIC ? ippCubic :
inter == cv::INTER_LANCZOS4 ? ippLanczos :
inter == cv::INTER_AREA ? ippSuper :
(IppiInterpolationType)-1;
}
#endif
//#include "_geom.h"
//#include "filterengine.hpp"
//
//#include "opencv2/core/sse_utils.hpp"
//
//inline bool isStorageOrMat(void * arr)
//{
// if (CV_IS_STORAGE( arr ))
// return true;
// else if (CV_IS_MAT( arr ))
// return false;
// else
// CV_Error( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" );
// return false;
//}
#endif /*__OPENCV_CV_INTERNAL_H_*/
#include<opencv2/opencv.hpp>
using namespace cv;
int connectedComponentsWithStats(InputArray img_, OutputArray _labels, OutputArray statsv,
OutputArray centroids, int connectivity, int ltype, int ccltype);
受代码长度限制,部分代码如下,下载资源提供全部代码。
int connectedComponents(InputArray img_, OutputArray _labels, int connectivity, int ltype, int ccltype){
const cv::Mat img = img_.getMat();
_labels.create(img.size(), CV_MAT_DEPTH(ltype));
cv::Mat labels = _labels.getMat();
connectedcomponents::NoOp sop;
if (ltype == CV_16U){
return connectedComponents_sub1(img, labels, connectivity, ccltype, sop);
}
else if (ltype == CV_32S){
return connectedComponents_sub1(img, labels, connectivity, ccltype, sop);
}
else{
CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s");
return 0;
}
}
int connectedComponentsWithStats(InputArray img_, OutputArray _labels, OutputArray statsv,
OutputArray centroids, int connectivity = 8, int ltype = CV_32S, int ccltype = CCL_DEFAULT)
{
const cv::Mat img = img_.getMat();
_labels.create(img.size(), CV_MAT_DEPTH(ltype));
cv::Mat labels = _labels.getMat();
connectedcomponents::CCStatsOp sop(statsv, centroids);
if (ltype == CV_16U){
return connectedComponents_sub1(img, labels, connectivity, ccltype, sop);
}
else if (ltype == CV_32S){
return connectedComponents_sub1(img, labels, connectivity, ccltype, sop);
}
else{
CV_Error(CV_StsUnsupportedFormat, "the type of labels must be 16u or 32s");
return 0;
}
}
//OpenCV3.3.0
#include <algorithm>
#include <iostream>
#include<opencv2/opencv.hpp>
#include "m_precomp.hpp"
using namespace cv;
using namespace std;
int main()
{
Mat img, img_edge, labels, centroids, img_color, stats;
img = imread("1.png", 0);
threshold(img, img_edge, 0, 255, THRESH_OTSU);
int nccomps = connectedComponentsWithStats(img_edge, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
cout << "连通域个数: " << nccomps << endl;
vector<Vec3b>colors(nccomps + 1);;
colors[0] = Vec3b(0, 0, 0);
for (int i = 1; i <= nccomps; i++)
{
colors[i] = Vec3b(rand() % 256, rand() % 256, rand() % 256);
if (stats.at<int>(i-1, CC_STAT_AREA) < 2500)
colors[i] = Vec3b(0, 0, 0);
cout << stats.at<int>(i - 1, CC_STAT_AREA) << endl;//连通域的面积
}
img_color = Mat::zeros(img.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<Vec3b>(y, x) = colors[label];
}
return 0;
}
https://github.com/opencv/opencv/blob/master/modules/imgproc/src/connectedcomponents.cpp
https://blog.csdn.net/jgj123321/article/details/93489417
源代码下载链接:
https://download.csdn.net/download/fei13148687/12241852