广告合作
  • 今日头条

    今日头条

  • 百度一下

    百度一下,你就知道

  • 新浪网

    新浪网 - 提供新闻线索,重大新闻爆料

  • 搜狐

    搜狐

  • 豆瓣

    豆瓣

  • 百度贴吧

    百度贴吧——全球领先的中文社区

  • 首页 尚未审核订阅工具 订阅

    OpenCV:区域生长法实现

    来源:网络收集  点击:  时间:2024-05-07
    【导读】:
    绪:区域生长法是图像分割方法的一种;其是根据区域内像素点的相似性质;本文主要介绍:区域生长法的基本思想;关键问题;算法实现流程;示例程序;工具/原料moreOpenCV 2410方法/步骤1/6分步阅读

    基本思想:

    区域生长法的基本思想是:将具有相似性质的像素点合并到一起;

    在每一个区域内首先要指定一个种子点作为生长的起点;

    然后将种子点周围邻域的像素点与种子点进行比较,

    对具有相似性质的点合并之后继续向外生长,

    直到没有满足条件的像素被包括进来为止;

    这样一个区域的生长就完成了。

    下图是:发在PAMI上的LSD直线检测算法中的关键一步就是找line support regions.这个区域的查找就是利用区域生长法则,生长的条件就是梯度的方向角度;

    图中第一张图是原始图像,第二张是计算梯度角度,第三张是根据梯度角度区域生长的结果,相同颜色就是一个区域生长结果。

    2/6

    关键点在于:

    ①给定种子点(种子点如何选取)

    种子点的选取很多时候都采用人工交互的方法实现,

    也有用其他方式的,比如寻找物体并提取物体内部点作为种子点。

    ②确定在生长过程中能将相邻像素包括进来的准则(相似性质准则)

    灰度图像的差值;

    彩色图像的颜色等等。

    都是关于像素与像素间的关系描述。

    ③生长的停止条件:

    四连通与八连通

    3/6

    区域生长流程:

    ①给出种子点,这里一次给出一个种子点

    ②给出相似性准则,这里采用灰度差;

    ③将种子点与其八邻域像素点进行相似性比较;相似点则作为下次生长的种子点;

    ④停止生长:八邻域内没有合并的像素点时,即没有新的种子点时,停止。

    如图所示:

    4/6

    示例程序:

    OpenCV没有自带区域生长函数;

    为了说明区域是如何生长的,

    #include opencv2\opencv.hpp

    #include opencv2\highgui\highgui.hpp

    #include opencv2\features2d\features2d.hpp

    #include opencv2\core\core.hpp

    using namespace std;

    using namespace cv;

    void RegionGrowing(Mat srcImg,Mat dstImg,Point pt,int thre)

    {

    Point ptGrowing;//生长点像素坐标

    int nGrowLabel=0;//是否被标记

    int startPtValue=0;//生长起始点灰度值

    int currPtValue=0;//当前生长点灰度值

    //8邻域

    int mDir={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};

    vectorPoint growPtVec;//生长点堆栈

    growPtVec.push_back(pt);//将初始生长点压入堆栈

    Mat markImg=Mat::zeros(srcImg.size(),CV_8UC1);//标记点

    unsigned char *pData = (unsigned char *)(markImg.data+pt.y*markImg.step);

    pData=255;//标记初始生长点

    startPtValue = ((unsigned char*)(srcImg.data+pt.y*srcImg.step));

    while (!growPtVec.empty())

    {

    Point currPt = growPtVec.back();//返回当前vector最末一个元素

    growPtVec.pop_back();//弹出最后压入的数据

    for (int i=0;i8;i++)

    {

    ptGrowing.x = currPt.x+mDir;

    ptGrowing.y = currPt.y+mDir;

    //判断是否是边缘点

    if (ptGrowing.x0||ptGrowing.y0||(ptGrowing.xsrcImg.cols-1)||(ptGrowing.ysrcImg.rows))

    continue;//继续执行下一次循环

    //判断是否已被标记

    nGrowLabel = ((unsigned char*)(markImg.data+ptGrowing.y*markImg.step));

    if (nGrowLabel==0)//没有被标记

    {

    currPtValue = ((unsigned char*)(srcImg.data+ptGrowing.y*srcImg.step));

    if (abs(currPtValue-startPtValue)=thre)

    {

    ((unsigned char*)(markImg.data+ptGrowing.y*markImg.step))=255;

    growPtVec.push_back(ptGrowing);

    }

    }

    }

    }

    markImg.copyTo(dstImg);

    }

    int main()

    {

    Mat srcImg = imread(1.jpg,0);

    if (srcImg.empty())

    printf(image read error);

    Mat srcImg1=srcImg.clone();

    Mat outImg1,outImg2;

    RegionGrowing(srcImg1,outImg1,Point(241,258),10);

    RegionGrowing(srcImg1,outImg2,Point(302,118),80);

    add(outImg1,outImg2,outImg1);

    imshow(p1p2,outImg1);

    Mat resultImg;

    srcImg.copyTo(resultImg,~outImg1);

    imshow(outImg,resultImg);

    waitKey(0);

    return 0;

    }

    5/6

    算法效果:

    这里首先人为选取一个种子点,

    在其八邻域内,由相似性准则进行判断并更新种子点;

    当不再产生新的种子点时,截止;

    当区分多目标是,可以认为选取多个种子点,然后将每个种子点分割区域合并;

    即可分割出多目标。

    6/6

    给出一个比较好区域生长法的程序:

    //仅根据纹理分割图像,纹理特征是四维集合;

    void segmentTexture(Mat texture)

    {

    Mat regions(texture.rows, texture.cols, CV_8UC1, 0.0);

    Mat mark(texture.rows, texture.cols, CV_8UC1, 0.0);

    int min_regions = 10;

    RNG rng(25);

    Point seedPoint, now;

    Vec4b curr, next, seed;

    queuePoint Q;

    vectorpairpairPoint, Vec3b, int Points;

    int pixelCount=0;//pixel covered in a segment

    for(int i =250; i10; i -= 250/min_regions)

    {

    rng(12345);

    do

    {

    seedPoint.x = rng.uniform(0, texture.cols);

    seedPoint.y = rng.uniform(0, texture.rows);

    seed = texture.atVec4b(seedPoint.y, seedPoint.x);

    }

    while(mark.atuchar(seedPoint.y, seedPoint.x) !=0 );

    mark.atuchar(seedPoint.y, seedPoint.x) = i;

    Q.push(seedPoint);

    while(!Q.empty())

    {

    now = Q.front();

    Q.pop();

    curr=texture.atVec4b(now.y, now.x);

    for(int p=-1; p=1; p++)

    {

    for(int q=-1; q=1; q++)

    {

    if(0=now.x+p now.x+ptexture.cols 0=now.y+q now.y+qtexture.rows)

    {

    next=texture.atVec4b(now.y+q, now.x+p);

    if(mark.atuchar(now.y+q, now.x+p)==0

    (textureDifference(next, seed)==1 || farTextureDifference(next, curr)==2))

    {

    Q.push(Point(now.x+p, now.y+q));

    mark.atuchar(now.y+q, now.x+p)=i;

    //segm.atVec3b(now.y, now.x)=image.atVec3b(seedPoint.y, seedPoint.x);

    }

    }

    }

    }

    }

    }

    ///namedWindow(texture segment,2);

    ///imshow(texture segment,mark);

    imwrite(textureSegment.bmp,mark);

    }

    注意事项

    在每一个区域内首先要指定一个种子点作为生长的起点;

    然后将种子点周围邻域的像素点与种子点进行比较,

    对具有相似性质的点合并之后继续向外生长, 直到没有满足条件的像素被包括进来为止;

    区域生长法OPENCV区域OPENCV分割聚类分割
    本文关键词:

    版权声明:

    1、本文系转载,版权归原作者所有,旨在传递信息,不代表看本站的观点和立场。

    2、本站仅提供信息发布平台,不承担相关法律责任。

    3、若侵犯您的版权或隐私,请联系本站管理员删除。

    4、文章链接:http://www.ff371.cn/art_703432.html

    相关资讯

    ©2019-2020 http://www.ff371.cn/ 国ICP备20009186号06-03 11:01:18  耗时:0.024