0
votes

I am trying to fill everything that is outside a contour using a queue implementation of flood fill. However i have some problems deducing the starting point to add to the queue.

I define a new double of 400*400 named tmpSlice and fill it with zeroes. Then i map the contour with label value 1.0. This part works just fine.

The problem occurs when i have to push a starting point onto the queue the best scenario would be to push the top left corner or point 0.

However i can not push 0 as a starting point without getting a segmentation fault. I am currently pushing 160000 which is the size of tmpSlice this is the only number i have been able to insert without errors. However when i am pushing 160000 onto the queue and after the flood fill has executed i run the loop(at bottom of code) that runs from 0-160000.

This loop should color everything which has value 0 and 1 as one and everything that has value 2 should be zero. But currently everything inside the tmpSlice has value 0 except the original contour that has value 1.

For clarification 2 represents the outside of the contour, 1 represents the border of the contour and 0 represents whats inside the contour

So basically the flood fill does nothing on my dataset tmpSlice. I think it is because of the starting point inserted onto the queue but i haven't been able to insert any values that will work.

Thoughts? PS. I am limited to use the new double because a vector::std doesn't work with some functions from the minc library that i am using.

     /* Flood fill */
     //Colour we are looking for as background
     int TargetColour = 0.0;
     //The new colour we will write
     int NewColour = 2.0;
     //create set to secure unique entries into the queue, otherwise we etc. insert the 9th element in a 3x3 array 6 times.
     set < int > Set;
     //Create queue
     queue < int > MyQue;
     //Insert first point into the queue
     MyQue.push(sizes[1]*sizes[2]);
     int Node;
     //While loop for iterating over the nodes.
     while (!MyQue.empty()){
         //Set front element to Node, and pop the front element from queue
         Node = MyQue.front();
         MyQue.pop();

         //Change the colour to newcolour
         tmpSlice[Node] = NewColour;
         //Define the Node directions
         int WestNode = Node-1;
         int EastNode = Node+1;


         //sizes are the lengths x,y
         int NorthNode = Node-sizes[1];
         int SouthNode = Node+sizes[2];

         //Boundary checks
         EastNodeBoundaryCheck = floor((Node-sizes[1]*sizes[2]*floor(Node/(sizes[1]*sizes[2])))/sizes[1]) == floor((EastNode-sizes[1]*sizes[2]*floor(EastNode/(sizes[1]*sizes[2])))/sizes[1]);
         SouthNodeBoundaryCheck = floor(Node / (sizes[1]*sizes[2])) == floor(SouthNode / (sizes[1]*sizes[2]));
         WestNodeBoundaryCheck = floor((Node-sizes[1]*sizes[2]*floor(Node/(sizes[1]*sizes[2])))/sizes[1]) == floor((WestNode-sizes[1]*sizes[2]*floor(WestNode/(sizes[1]*sizes[2])))/sizes[1]);
         NorthNodeBoundaryCheck = floor(Node / (sizes[1]*sizes[2])) == floor(NorthNode / (sizes[1]*sizes[2]));


         //East Node
         if (Set.insert(EastNode).second) {
            if (tmpSlice[EastNode] == TargetColour && EastNodeBoundaryCheck == 1){
                MyQue.push(EastNode);
             }
          }

            //South Node
         if (Set.insert(SouthNode).second) {
            if (tmpSlice[SouthNode] == TargetColour && SouthNodeBoundaryCheck == 1){
                MyQue.push(SouthNode);
            }
         }

         //West Node
         if (Set.insert(WestNode).second) {
          if (tmpSlice[WestNode] == TargetColour && WestNodeBoundaryCheck == 1){
                MyQue.push(WestNode);
           }
        }

         //North Node
         if (Set.insert(NorthNode).second) {
            if (tmpSlice[NorthNode] == TargetColour && NorthNodeBoundaryCheck == 1){
                MyQue.push(NorthNode);
                }
        }


    }

    // Insert the colored points as 0 and everything else as 1
    for(i = 0; i < sizes[1]*sizes[2]; i++){
        if(tmpSlice[i] == 0.0 || 1.0){
            slab[first_voxel_at_slice + i] = 1.0;
        }
        if(tmpSlice[i] == 2.0){
            slab[first_voxel_at_slice + i] = 0.0;
        }
 }
1
What is the type of sizes[][]?em2er
@em2er sorry my bad. They are int and in my test case they are 400 and 400. I seem to be able to insert 0 onto the starting point if i remove the tmpSlice[NorthNode] == TargetColour. Apparently I'm unable to check the value of tmpSlice[-399] which actually makes sense. However now the bottom of the contour is gone.Joachim Hansen
Considering the type of Node is int and size[][] also, why are you using expressions like a floor(Node/(sizes[1]*sizes[2]))? if int divided by bigger int, the result is always 0, otherwise the result will be already floored. floor is for floating point values, it doesn't make sense in your way of using it.em2er
@em2er, I am sorry for being an inconvenience for you, i actually just solved it i needed to push 0 onto the queue, and make a check if the north node is bigger than 0 before trying to check the value. Thank you very much for getting me to think about sizes which led me to the answer :-)Joachim Hansen

1 Answers

0
votes

I found the answer myself when answering a comment :-) I needed to check the NorthNode if it was bigger than 0 for the first row to avoid segmentation fault.

         //North Node
         if (Set.insert(NorthNode).second) {
             if (NorthNode > 0){
                 if (tmpSlice[NorthNode] == TargetColour && NorthNodeBoundaryCheck == 1){
                         MyQue.push(NorthNode);
                     }
             }
        }