区域生长 订阅
区域生长(region growing)是指将成组的像素或区域发展成更大区域的过程。从种子点的集合开始,从这些点的区域增长是通过将与每个种子点有相似属性像强度、灰度级、纹理颜色等的相邻像素合并到此区域。 展开全文
区域生长(region growing)是指将成组的像素或区域发展成更大区域的过程。从种子点的集合开始,从这些点的区域增长是通过将与每个种子点有相似属性像强度、灰度级、纹理颜色等的相邻像素合并到此区域。
信息
拥    有
属性像强度、灰度级
属    于
成组的像素或区域发展成更大区域
中文名
区域生长
外文名
region growing
区域生长主要问题
它是一个迭代的过程,这里每个种子像素点都迭代生长, 直到处理过每个像素,因此形成了不同的区域,这些区域它们的边界通过闭合的多边形定义。在区域生长中的主要问题如下:(1)表示区域的初始化种子的选择:在区域生长过程中,这些不同区域点合适属性的选择。(2)基于图像具体属性的像素生长不一定是好的分割。在区域生长过程中,不应该使用连通性或邻接信息。(3)相似性:相似性表示在灰度级中观察在两个空间邻接像素之间或像素集合的平均灰度级间的最小差分,它们将产生不同的区域。如果这个差分比相似度阈值小,则像素属于相同的区域。(4)区域面积:最小面积阈值与像素中的最小区域大小有关。在分割的图像中,没有区域比这个阈值小,它由用户定义。区域生长的后处理(region growing post-processing):由于非优化参数的设置,区域生长经常会导致欠生长或过生长。人们已经开发了各种各样的后处理。从区域生长和基于边缘的分割中,后处理能获得联合分割的信息。更加简单的后处理是根据一般启发法,并且根据最初应用的均匀性标准,减少分割图像中无法与任何邻接区域合并的最小区域的数量。在场景中区域间的邻接关系可以由区域邻接图(region adjacency graph, RAG)表示。在场景中的区域由在RAG的节点集合表示 N = {N1, N2, ... , Nm},这里,节点Ni表示在场景中的区域Ri ,并且区域Ri的属性存储在节点的数据结构Ni中。在Ni和Nj之间的边缘Eij表示在区域Ri和Rj之间的连接。如果在区域Ri里存放一个像素与在区域Rj彼此相邻,那么两个区域Ri和Rj是相邻的。邻接可能是4连通或8连通的。邻接关系是自反(reflexive)和对称(symmetric)的,但不一定是可传递(transitive)的。下图显示具有6个截然不同区域的场景邻接图。 当它表示区域邻接图(RAG)是,二进制矩阵A成为 [1]  邻接矩阵(adjacency matrix)。在RAG里,当节点Ni和Nj邻接,在A中,aij是1。因为邻接关系是自反的,矩阵的对角元素都是1。在上图的多区域场景邻接矩阵(关系)如下所示。由于在场景中分割单一大区域,分割算法可能产生许多个小区域。在这种情况下,较小的区域需要根据相似性合并,并且使较小的区域更紧密。简单的区域合并算法如下所述。步骤1:使用阈值集合将图像分割为R1,R2,R,…,Rm。步骤2:从图像的分割描述中生成区域邻接图(region adjacency graphics,RAG)。步骤3:对于每个Rj,i = 1,2,…,m,从RAG中确定所有Rj,j≠i,如Ri和Rj邻接。步骤4:对于所有i和j,计算在Ri和Rj之间合适的相似性度量Sij。步骤5:如果Sij>T,那么合并Ri和Rj。步骤6:根据相似性标准,重复步骤3~步骤5,直到没有合并的区域为止。合并的另一个策略是根据两个区域之间的边缘强度。在这个方法中,在邻接区域之间的合并是根据两个区域间沿标定边界长度的边缘强度。如果边缘强度小,即边缘点较弱(weak),如果合并没有大量改变平均像素强度值,那么可以合并两个区域。还有这种情况:由于错误的预处理分割,产生了太小的区域。这归结于不同区域错误合并成一个区域。在这种情况下,在分割区域中灰度值的变化可能高于 [2]  阈值(T),因此,需要将区域分裂成更小的区域,这样每个更小的区域都有均匀小方差。分裂和合并可能结合在一起用于复杂场景的分割,基于规则可以指导分裂和合并运算的应用。
收起全文
精华内容
下载资源
问答
  • 区域生长

    2018-08-30 14:30:01
     区域生长算法的基本思想是将有相似性质的像素点合并到一起。对每一个区域要先指定一个种子点作为生长的起点,然后将种子点周围领域的像素点和种子点进行对比,将具有相似性质的点合并起来继...

    转自:https://blog.csdn.net/qq_37764129/article/details/81227091

    注:本程序只能做图像分割,结果图是转自原作者的,暂时没实现该功能。

    1、理论基础

          区域生长算法的基本思想是将有相似性质的像素点合并到一起。对每一个区域要先指定一个种子点作为生长的起点,然后将种子点周围领域的像素点和种子点进行对比,将具有相似性质的点合并起来继续向外生长,直到没有满足条件的像素被包括进来为止。这样一个区域的生长就完成了。这个过程中有几个关键的问题:

    a> 给定种子点(种子点如何选取?)

          种子点的选取很多时候都采用人工交互的方法实现,也有用其他方式的,比如寻找物体并提取物体内部点作为种子点。

    b> 确定在生长过程中能将相邻像素包括进来的准则

         灰度图像的差值;彩色图像的颜色等等。都是关于像素与像素间的关系描述。

    c> 生长的停止条件

    2、灰度差值的区域生长算法实现

    算法实现的步骤:

    a>  创建一个空白的图像(全黑);

    b> 将种子点存入vector中,vector中存储待生长的种子点;

    c> 依次弹出种子点并判断种子点如周围8领域的关系(生长规则),相似的点则作为下次生长的种子点;

    d> vector中不存在种子点后就停止生长。

    
     
    1. #include <opencv2\highgui\highgui.hpp>

    2. #include <iostream>

    3. #include "math.h"

    4.  
    5. using namespace cv;

    6. using namespace std;

    7.  
    8. Mat RegionGrow(Mat src, Point2i pt, int th)

    9. {

    10. Point2i ptGrowing; //待生长点位置

    11. int nGrowLable = 0; //标记是否生长过

    12. int nSrcValue = 0; //生长起点灰度值

    13. int nCurValue = 0; //当前生长点灰度值

    14. Mat matDst = Mat::zeros(src.size(), CV_8UC1); //创建一个空白区域,填充为黑色

    15. //生长方向顺序数据

    16. int DIR[8][2] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 } };

    17. Vector<Point2i> vcGrowPt; //生长点栈

    18. vcGrowPt.push_back(pt); //将生长点压入栈中

    19. matDst.at<uchar>(pt.y, pt.x) = 255; //标记生长点

    20. nSrcValue = src.at<uchar>(pt.y, pt.x); //记录生长点的灰度值

    21.  
    22. while (!vcGrowPt.empty()) //生长栈不为空则生长

    23. {

    24. pt = vcGrowPt.back(); //取出一个生长点

    25. vcGrowPt.pop_back();

    26.  
    27. //分别对八个方向上的点进行生长

    28. for (int i = 0; i<9; ++i)

    29. {

    30. ptGrowing.x = pt.x + DIR[i][0];

    31. ptGrowing.y = pt.y + DIR[i][1];

    32. //检查是否是边缘点

    33. if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1))

    34. continue;

    35.  
    36. nGrowLable = matDst.at<uchar>(ptGrowing.y, ptGrowing.x); //当前待生长点的灰度值

    37.  
    38. if (nGrowLable == 0) //如果标记点还没有被生长

    39. {

    40. nCurValue = src.at<uchar>(ptGrowing.y, ptGrowing.x);

    41. if (abs(nSrcValue - nCurValue) < th) //在阈值范围内则生长

    42. {

    43. matDst.at<uchar>(ptGrowing.y, ptGrowing.x) = 255; //标记为白色

    44. vcGrowPt.push_back(ptGrowing); //将下一个生长点压入栈中

    45. }

    46. }

    47. }

    48. }

    49. return matDst.clone();

    50. }

    51. int main() //区域生长

    52. {

    53. Mat src = imread("E:\\QT text\\image processing\\delineation\\image\\1.jpg");

    54. namedWindow("原图", 0);

    55. imshow("原图", src);

    56.  
    57. Point pt = (514,510); //待生长点位置

    58. int th = 10;

    59. src = RegionGrow(src, pt, th);

    60. namedWindow("RegionGrow", 0);

    61. imshow("RegionGrow", src);

    62. waitKey(0);

    63. return 0;

    64. }

    3、算法效果

    贴图看看使用该算法的图像处理效果:

    首先对原图像进行二值化:

            得到种子点的方法这里就不用介绍了,这个不是该算法的重点。得到两个种子点(左右肺),分别使用区域生长算法得到左右肺区,然后与原图进行与运算,得到结果:

            To:博乐评论中提到的原始区域生长的算法思想。原始区域生长中一般有四领域的生长和八领域的生长两种方式,基本思想和该算法是一致的。这个算法也是博主在以前没有使用opencv的程序中修改得来的。

    转自:https://blog.csdn.net/robin__chou/article/details/50071313

    相关博客:

    区域生长基础理论及代码:https://blog.csdn.net/gaohuazhao/article/details/51100429

    展开全文
  • PCL 区域生长分割

    万次阅读 2020-07-25 20:45:48
    基于区域生长的分割

    一、算法原理

    1、算法流程

      根据点的曲率值对点云进行排序,曲率最小的点叫做初始种子点,
    (1)区域生长算法从曲率最小的种子点开始生长,初始种子点所在区域为最平滑区域,从初始种子点所在的区域开始生长可减小分割片段的总数,从而提高算法的效率。
    (2)设置一空的聚类区域C和空的种子点序列Q,聚类数组L。
    (3)选好初始种子点,将其加入种子点序列Q中,并搜索该种子点的领域点,计算每一个领域点法线与种子点法线之间的夹角,小于设定的平滑阀值时,将领域点加入到C中,同时判断该领域点的曲率值是否小于曲率阀值,将小于曲率阈值的领域点加入种子点序列Q中,在邻域点都判断完成后,删除当前种子点,在Q中重新选择新的种子点重复上述步骤,直到Q中序列为空,一个区域生长完成,将其加入聚类数组L中。
    (4)利用曲率值从小到大排序,顺序选择输入点集 的点作为种子点加入到种子点序列中,重复以上生长的步骤。

    2、算法概述

    在这里插入图片描述

    2、代码图解

    在这里插入图片描述

    二、代码实现

    #include <iostream>
    #include <vector>
    #include <pcl/point_types.h>
    #include <pcl/io/pcd_io.h>
    #include <pcl/search/search.h>
    #include <pcl/search/kdtree.h>
    #include <pcl/features/normal_3d.h>
    #include <pcl/visualization/cloud_viewer.h>
    #include <pcl/filters/passthrough.h>
    #include <pcl/segmentation/region_growing.h>//区域生长
    #include <pcl/console/print.h>
    #include <pcl/console/parse.h>
    #include <pcl/console/time.h>
    #include <windows.h>
    #include <stdio.h>
    #include <psapi.h>
    void PrintMemoryInfo( )
    {
        HANDLE hProcess;
        PROCESS_MEMORY_COUNTERS pmc;
    
    	hProcess=GetCurrentProcess();
        printf( "\nProcess ID: %u\n", hProcess );
    
    	//输出进程使用的内存信息
       
        if (NULL == hProcess)
            return;
    
        if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
        {
            printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
            printf( "\tPeakWorkingSetSize: 0x%08X\n", 
                      pmc.PeakWorkingSetSize );
            printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
            printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", 
                      pmc.QuotaPeakPagedPoolUsage );
            printf( "\tQuotaPagedPoolUsage: 0x%08X\n", 
                      pmc.QuotaPagedPoolUsage );
            printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", 
                      pmc.QuotaPeakNonPagedPoolUsage );
            printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", 
                      pmc.QuotaNonPagedPoolUsage );
            printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); 
            printf( "\tPeakPagefileUsage: 0x%08X\n", 
                      pmc.PeakPagefileUsage );
        }
    
        CloseHandle( hProcess );
    }
    
    using namespace pcl::console;
    int
    main (int argc, char** argv)
    {
    
    	if(argc<2)
    	{
    		std::cout<<".exe xx.pcd -kn 50 -bc 0 -fc 10.0 -nc 0 -st 30 -ct 0.05"<<endl;
    
    		return 0;
    	}//如果输入参数小于1个,输出提示
    	time_t start,end,diff[5],option;
    	start = time(0); 
    	int K=50;      //设置默认输入参数
    	bool Bool_Cuting=false;//设置默认输入参数
    	float far_cuting=10,near_cuting=0,SmoothnessThreshold=30.0,CurvatureThreshold=0.05;//设置默认输入参数
    	parse_argument (argc, argv, "-kn", K);
    	parse_argument (argc, argv, "-bc", Bool_Cuting);
    	parse_argument (argc, argv, "-fc", far_cuting);
    	parse_argument (argc, argv, "-nc", near_cuting);
    	parse_argument (argc, argv, "-st", SmoothnessThreshold);
    	parse_argument (argc, argv, "-ct", CurvatureThreshold);//设置输入参数方式
    	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    	if ( pcl::io::loadPCDFile <pcl::PointXYZ> (argv[1], *cloud) == -1)
    	{
    		std::cout << "Cloud reading failed." << std::endl;
    		return (-1);
    	}//--------------加载点云数据-------------------------------
    	end = time(0); 
    	diff[0] = difftime (end, start); 
    	PCL_INFO ("\Loading pcd file takes(seconds): %d\n", diff[0]); 
    	//----------------法线估计----------------------------------
    	pcl::search::Search<pcl::PointXYZ>::Ptr tree  (new pcl::search::KdTree<pcl::PointXYZ>);
    	pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);
    	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
    	n.setSearchMethod (tree);//设置搜索方法
    	n.setInputCloud (cloud);//设置法线估计对象输入点集
    	n.setKSearch (K);// 设置用于法向量估计的k近邻数目
    	n.compute (*normals);//计算并输出法向量
    	end = time(0); 
    	diff[1] = difftime (end, start)-diff[0]; 
    	PCL_INFO ("\Estimating normal takes(seconds): %d\n", diff[1]); 
    	//-----------------直通滤波---(可选操作)--------------------
    	pcl::IndicesPtr indices (new std::vector <int>);//创建一组索引
    	if(Bool_Cuting)//判断是否需要直通滤波
    	{
    		pcl::PassThrough<pcl::PointXYZ> pass;//设置直通滤波器对象
    		pass.setInputCloud (cloud);//设置输入点云
    		pass.setFilterFieldName ("z");//设置指定过滤的维度
    		pass.setFilterLimits (near_cuting, far_cuting);//设置指定纬度过滤的范围
    		pass.filter (*indices);//执行滤波,保存滤波结果在上述索引中
    	}
    
    	//-----------------------区域生长----------------------------
    	pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;//创建区域生长分割对象
    	reg.setMinClusterSize (50);//设置一个聚类需要的最小点数
    	reg.setMaxClusterSize (1000000);//设置一个聚类需要的最大点数
    	reg.setSearchMethod (tree);//设置搜索方法
    	reg.setNumberOfNeighbours (30);//设置搜索的临近点数目
    	reg.setInputCloud (cloud);//设置输入点云
    	if(Bool_Cuting)reg.setIndices (indices);//通过输入参数设置,确定是否输入点云索引
    	reg.setInputNormals (normals);//设置输入点云的法向量
    	reg.setSmoothnessThreshold (SmoothnessThreshold / 180.0 * M_PI);//设置平滑阈值
    	reg.setCurvatureThreshold (CurvatureThreshold);//设置曲率阈值
    
    	std::vector <pcl::PointIndices> clusters;
    	reg.extract (clusters);//获取聚类的结果,分割结果保存在点云索引的向量中。
    	end = time(0); 
    	diff[2] = difftime (end, start)-diff[0]-diff[1]; 
    	PCL_INFO ("\Region growing takes(seconds): %d\n", diff[2]); 
    
    	std::cout << "Number of clusters is equal to " << clusters.size () << std::endl;//输出聚类的数量
    	std::cout << "First cluster has " << clusters[0].indices.size () << " points." << endl;//输出第一个聚类的数量
    	std::cout << "These are the indices of the points of the initial" <<
    	std::endl << "cloud that belong to the first cluster:" << std::endl;
    	//---------------------------保存聚类的点云-----------------------------
    	/*int j = 0;
    	for (std::vector<pcl::PointIndices>::const_iterator it = clusters.begin(); it != clusters.end(); ++it)
    	{
    		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);
    
    		for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); pit++)
    			cloud_cluster->points.push_back(cloud->points[*pit]);
    		cloud_cluster->width = cloud_cluster->points.size();
    		cloud_cluster->height = 1;
    		cloud_cluster->is_dense = true;
    
    		std::cout << "PointCloud representing the Cluster: " << cloud_cluster->points.size() << " data points."
    			<< std::endl;
    		std::stringstream ss;
    		ss << "cloud_cluster_" << j << ".pcd";
    		pcl::io::savePCDFileASCII(ss.str(), *cloud_cluster);
    		cout << ss.str() << "Saved" << endl;
    		j++;
    	}
    
    	*/
    	PrintMemoryInfo();
    	//--------------------进行可视化------------------------------------------
    	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud ();
    	//保存附加颜色的点云
    	//pcl::io::savePCDFileASCII("colored_pointCloud.pcd",*colored_cloud);
    	pcl::visualization::CloudViewer viewer ("区域生长分割方法");
    	viewer.showCloud(colored_cloud);
    	while (!viewer.wasStopped ())
    	{
    	}
    
    	return (0);
    }
    

    三、结果展示

    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • PCL 基于颜色的区域生长分割

    万次阅读 2020-07-25 21:40:04
    基于颜色的区域生长分割

    一、算法原理

    1、原理概述

      该算法与区域生长算法一样,是基于同一策略之上的,与区域生长相比,该算法主要有两处不同:第一,该算法用颜色代替了法线,去掉了点云规模上 限的限制。可以认为,同一个颜色且挨得近,是一类的可能性很大,不需要上限来限制。所以这种方式比较适合用于室内场景分割,尤其是复杂室内场景,颜色分割可以轻松的将连续的场景点云变成不同的物体。哪怕是高低不平的地面,没法用采样一致分割器抽掉,颜色分割算法同样能完成分割任务。第二,利用合并算法来控制过分割或欠分割。分割过程中,若两个相邻聚类的平均颜色相差较少,则将这两个聚类合并。然后进行第二步合并,在此步骤中,检查每一个聚类所包含的点的数量,如果这个数量小于用户定义的值,则当前这个聚类与其相近邻聚类合并在一起。

    1、算法步骤

    (1)分割,当前种子点和领域点之间色差小于色差阀值的视为一个聚类;
    (2)合并,聚类之间的色差小于色差阀值和并为一个聚类,且当前聚类中点的数量小于聚类点数量的与最近的聚类合并在一起;

    3、代码图解

    在这里插入图片描述

    二、代码实现

    #include <iostream>
    #include <vector>
    #include <pcl/point_types.h>
    #include <pcl/io/pcd_io.h>
    #include <pcl/search/search.h>
    #include <pcl/search/kdtree.h>
    #include <pcl/visualization/cloud_viewer.h>
    #include <boost/thread/thread.hpp>
    #include <pcl/filters/passthrough.h>
    #include <pcl/segmentation/region_growing_rgb.h>
    
    using namespace std;
    
    int
    main(int argc, char** argv)
    {
        
    
        pcl::PointCloud <pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud <pcl::PointXYZRGB>);
        if (pcl::io::loadPCDFile <pcl::PointXYZRGB>("region_growing_rgb_tutorial.pcd", *cloud) == -1)
        {
            cout << "Cloud reading failed." << endl;
            return (-1);
        }
        //-------------------------直通滤波----------------------------
        pcl::IndicesPtr indices(new std::vector <int>);
        pcl::PassThrough<pcl::PointXYZRGB> pass;
        pass.setInputCloud(cloud);
        pass.setFilterFieldName("z");
        pass.setFilterLimits(0.0, 1.0);
        pass.filter(*indices);
        //-----------------可以同时用颜色测试和法线测试这两种手段-----------------------
        pcl::search::Search <pcl::PointXYZRGB>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGB>);
        pcl::RegionGrowingRGB<pcl::PointXYZRGB> reg;
        reg.setInputCloud(cloud);
        reg.setIndices(indices);
        reg.setSearchMethod(tree);
        reg.setDistanceThreshold(10);//设置距离阈值,用于聚类相邻点搜索
        reg.setPointColorThreshold(6);//设置两点颜色阈值
        reg.setRegionColorThreshold(5);//设置两类区域颜色阈值
        reg.setMinClusterSize(600);//设置一个聚类的最少点数目
    
        vector <pcl::PointIndices> clusters;
        reg.extract(clusters);//获取聚类的结果,分割结果保存在点云索引的向量中
        //------------对不同的聚类分割结果,随机赋予颜色---------------------------
        pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud();
        //----------------------------可视化----------------------------------------
        pcl::visualization::CloudViewer viewer("Cluster viewer");
        viewer.showCloud(colored_cloud);
        while (!viewer.wasStopped())
        {
            
        }
    
        return 0;
    }
    
    

    三、结果展示

    1、参数设置

    在这里插入图片描述

    2、可视化

    在这里插入图片描述

    展开全文
  • 4.1图像分割之区域生长

    万次阅读 多人点赞 2018-08-04 16:37:39
    传统的区域分割方法有区域生长和区域分裂与合并, 其中最基础的是区域生长法。 区域生长法  区域生长是根据事先定义的准则将像素或者子区域聚合成更大区域的过程。其基本思想是从一组生长点开始...
     我们将讨论以区域为基础的图像分割处理技术。传统的区域分割方法有区域生长和区域分裂与合并,
     其中最基础的是区域生长法。
    

    区域生长法

    区域生长是根据事先定义的准则将像素或者子区域聚合成更大区域的过程。其基本思想是从一组生长点开始(生长点可以是单个像素,也可以是某个小区域),将与该生长点性质相似的相邻像素或者区域与生长点合并,形成新的生长点,重复此过程直到不能生长为止。生长点和相似区域的相似性判断依据可以是灰度值、纹理、颜色等图像信息。所以区域生长算法关键有三个:
    1、选择合适的生长点
    2、确定相似性准则即生长准则
    3、确定生长停止条件
      下面给出一个区域生长的实例:图(a)为原始图像,数字表示像素的灰度。以灰度值为8的像素为初始的生长点,记为f(i,j)。在8邻域内,生长准则是待测点灰度值与生长点灰度值相差为1或0.那么图(b)是第一次区域生长后,f(i-1,j)、f(i,j-1)、f(i,j+1)和生长点灰度值相差都是1,因而被合并。图©是第二次生长后,f(i+1,j)被合并。图(d)为第三次生长后,f(i+1,j-1)、f(i+2,j)被合并,至此,已经不存在满足生长准则的像素点,生长停止。
    这里写图片描述

    示例演示

    我们实现一个功能,鼠标选择一个初始生长点,生长准则是待测点灰度值与初始生长点灰度值差的绝对值不大于8。示例代码中regionGrow函数参考了《数字图像处理与机器视觉》第九章第五节,regionGrowFast函数是优化过的实现,代码如下:

    cv::Mat MainWindow::regionGrowFast(const cv::Mat &src, const cv::Point2i seed, int throld)
    {
        //convert src to gray for getting gray value of every pixel
        cv::Mat gray;
        cv::cvtColor(src,gray, cv::COLOR_RGB2GRAY);
    
        // set every pixel to black
        cv::Mat result = cv::Mat::zeros(src.size(), CV_8UC1);
        if((seed.x < 0) || (seed.y < 0))
            return result;
        result.at<uchar>(seed.y, seed.x) = 255;
    
        //gray value of seed
        int seed_gray = gray.at<uchar>(seed.y, seed.x);
        //grow direction sequenc
        int grow_direction[8][2] = {{-1,-1}, {0,-1}, {1,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}};
        //seeds collection
        std::vector<cv::Point2i> seeds;
        seeds.push_back(seed);
    
        //start growing
        while(! seeds.empty()){
            //get a seed
            cv::Point2i current_seed = seeds.back();
            seeds.pop_back();
    
            for(int i = 0; i < 8; ++i){
                cv::Point2i neighbor_seed(current_seed.x + grow_direction[i][0], current_seed.y + grow_direction[i][1]);
                //check wether in image
                if(neighbor_seed.x < 0 || neighbor_seed.y < 0 || neighbor_seed.x > (gray.cols-1) || (neighbor_seed.y > gray.rows -1))
                    continue;
                int value = gray.at<uchar>(neighbor_seed.y, neighbor_seed.x);
                if((result.at<uchar>(neighbor_seed.y, neighbor_seed.x) == 0) && (abs(value - seed_gray) <= throld)){
                    result.at<uchar>(neighbor_seed.y, neighbor_seed.x) = 255;
                    seeds.push_back(neighbor_seed);
                }
            }
        }
        return result;
    }
    

    运行结果:

    这里写图片描述

    [代码下载]

    展开全文
  • 区域生长法MATLAB

    2020-07-08 20:01:09
    区域生长算法的设计主要由以下三点:生长种子点的确定,区域生长的条件,区域生长停止的条件。 代码采用交互的方式,用鼠标选取合适的种子点,搜索种子点8邻域内的像素。
  • 区域生长算法程序

    2018-03-19 15:07:03
    区域生长的matlab程序。可以用来进行学习区域生长算法时使用,
  • 摘要:多种子的区域生长算法,基于C++编写。关键字:图像处理, 种子生长, 区域生长1. 题外话最近需要找一种简单对图像进行分割的算法,作为后续算法的前处理阶段。最开始想到的是聚类,但是聚类会有分割后不保证连通...
  • 区域生长是一种串行区域分割的图像分割方法。区域生长是指从某个像素出发,按照一定的准则,逐步加入邻近像素,当满足一定的条件时,区域生长终止。区域生长的好坏决定于1.初始点(种子点)的选取。2.生长准则。3....
  • 区域生长算法实现

    2017-07-11 15:45:48
    区域生长算法实现简单历程
  • 区域生长代码

    2016-01-06 10:58:02
    区域生长算法,适合学习。需要vs以及opencv2的开发环境,运行成功后点击图像选择种子点即可
  • 区域生长算法

    2015-04-19 17:15:55
    区域生长算法的简单实现,人工选取种子,对二值图像的前景进行分割。
  • 三维区域生长

    2018-01-23 22:00:29
    区域生长(region growing)是指将成组的像素或区域发展成更大区域的过程。从种子点的集合开始,从这些点的区域增长是通过将与每个种子点有相似属性像强度、灰度级、纹理颜色等的相邻像素合并到此区域。
  • 示例程序:OpenCV没有自带区域生长函数;为了说明区域是如何生长的,#include #include #include #include using namespace std;using namespace cv;void RegionGrowing(Mat srcImg,Mat& dstImg,Point pt,int th...
  • 区域生长matlab代码

    2015-04-16 15:07:42
    区域生长的代码,matlab实现 手动点选种子点,根据设置的阈值(可更改),进行区域生长
  • 区域生长

    千次阅读 2018-06-16 21:07:56
    区域生长的基本思想是将具有相似性质的像素集合起来构成区域。具体先对每个需要分割的区域找一个种子像素作为生长的起点,然后将种子像素周围邻域中与种子像素具有相同或相似性质的像素(根据某种事先确定的生长或...
  • 区域生长种子点选取,种子点变换生长,种子点变换生长,种子点变换生长,种子点变换生长,种子点变换生长,种子点变换生长,种子点变换生长
  • 区域生长:就是以某个像素值进行扩散,查找颜色相近的范围区域。 这里主要介绍四种方法:固定灰度值、动态灰度值、固定RGB值、动态RGB值。这四种方法对应不同图片。经测试效果可以 1.固定灰度值区域生长 //固定...
  • matlab图像区域生长

    2017-06-20 23:26:12
    MATLAB编写的图像区域生长函数(附原图像和结果),用于二值图像的分割,由于for循环调用较多,建议先认真阅读,谨慎运行。
  • 区域生长法MATLAB版本程序代码,需要把图像名字改成程序里一致的 区域生长法MATLAB版本程序代码,需要把图像名字改成程序里一致的
  • 区域生长法分割

    2020-06-24 10:48:10
    区域分割区域生长区域生长区域生长法的基本思想就是将具有相似性的像素集合起来形成一个区域。 具体做法就是,首先选择一个种子点,通过比较种子点邻域的相似性,将邻域中满足相似性准则的像素归入种子点所在...
  • 基于区域生长图像分割

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,309
精华内容 523
关键字:

区域生长