Ask Your Question
0

Extract connected pixels using the idea of Breadth-first search

asked 2013-05-17 06:24:27 -0600

Jawaher Khemakhem gravatar image

updated 2013-05-17 06:28:07 -0600

I am trying to collect a set of pixels between two pixels:start and end point from a skeleton image . image description So the idea is : I start on a position in the image. I put that position in a list. Then in a loop,

  • I get and remove the point at the beginning of the list and make it black in the current image so it won't be added again.
  • I put that point in another list (this is the list that you want).I look at every point around the position and if it is not black, add it to the beginning of the list.

Then start the loop again.

I have develop a piece of code but the loop ends after adding four or five pixels ,before arriving to the end point

 vector<Point> traceLine(Mat img , Point peak)

  {

   vector<Point> vect1;
   vector<Point> vect2;
   vect1.push_back(peak);
        while(vect1.size() != 0)
          {
            Point p=vect1[0];
            img.at<uchar>(p.x,p.y)=0;
            vect1.erase(vect1.begin());
            //cout<<vect1[1];

            vect2.push_back(p);
             vector<Point> vectN;
            vectN=search8Neighbor(img,p);
            cout<<vectN.size()<<endl;
            if(vectN.size()!=0)
                  {
                   for(int i=0;i<vectN.size();i++)

                     vect1.push_back(vectN[i]);

                  }
           }
        return vect2;
 }
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
2

answered 2013-05-20 09:06:07 -0600

Notas gravatar image

First, access matrix elements using row and then column, not the other way around. Second, you should take a look at your image. It is not binary. I did a threshold using gimp and around your skeleton lines are lots of pixels with values < 10 which of course get added to the list and are processed. So binarize the image. Plus, I forgot one thing. Change the beginning of the loop to this: Point p=vect1[0]; vect1.erase(vect1.begin()); if (img.at<uchar>(p.y,p.x) == 0) { continue; } img.at<uchar>(p.y,p.x)=0; ... Otherwise, it is possible that a point gets visited again a second time e.g. if you have points that are next to each other.

Plus, since you want to have the different lines from the middle, you have to call the algorithm on the pixel above, below left and below right of your middle point. If you call it once with the middle, it adds everything in the picture into one list.

edit flag offensive delete link more

Comments

I have successfully modified the code ; thank a lot for your answer :)

Jawaher Khemakhem gravatar imageJawaher Khemakhem ( 2013-05-20 10:12:55 -0600 )edit
0

answered 2013-05-20 10:15:00 -0600

Jawaher Khemakhem gravatar image

the code above will be :

  vector<Point> traceLine(Mat img , Point peak)
   {
vector<Point> vect1;
vector<Point> vect2;
img.at<uchar>(peak.y, peak.x)=0;//
vect1.push_back(peak);//add peak to vect1
while(vect1.size() != 0)
    {
    Point p=vect1[0];
    vect1.erase(vect1.begin());
    vect2.push_back(p);
    vector<Point> vectN;
    vectN = search8Neighbor(img, p);

    //cout<< " vectN.size()=" << vectN.size()<<endl;

    for(int i = 0; i < int(vectN.size()); ++i)
        {
            img.at<uchar>(vectN[i].y, vectN[i].x)=0;
            vect1.push_back(vectN[i]);
        }
    }
return vect2;
}
edit flag offensive delete link more

Comments

Could I ask you how you take the starting point? I need to take the starting point automatically first and then trace the line using DFS instead of BFS graph search. I would appreciate if you could help me.

Saturn gravatar imageSaturn ( 2016-07-05 12:56:29 -0600 )edit

Question Tools

Stats

Asked: 2013-05-17 06:24:27 -0600

Seen: 2,578 times

Last updated: May 20 '13