Не удается найти правильное начальное значение для реализации FloodFill в C++

Я пытаюсь заполнить все, что находится за пределами контура, используя реализацию заливки с очередью. Однако у меня есть некоторые проблемы с выводом начальной точки для добавления в очередь.

Я определяю новый дубль 400*400 с именем tmpSlice и заполняю его нулями. Затем я наношу контур со значением метки 1.0. Эта часть работает просто отлично.

Проблема возникает, когда мне нужно поместить начальную точку в очередь, лучшим сценарием будет нажатие на верхний левый угол или точку 0.

Однако я не могу нажать 0 в качестве отправной точки, не получив ошибку сегментации. В настоящее время я нажимаю 160000, что соответствует размеру tmpSlice, это единственное число, которое я смог вставить без ошибок. Однако, когда я помещаю 160000 в очередь и после выполнения заливки, я запускаю цикл (в нижней части кода), который выполняется от 0 до 160000.

Этот цикл должен окрашивать все, что имеет значение 0 и 1, как единицу, а все, что имеет значение 2, должно быть равно нулю. Но в настоящее время все внутри tmpSlice имеет значение 0, кроме исходного контура, значение которого равно 1.

Для уточнения 2 представляет собой внешнюю часть контура, 1 представляет собой границу контура и 0 представляет то, что находится внутри контура.

Таким образом, в основном заливка ничего не делает с моим набором данных tmpSlice. Я думаю, это из-за того, что начальная точка вставлена ​​в очередь, но я не смог вставить какие-либо значения, которые будут работать.

Мысли? PS. Я ограничен в использовании нового двойника, потому что vector::std не работает с некоторыми функциями из библиотеки minc, которую я использую.

     /* 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;
        }
 }

person Joachim Hansen    schedule 18.03.2017    source источник
comment
Что такое тип размеров[][]?   -  person em2er    schedule 18.03.2017
comment
@ em2er извините, мой плохой. Это int, и в моем тестовом случае это 400 и 400. Кажется, я могу вставить 0 в начальную точку, если я удалю tmpSlice[NorthNode] == TargetColour. По-видимому, я не могу проверить значение tmpSlice[-399], что на самом деле имеет смысл. Однако теперь нижняя часть контура исчезла.   -  person Joachim Hansen    schedule 18.03.2017
comment
Учитывая, что тип Node — int, а size[][] также, почему вы используете такие выражения, как floor(Node/(sizes[1]*sizes[2]))? если целое разделить на большее целое, результат всегда будет 0, иначе результат будет уже наполовину. floor предназначен для значений с плавающей запятой, его использование не имеет смысла.   -  person em2er    schedule 18.03.2017
comment
@ em2er, извините за неудобство для вас, я на самом деле только что решил это, мне нужно было поместить 0 в очередь и проверить, больше ли северный узел, чем 0, прежде чем пытаться проверить значение. Большое спасибо за то, что заставили меня задуматься о размерах, которые привели меня к ответу :-)   -  person Joachim Hansen    schedule 18.03.2017


Ответы (1)


Я сам нашел ответ, отвечая на комментарий :-) Мне нужно было проверить NorthNode, если он больше 0 для первой строки, чтобы избежать ошибки сегментации.

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