精华内容
下载资源
问答
  • def showConnectedComponents(binary_img): w, h = binary_img.shape color = [] color.append((0, 0, 0)) img_color = np.zeros((w, h, 3), dtype=np.uint8) retval, labels, stats, centroids = cv2....
    def showConnectedComponents(binary_img):
    
        w, h = binary_img.shape
        color = []
        color.append((0, 0, 0))
        img_color = np.zeros((w, h, 3), dtype=np.uint8)
        retval, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_img)
        for num in range(1,retval):
            color_b = random.randint(0, 255)
            color_g = random.randint(0, 255)
            color_r = random.randint(0, 255)
            color.append((color_b, color_g, color_r))
        for x in range(w):
            for y in range(h):
                lable = labels[x,y]
                img_color[x,y,:] = color[int(lable)]
        imshow("img_color",img_color)
        # cv2.waitKey(0)
    
    展开全文
  • opencv连通域

    2020-11-25 20:50:41
    opencv连通域学习连通域 连通域 图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域,连通域分析是指在图像中寻找彼此相互独立的连通域并将其标记出来。提取图像中不同的连通域是图像中较为常用的...

    opencv连通域学习

    连通域

    图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域,连通域分析是指在图像中寻找彼此相互独立的连通域并将其标记出来。提取图像中不同的连通域是图像中较为常用的方法。例如在车牌识别、文字识别、目标检测等领域对感兴趣区域分割与识别。一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响,连通域分析常处理的是二值化后的图像。

    图像中两个像素相邻有两种定义方式,分别是4-领域和8-领域。根据两个像素相邻的定义方式不同,得到的连通域也不相同,因此在分析连通域的同时,一定要声明是在哪种领域条件下分析得到的结果。
    在这里插入图片描述

    常用的图像领域分析法有两遍扫描法和种子填充法。两遍扫描法会遍历两次图像,第一次遍历图像时会给每个非0像素赋予一个数字标签,当某个像素的上方和左侧领域内的像素已经有数字标签时,取两者中的最小值作为当前像素的标签,否则赋予当前像素一个新的数字标签。第一次遍历图像的时候同一个连通域可能会被赋予一个或者多个不同的标签,如下图所示,因此第二次遍历需要将这些属于同一个连通域的不同标签合并,最后实现同一个领域内的所有像素具有相同的标签。
    在这里插入图片描述
    种子填充法源于计算机图像学,常用于对某些图形进行填充。该方法首先将所有非0像素放到一个集合中,之后在集合中随机选出一个像素作为种子像素,根据领域关系不断扩充种子像素所在的连通域,并在集合中删除掉扩充出的像素,直到种子像素所在的连通域无法扩充,之后再从集合中随机选取一个像素作为新的种子像素,重复上述过程直到集合中没有像素。

    opencv4提供了用于提取图像中不同连通域的connectedComponents()函数,该函数用于计算二值图像中连通域的个数,并在图像中将不同的连通域用不同的数字标签标记出来,其中标签0表示图像中的背景区域,同时函数具有一个int类型的返回数据,用于表示图像中连通域的数目。函数的第一个参数时待标记连通域的输入图像,函数要求输入图像必须是数据类型为CV_8U的单通道灰度图像,而且最好是经过二值化的二值图像。函数第二个参数是标记连通域后的输出图像,图像尺寸与第一个参数的输入图像尺寸相同,图像的数据类型与函数的第四个参数相关。函数第三个参数是统计连通域时选择的领域种类,函数支持两种领域,分别用4表示4-领域,8表示8-领域。函数第四个参数为输出图像的数据类型,可以选择的参数为CV_32和CV_16U两种。函数的最后一个参数时标记连通域时使用算法的标志,目前只支持Grana(BBDT)和Wu(SAUF)两种算法。

    上述函数原型的所有参数都没有默认值,在调用时需要设置全部参数,增加了使用的复杂程度,因此opencv4提供了connectedComponents()函数的简易原型,减少了参数数量以及部分参数增加了默认。

    展开全文
  • OpenCV 连通域数量统计

    2021-06-01 15:20:30
    2.根据种子填充法思路,遍历图像,得到每个连通域外接矩形坐标信息、面积信息 核心代码 /* Input: src: 待检测连通域的二值化图像 Output: dst: 标记后的图像 featherList: 连通域特征的清单(可自行查阅...

    学习目标:

    1.输入图像为分割结果图像 2.根据种子填充法思路,遍历图像,得到每个连通域外接矩形坐标信息、面积信息

    核心代码

    /*
    	Input:
    		src: 待检测连通域的二值化图像
    	Output:
    		dst: 标记后的图像
    		featherList: 连通域特征的清单(可自行查阅文档)
    	return:
    		连通域数量。
    */
    int connectionDetect(Mat &src, Mat &dst, vector<Feather> &featherList)
    {
    	int rows = src.rows;
    	int cols = src.cols;
    	int labelValue = 0;
    	Point seed, neighbor;
    	stack<Point> pointStack;
    	// 用于计算连通域的面积
    	int area = 0;         
    	// 连通域的左边界,即外接最小矩形的左边框,横坐标值,依此类推
    	int leftBoundary = 0;       
    	int rightBoundary = 0;
    	int topBoundary = 0;
    	int bottomBoundary = 0;
    	// 外接矩形框
    	Rect box;                   
    	Feather feather;
    	vector<stack<Point>> points;
    	featherList.clear();
    
    	dst.release();
    	dst = src.clone();
    	for (int i = 0; i < rows; i++)
    	{
    		uchar *pRow = dst.ptr<uchar>(i);
    		for (int j = 0; j < cols; j++)
    		{
    			if (pRow[j] == 255)
    			{
    				area = 0;
    				// labelValue最大为254,最小为1.
    				labelValue++;       
    				// Point(横坐标,纵坐标)
    				seed = Point(j, i);     
    				dst.at<uchar>(seed) = labelValue;
    				pointStack.push(seed);
    
    				area++;
    				leftBoundary = seed.x;
    				rightBoundary = seed.x;
    				topBoundary = seed.y;
    				bottomBoundary = seed.y;
    
    				while (!pointStack.empty())
    				{
    					neighbor = Point(seed.x + 1, seed.y);
    					if ((seed.x != (cols - 1)) && (dst.at<uchar>(neighbor) == 255))
    					{
    						dst.at<uchar>(neighbor) = labelValue;
    						pointStack.push(neighbor);
    
    						area++;
    						if (rightBoundary < neighbor.x)
    							rightBoundary = neighbor.x;
    					}
    
    					neighbor = Point(seed.x, seed.y + 1);
    					if ((seed.y != (rows - 1)) && (dst.at<uchar>(neighbor) == 255))
    					{
    						dst.at<uchar>(neighbor) = labelValue;
    						pointStack.push(neighbor);
    
    						area++;
    						if (bottomBoundary < neighbor.y)
    							bottomBoundary = neighbor.y;
    
    					}
    
    					neighbor = Point(seed.x - 1, seed.y);
    					if ((seed.x != 0) && (dst.at<uchar>(neighbor) == 255))
    					{
    						dst.at<uchar>(neighbor) = labelValue;
    						pointStack.push(neighbor);
    
    						area++;
    						if (leftBoundary > neighbor.x)
    							leftBoundary = neighbor.x;
    					}
    
    					neighbor = Point(seed.x, seed.y - 1);
    					if ((seed.y != 0) && (dst.at<uchar>(neighbor) == 255))
    					{
    						dst.at<uchar>(neighbor) = labelValue;
    						pointStack.push(neighbor);
    
    						area++;
    						if (topBoundary > neighbor.y)
    							topBoundary = neighbor.y;
    					}
    
    					seed = pointStack.top();
    					pointStack.pop();
    				}
    				box = Rect(leftBoundary, topBoundary, rightBoundary - leftBoundary, bottomBoundary - topBoundary);
    				feather.area = area;
    				feather.boundingbox = box;
    				feather.label = labelValue;
    				featherList.push_back(feather);
    			}
    		}
    	}
    	return labelValue;
    }
    
    
    # 代码执行说明
    
    <font color=#999AAA >
    在此不进行实例演示
    1、 输入图像为分割后图像
    2、 执行结果可根据featherList信息自行绘制矩形框
    <hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">
    
    
    展开全文
  • OpenCV连通域分析

    千次阅读 2018-08-28 16:50:24
    OpenCV_连通区域分析(Connected Component Analysis/Labeling) 【摘要】 本文主要介绍在CVPR和图像处理领域中较为常用的一种图像区域(Blob)提取的方法——连通性分析法(连通区域标记法)。...



    原文地址

    OpenCV_连通区域分析(Connected Component Analysis/Labeling)


    【摘要】

    本文主要介绍在CVPR和图像处理领域中较为常用的一种图像区域(Blob)提取的方法——连通性分析法(连通区域标记法)。文中介绍了两种常见的连通性分析的算法:1)Two-pass;2)Seed-Filling种子填充,并给出了两个算法的基于OpenCV的C++实现代码。



    一、连通区域分析

    连通区域(Connected Component)一般是指图像中具有相同像素值且位置相邻的前景像素点组成的图像区域(Region,Blob)。连通区域分析(Connected Component Analysis,Connected Component Labeling)是指将图像中的各个连通区域找出并标记。

    连通区域分析是一种在CVPR和图像分析处理的众多应用领域中较为常用和基本的方法。例如:OCR识别中字符分割提取(车牌识别、文本识别、字幕识别等)、视觉跟踪中的运动前景目标分割与提取(行人入侵检测、遗留物体检测、基于视觉的车辆检测与跟踪等)、医学图像处理(感兴趣目标区域提取)、等等。也就是说,在需要将前景目标提取出来以便后续进行处理的应用场景中都能够用到连通区域分析方法,通常连通区域分析处理的对象是一张二值化后的图像。


    二、连通区域分析的算法

    从连通区域的定义可以知道,一个连通区域是由具有相同像素值的相邻像素组成像素集合,因此,我们就可以通过这两个条件在图像中寻找连通区域,对于找到的每个连通区域,我们赋予其一个唯一的标识(Label),以区别其他连通区域。

    连通区域分析有基本的算法,也有其改进算法,本文介绍其中的两种常见算法:

    1)Two-Pass法;2)Seed-Filling种子填充法;


    Note:

    a、这里的扫描指的是按行或按列访问以便图像的所有像素,本文算法采用的是按行扫描方式;

    b、图像记为B,为二值图像:前景像素(pixel value = 1),背景像素(pixel value = 0)

    c、label从2开始计数;

    d、像素相邻关系:4-领域、8-领域,本文算法采用4-邻域;


                                         

    4—领域图例                                                     8—领域图例



    1)Two-Pass(两遍扫描法)

    两遍扫描法,正如其名,指的就是通过扫描两遍图像,就可以将图像中存在的所有连通区域找出并标记。思路:第一遍扫描时赋予每个像素位置一个label,扫描过程中同一个连通区域内的像素集合中可能会被赋予一个或多个不同label,因此需要将这些属于同一个连通区域但具有不同值的label合并,也就是记录它们之间的相等关系;第二遍扫描就是将具有相等关系的equal_labels所标记的像素归为一个连通区域并赋予一个相同的label(通常这个label是equal_labels中的最小值)。


    下面给出Two-Pass算法的简单步骤:

    (1)第一次扫描:

    访问当前像素B(x,y),如果B(x,y) == 1:

    a、如果B(x,y)的领域中像素值都为0,则赋予B(x,y)一个新的label:

    label += 1, B(x,y) = label;

    b、如果B(x,y)的领域中有像素值 > 1的像素Neighbors:

    1)将Neighbors中的最小值赋予给B(x,y):

    B(x,y) = min{Neighbors}

    2)记录Neighbors中各个值(label)之间的相等关系,即这些值(label)同属同一个连通区域;

     labelSet[i] = { label_m, .., label_n },labelSet[i]中的所有label都属于同一个连通区域(注:这里可以有多种实现方式,只要能够记录这些具有相等关系的label之间的关系即可)

    (2)第二次扫描:

    访问当前像素B(x,y),如果B(x,y) > 1:

    a、找到与label = B(x,y)同属相等关系的一个最小label值,赋予给B(x,y);

    完成扫描后,图像中具有相同label值的像素就组成了同一个连通区域。


    下面这张图动态地演示了Two-pass算法:





    2)Seed Filling(种子填充法)

    种子填充方法来源于计算机图形学,常用于对某个图形进行填充。思路:选取一个前景像素点作为种子,然后根据连通区域的两个基本条件(像素值相同、位置相邻)将与种子相邻的前景像素合并到同一个像素集合中,最后得到的该像素集合则为一个连通区域。


    下面给出基于种子填充法的连通区域分析方法:

    (1)扫描图像,直到当前像素点B(x,y) == 1:

    a、将B(x,y)作为种子(像素位置),并赋予其一个label,然后将该种子相邻的所有前景像素都压入栈中;

    b、弹出栈顶像素,赋予其相同的label,然后再将与该栈顶像素相邻的所有前景像素都压入栈中;

    c、重复b步骤,直到栈为空;

    此时,便找到了图像B中的一个连通区域,该区域内的像素值被标记为label;

    (2)重复第(1)步,直到扫描结束;

    扫描结束后,就可以得到图像B中所有的连通区域;


    下面这张图动态地演示了Seed-Filling算法:




    三、实验演示


    1)前景二值图像


    2)连通区域分析方法标记后得到的label图像


    Two-pass算法:



    Seed-filling算法:


    注:为了显示方便,将像素值乘以了一个整数进行放大。


    3)color后的label图像

    Two-pass算法:


    Seed-filling算法:



    注:颜色是随机生成的。





    四、代码


    1)Two-pass算法的一种实现

    说明:

    基于OpenCV和C++实现,领域:4-领域。实现与算法描述稍有差别(具体为记录具有相等关系的label方法实现上)。

    1. <span style=“font-size:12px”>//  Connected Component Analysis/Labeling By Two-Pass Algorithm   
    2. //  Author:  www.icvpr.com    
    3. //  Blog  :  http://blog.csdn.net/icvpr   
    4. #include <iostream>  原文
    5. #include <string>  
    6. #include <list>  
    7. #include <vector>  
    8. #include <map>  
    9.   
    10. #include <opencv2/imgproc/imgproc.hpp>  
    11. #include <opencv2/highgui/highgui.hpp>  
    12.   
    13.   
    14. void icvprCcaByTwoPass(const cv::Mat& _binImg, cv::Mat& _lableImg)  
    15. {  
    16.     // connected component analysis (4-component)  
    17.     // use two-pass algorithm  
    18.     // 1. first pass: label each foreground pixel with a label  
    19.     // 2. second pass: visit each labeled pixel and merge neighbor labels  
    20.     //   
    21.     // foreground pixel: _binImg(x,y) = 1  
    22.     // background pixel: _binImg(x,y) = 0  
    23.   
    24.   
    25.     if (_binImg.empty() ||  
    26.         _binImg.type() != CV_8UC1)  
    27.     {  
    28.         return ;  
    29.     }  
    30.   
    31.     // 1. first pass  
    32.   
    33.     _lableImg.release() ;  
    34.     _binImg.convertTo(_lableImg, CV_32SC1) ;  
    35.   
    36.     int label = 1 ;  // start by 2  
    37.     std::vector<int> labelSet ;  
    38.     labelSet.push_back(0) ;   // background: 0  
    39.     labelSet.push_back(1) ;   // foreground: 1  
    40.   
    41.     int rows = _binImg.rows - 1 ;  
    42.     int cols = _binImg.cols - 1 ;  
    43.     for (int i = 1; i < rows; i++)  
    44.     {  
    45.         int* data_preRow = _lableImg.ptr<int>(i-1) ;  
    46.         int* data_curRow = _lableImg.ptr<int>(i) ;  
    47.         for (int j = 1; j < cols; j++)  
    48.         {  
    49.             if (data_curRow[j] == 1)  
    50.             {  
    51.                 std::vector<int> neighborLabels ;  
    52.                 neighborLabels.reserve(2) ;  
    53.                 int leftPixel = data_curRow[j-1] ;  
    54.                 int upPixel = data_preRow[j] ;  
    55.                 if ( leftPixel > 1)  
    56.                 {  
    57.                     neighborLabels.push_back(leftPixel) ;  
    58.                 }  
    59.                 if (upPixel > 1)  
    60.                 {  
    61.                     neighborLabels.push_back(upPixel) ;  
    62.                 }  
    63.   
    64.                 if (neighborLabels.empty())  
    65.                 {  
    66.                     labelSet.push_back(++label) ;  // assign to a new label  
    67.                     data_curRow[j] = label ;  
    68.                     labelSet[label] = label ;  
    69.                 }  
    70.                 else  
    71.                 {  
    72.                     std::sort(neighborLabels.begin(), neighborLabels.end()) ;  
    73.                     int smallestLabel = neighborLabels[0] ;    
    74.                     data_curRow[j] = smallestLabel ;  
    75.   
    76.                     // save equivalence  
    77.                     for (size_t k = 1; k < neighborLabels.size(); k++)  
    78.                     {  
    79.                         int tempLabel = neighborLabels[k] ;  
    80.                         int& oldSmallestLabel = labelSet[tempLabel] ;  
    81.                         if (oldSmallestLabel > smallestLabel)  
    82.                         {                             
    83.                             labelSet[oldSmallestLabel] = smallestLabel ;  
    84.                             oldSmallestLabel = smallestLabel ;  
    85.                         }                         
    86.                         else if (oldSmallestLabel < smallestLabel)  
    87.                         {  
    88.                             labelSet[smallestLabel] = oldSmallestLabel ;  
    89.                         }  
    90.                     }  
    91.                 }                 
    92.             }  
    93.         }  
    94.     }  
    95.   
    96.     // update equivalent labels  
    97.     // assigned with the smallest label in each equivalent label set  
    98.     for (size_t i = 2; i < labelSet.size(); i++)  
    99.     {  
    100.         int curLabel = labelSet[i] ;  
    101.         int preLabel = labelSet[curLabel] ;  
    102.         while (preLabel != curLabel)  
    103.         {  
    104.             curLabel = preLabel ;  
    105.             preLabel = labelSet[preLabel] ;  
    106.         }  
    107.         labelSet[i] = curLabel ;  
    108.     }  
    109.   
    110.   
    111.     // 2. second pass  
    112.     for (int i = 0; i < rows; i++)  
    113.     {  
    114.         int* data = _lableImg.ptr<int>(i) ;  
    115.         for (int j = 0; j < cols; j++)  
    116.         {  
    117.             int& pixelLabel = data[j] ;  
    118.             pixelLabel = labelSet[pixelLabel] ;   
    119.         }  
    120.     }  
    121. }</span>  




    2)Seed-Filling种子填充方法

    说明:

    基于OpenCV和C++实现;领域:4-领域。


    1. <span style=“font-size:12px”>//  Connected Component Analysis/Labeling By Seed-Filling Algorithm   
    2. //  Author:  www.icvpr.com    
    3. //  Blog  :  http://blog.csdn.net/icvpr   
    4. #include <iostream>  
    5. #include <string>  
    6. #include <list>  
    7. #include <vector>  
    8. #include <map>  
    9. #include <stack>  
    10.   
    11. #include <opencv2/imgproc/imgproc.hpp>  
    12. #include <opencv2/highgui/highgui.hpp>  
    13.   
    14.   
    15. void icvprCcaBySeedFill(const cv::Mat& _binImg, cv::Mat& _lableImg)  
    16. {  
    17.     // connected component analysis (4-component)  
    18.     // use seed filling algorithm  
    19.     // 1. begin with a foreground pixel and push its foreground neighbors into a stack;  
    20.     // 2. pop the top pixel on the stack and label it with the same label until the stack is empty  
    21.     //   
    22.     // foreground pixel: _binImg(x,y) = 1  
    23.     // background pixel: _binImg(x,y) = 0  
    24.   
    25.   
    26.     if (_binImg.empty() ||  
    27.         _binImg.type() != CV_8UC1)  
    28.     {  
    29.         return ;  
    30.     }  
    31.   
    32.     _lableImg.release() ;  
    33.     _binImg.convertTo(_lableImg, CV_32SC1) ;  
    34.   
    35.     int label = 1 ;  // start by 2  
    36.   
    37.     int rows = _binImg.rows - 1 ;  
    38.     int cols = _binImg.cols - 1 ;  
    39.     for (int i = 1; i < rows-1; i++)  
    40.     {  
    41.         int* data= _lableImg.ptr<int>(i) ;  
    42.         for (int j = 1; j < cols-1; j++)  
    43.         {  
    44.             if (data[j] == 1)  
    45.             {  
    46.                 std::stack<std::pair<int,int>> neighborPixels ;     
    47.                 neighborPixels.push(std::pair<int,int>(i,j)) ;     // pixel position: <i,j>  
    48.                 ++label ;  // begin with a new label  
    49.                 while (!neighborPixels.empty())  
    50.                 {  
    51.                     // get the top pixel on the stack and label it with the same label  
    52.                     std::pair<int,int> curPixel = neighborPixels.top() ;  
    53.                     int curX = curPixel.first ;  
    54.                     int curY = curPixel.second ;  
    55.                     _lableImg.at<int>(curX, curY) = label ;  
    56.   
    57.                     // pop the top pixel  
    58.                     neighborPixels.pop() ;  
    59.   
    60.                     // push the 4-neighbors (foreground pixels)  
    61.                     if (_lableImg.at<int>(curX, curY-1) == 1)  
    62.                     {// left pixel  
    63.                         neighborPixels.push(std::pair<int,int>(curX, curY-1)) ;  
    64.                     }  
    65.                     if (_lableImg.at<int>(curX, curY+1) == 1)  
    66.                     {// right pixel  
    67.                         neighborPixels.push(std::pair<int,int>(curX, curY+1)) ;  
    68.                     }  
    69.                     if (_lableImg.at<int>(curX-1, curY) == 1)  
    70.                     {// up pixel  
    71.                         neighborPixels.push(std::pair<int,int>(curX-1, curY)) ;  
    72.                     }  
    73.                     if (_lableImg.at<int>(curX+1, curY) == 1)  
    74.                     {// down pixel  
    75.                         neighborPixels.push(std::pair<int,int>(curX+1, curY)) ;  
    76.                     }  
    77.                 }         
    78.             }  
    79.         }  
    80.     }  
    81. }</span>  



    3)颜色标记(用于显示)


    1. <span style=“font-size:12px”>//  Connected Component Analysis/Labeling – Color Labeling   
    2. //  Author:  www.icvpr.com    
    3. //  Blog  :  http://blog.csdn.net/icvpr   
    4. #include <iostream>  
    5. #include <string>  
    6. #include <list>  
    7. #include <vector>  
    8. #include <map>  
    9. #include <stack>  
    10.   
    11. #include <opencv2/imgproc/imgproc.hpp>  
    12. #include <opencv2/highgui/highgui.hpp>  
    13.   
    14. cv::Scalar icvprGetRandomColor()  
    15. {  
    16.     uchar r = 255 * (rand()/(1.0 + RAND_MAX));  
    17.     uchar g = 255 * (rand()/(1.0 + RAND_MAX));  
    18.     uchar b = 255 * (rand()/(1.0 + RAND_MAX));  
    19.     return cv::Scalar(b,g,r) ;  
    20. }  
    21.   
    22.   
    23. void icvprLabelColor(const cv::Mat& _labelImg, cv::Mat& _colorLabelImg)   
    24. {  
    25.     if (_labelImg.empty() ||  
    26.         _labelImg.type() != CV_32SC1)  
    27.     {  
    28.         return ;  
    29.     }  
    30.   
    31.     std::map<int, cv::Scalar> colors ;  
    32.   
    33.     int rows = _labelImg.rows ;  
    34.     int cols = _labelImg.cols ;  
    35.   
    36.     _colorLabelImg.release() ;  
    37.     _colorLabelImg.create(rows, cols, CV_8UC3) ;  
    38.     _colorLabelImg = cv::Scalar::all(0) ;  
    39.   
    40.     for (int i = 0; i < rows; i++)  
    41.     {  
    42.         const int* data_src = (int*)_labelImg.ptr<int>(i) ;  
    43.         uchar* data_dst = _colorLabelImg.ptr<uchar>(i) ;  
    44.         for (int j = 0; j < cols; j++)  
    45.         {  
    46.             int pixelValue = data_src[j] ;  
    47.             if (pixelValue > 1)  
    48.             {  
    49.                 if (colors.count(pixelValue) <= 0)  
    50.                 {  
    51.                     colors[pixelValue] = icvprGetRandomColor() ;  
    52.                 }  
    53.                 cv::Scalar color = colors[pixelValue] ;  
    54.                 *data_dst++   = color[0] ;  
    55.                 *data_dst++ = color[1] ;  
    56.                 *data_dst++ = color[2] ;  
    57.             }  
    58.             else  
    59.             {  
    60.                 data_dst++ ;  
    61.                 data_dst++ ;  
    62.                 data_dst++ ;  
    63.             }  
    64.         }  
    65.     }  
    66. }  
    67. </span>  




    4)测试程序


    1. <span style=“font-size:12px”>//  Connected Component Analysis/Labeling – Test code  
    2. //  Author:  www.icvpr.com    
    3. //  Blog  :  http://blog.csdn.net/icvpr   
    4. #include <iostream>  
    5. #include <string>  
    6. #include <list>  
    7. #include <vector>  
    8. #include <map>  
    9. #include <stack>  
    10.   
    11. #include <opencv2/imgproc/imgproc.hpp>  
    12. #include <opencv2/highgui/highgui.hpp>  
    13.   
    14. int main(int argc, char** argv)  
    15. {  
    16.     cv::Mat binImage = cv::imread(”../icvpr.com.jpg”, 0) ;  
    17.     cv::threshold(binImage, binImage, 50, 1, CV_THRESH_BINARY_INV) ;  
    18.   
    19.     // connected component labeling  
    20.     cv::Mat labelImg ;  
    21.     icvprCcaByTwoPass(binImage, labelImg) ;  
    22.     //icvprCcaBySeedFill(binImage, labelImg) ;  
    23.   
    24.     // show result  
    25.     cv::Mat grayImg ;  
    26.     labelImg *= 10 ;  
    27.     labelImg.convertTo(grayImg, CV_8UC1) ;  
    28.     cv::imshow(”labelImg”, grayImg) ;  
    29.   
    30.     cv::Mat colorLabelImg ;  
    31.     icvprLabelColor(labelImg, colorLabelImg) ;  
    32.     cv::imshow(”colorImg”, colorLabelImg) ;  
    33.     cv::waitKey(0) ;  
    34.   
    35.     return 0 ;  
    36. }</span>  




    Reference

    [1] http://en.wikipedia.org/wiki/Connected-component_labeling

    [2] http://homepages.inf.ed.ac.uk/rbf/HIPR2/label.htm

    [3] http://www.codeproject.com/Articles/336915/Connected-Component-Labeling-Algorithm



    声明:

    作者:icvpr | blog.csdn.net/icvpr


    展开全文
  • opencv 连通域笔记

    2021-03-18 13:56:17
    这个函数的作用是对一幅图像进行连通域提取,并返回找到的连通域的信息:retval、labels、stats、centroids num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=8, ...
  • 如何把图片里三个连通域矩形分离分别显示在三张图片里![图片说明](https://img-ask.csdn.net/upload/201702/27/1488211138_797661.jpg)
  • 连通域分割代码,当初是用来分割染色体的,可多张处理。比较常规的方法,界限分明的图像处理效果都还可以,为啥非要五十个字,写的人头大。
  • opencv学习(一)连通域分割及移动

    千次阅读 2018-01-10 22:42:04
    连通域分割原理: 将图像二值化,并用connectedComponentsWithStats算子进行分割,将二值图分割成label,可以取label中的任何一块,如果要进行区域筛选,现成的Stats中有面积和长宽,其他特征(圆度,凸度。。。。...
  • OpenCV笔记(1)——连通域分割实现

    万次阅读 热门讨论 2016-11-10 14:05:40
    一个很简单的想法就是通过连通域进行分割,每个字符是一个连通域,不同字符之间是不同的连通域,因为这里没有粘连,所以处理起来是非常方便的。 那么重点就来了,如何实现连通域分割呢? 原来的打算是通过扫描...
  • http://stackoverflow.com/questions/29491669/real-time-paper-sheet-detection-using-opencv-in-android/29492699#29492699 at srcImg; //you may want to apply Canny or some threshold before search...
  • 连通域分割算法

    千次阅读 2018-03-03 16:47:51
    OpenCV_连通区域分析(Connected Component Analysis/Labeling)【摘要】本文主要介绍在CVPR和图像处理领域中较为常用的一种图像区域(Blob)提取的方法——连通性分析法(连通区域标记法)。文中介绍了两种常见的...
  • CFS连通域分割

    2020-12-31 17:21:51
    """传入二值化后的图片进行连通域分割""" pixdata = img.load() w,h = img.size visited = set() q = queue.Queue() offset = [(-1,-1),(0,-1),(1,-1),(-1,0),(1,0),(-1,1),(0,1),(1,1)] cuts = []
  • 上一次通过投影的方式进行了文本块分割,但这种方法有很大的局限性,要求分行清晰、不能有字符跨多行、不能倾斜,而且对噪声比较敏感。还是拿上一回的图片,但是我在上面加了一个比较大的字,得出的结果就有问题了:...
  • cv2连通域分割

    2021-01-02 18:25:58
    import cv2 import os import random import numpy as np def connectedComponent(img): binary_img = img ret, binary_img = cv2.threshold(binary_img, 127, 255, cv2.THRESH_BINARY) # binary_img = ...
  • OpenCV—python 连通域标记

    千次阅读 2020-12-18 15:01:34
    提取图像中不同的连通域是图像处理中较为常用的方法,在目标检测等领域对感兴趣区域分割与识别。一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响,连通域分析常处理的是二...
  • opencv_连通域分析(经典总结)

    千次阅读 2014-05-13 18:46:36
    OpenCV_连通区域分析(Connected Component Analysis/Labeling) 【摘要】 本文主要介绍在CVPR和图像处理领域中较为常用的一种图像区域(Blob)提取的方法——连通性分析法(连通区域标记法)。文中...
  • OpenCV-二值图像连通域分析

    万次阅读 多人点赞 2017-09-18 14:10:47
    连通域分析对于图像处理后面涉及到模式识别的内容来说是基础 连通区域(Connected Component)一般是指图像中具有相同像素值且位置相邻的前景像素点组成的图像区域(Region,Blob)。连通区域分析(Connected ...
  • 主要给大家介绍了关于python验证码识别教程之利用投影法、连通域分割图片的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起看看吧
  • opencv 金字塔图像分割

    2018-11-13 04:04:25
    opencv 金字塔图像分割
  • OpenCV——二值图像连通域分析

    千次阅读 2018-06-30 10:40:48
    通域分析对于图像处理后面涉及到模式识别的内容来说是基础 连通区域(Connected Component)一般是指图像中具有相同像素值且位置相邻的前景像素点组成的图像区域(Region,Blob)。连通区域分析(Connected ...
  • OpenCV数字分割

    千次阅读 2018-11-30 10:16:32
    字符分割常用的方法有投影分割法和连通域分割法,对于下图若想提取其数字部分(这是项目中的某项指标,左边矩形是变化的),我才用的是连通域分割法,最后再加上轮廓筛选找到其位置 灰度化—&gt;自适应二值化...
  • 版权声明:本文为博主原创文章,可以随意共享转载,注明来源即可 ...通域分析对于图像处理后面涉及到模式识别的内容来说是基础 连通区域(Connected Component)一般是指图...
  • 提取图像中不同的连通域是图像处理中较为常用的方法,例如在车牌识别、文字识别、目标检测等领域对感兴趣区域分割与识别。一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响...
  • Opencv寻找连通域的几何中心 #include &quot;stdafx.h&quot; #include &amp;lt;iostream&amp;gt; #include &amp;lt;opencv2/opencv.hpp&amp;gt; using namespace cv; using namespace std....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 917
精华内容 366
关键字:

opencv连通域分割