当前位置:网站首页 > 创业 > 正文

OpenCV:区域生长法实现

0 张子豪 张子豪 2025-10-12 03:58 1

绪:

区域发展法是图像朋分方式的一种;

其是按照区域内像素点的相似性质;

本文本家儿要介绍:

区域发展法的根基思惟;关头问题;

算法实现流程;示例法式;

东西/原料

  • OpenCV 2410

方式/步调

  1. 1

    根基思惟:

    区域发展法的根基思惟是:将具有相似性质的像素点归并到一路;

    在每一个区域内起首要指心猿意马一个种子点作为发展的起点;

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

    对具有相似性质的点归并之后继续标的目的外发展,

    直到没有知足前提的像素被包罗进来为止;

    如许一个区域的发展就完当作了。

    下图是:发在PAMI上的LSD直线检测算法中的关头一步就是找line support regions.这个区域的查找就是操纵区域发展法例,发展的前提就是梯度的偏向角度;

    图中第一张图是原始图像,第二张是计较梯度角度,第三张是按照梯度角度区域发展的成果,不异颜色就是一个区域发展成果。

  2. 2

    关头点在于:

    ①给心猿意马种子点(种子点若何拔取)

    种子点的拔取良多时辰都采用人工交互的方式实现,

    也有效其他体例的,好比寻找物体并提取物体内部点作为种子点。

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

    灰度图像的差值;

    彩色图像的颜色等等。

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

    ③发展的遏制前提:

    四连通与八连通

  3. 3

    区域发展流程:

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

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

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

    ④遏制发展:八邻域内没有归并的像素点时,即没有新的种子点时,遏制。

    如图所示:

  4. 4

    示例法式:

    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[8][2]={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};

     

           vector<Point> 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[pt.x]=255;//标识表记标帜初始发展点

          

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

          

           while (!growPtVec.empty())

           {

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

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

     

                  for (int i=0;i<8;i++)

                  {

                         ptGrowing.x = currPt.x+mDir[i][0];

                         ptGrowing.y = currPt.y+mDir[i][1];

                         //判定是否是边缘点

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

                                continue;//继续执行下一次轮回

                         //判定是否已被标识表记标帜

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

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

                         {

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

                                if (abs(currPtValue-startPtValue)<=thre)

                                {

                                       ((unsigned char*)(markImg.data+ptGrowing.y*markImg.step))[ptGrowing.x]=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. 5

    算法结果:

    这里起首报酬拔取一个种子点,

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

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

    当区分多方针是,可以认为拔取多个种子点,然后将每个种子点朋分区域归并;

    即可朋分出多方针。

  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;

        queue<Point> Q;

     

        vector<pair<pair<Point, Vec3b>, int> > Points;

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

     

        for(int i =250; i>10; i -= 250/min_regions)

        {

            rng(12345);

            do

            {

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

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

                seed = texture.at<Vec4b>(seedPoint.y, seedPoint.x);

            }

            while(mark.at<uchar>(seedPoint.y, seedPoint.x) !=0 );

     

            mark.at<uchar>(seedPoint.y, seedPoint.x) = i;

            Q.push(seedPoint);

     

            while(!Q.empty())

            {

                now = Q.front();

                Q.pop();

     

                curr=texture.at<Vec4b>(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+p<texture.cols && 0<=now.y+q && now.y+q<texture.rows)

                        {

                            next=texture.at<Vec4b>(now.y+q, now.x+p);

                            if(mark.at<uchar>(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.at<uchar>(now.y+q, now.x+p)=i;

                                //segm.at<Vec3b>(now.y, now.x)=image.at<Vec3b>(seedPoint.y, seedPoint.x);

                            }

                        }

                    }

                }

            }

        }

        ///namedWindow("texture segment",2);

        ///imshow("texture segment",mark);

        imwrite("textureSegment.bmp",mark);

    }

注重事项

  • 在每一个区域内起首要指心猿意马一个种子点作为发展的起点;
  • 然后将种子点四周邻域的像素点与种子点进行比力,
  • 对具有相似性质的点归并之后继续标的目的外发展, 直到没有知足前提的像素被包罗进来为止;

来源:百闻(微信/QQ号:9397569),转载请保留出处和链接!


本文链接:https://www.ibaiwen.com/web/236033.html

张子豪

张子豪

TA很懒,啥都没写...

@百闻娱乐 本站部分内容转自互联网,若有侵权等问题请及时与本站联系,我们将在第一时间删除处理。 | 粤ICP备2024343649号 | (地图