функция подсчета больших двоичных объектов в C

#c #recursion #blob

#c #рекурсия #большой двоичный объект

Вопрос:

Сегодня у нас была задача, в которой нам нужно было найти все пиксели, которые были связаны друг с другом на картинке. Изображение просто зеленое = 1, без цвета = 0 и может быть представлено в виде массива:

     int grid[5][5] = {
    {1, 1, 0, 0, 0},
    {0, 1, 1, 0, 0},
    {0, 0, 1, 0, 1},
    {1, 0, 0, 0, 1},
    {0, 1, 0, 1, 1},
};
  

Мы сидели 3 часа в моей группе и пытались решить эту проблему (первая лекция о рекурсии), но мы просто не можем заставить ее работать. Проблема, похоже, в том, что функции каким-то образом принимают нахождение вне сетки. Любой, кто, вот код:

 #include <stdio.h>
#include <string.h>

//Prototype
int blob_count(int y, int x, int gridCopy[][5], int sum);

int blob_count(int y, int x, int gridCopy[][5], int sum){

   //Local vars
    int posX, posY;
    printf("nnX: %d - Y: %dnposX: %d - posY: %dnSum: %d", x, y, posX, posY, sum);
    printf("nn{%d - %d - %d - %d - %d}n{%d - %d - %d - %d - %d}n{%d - %d - %d - %d - %d}n{%d - %d - %d - %d - %d}n{%d - %d - %d - %d - %d}n",
           gridCopy[0][0],
           gridCopy[0][1],
           gridCopy[0][2],
           gridCopy[0][3],
           gridCopy[0][4],

           gridCopy[1][0],
           gridCopy[1][1],
           gridCopy[1][2],
           gridCopy[1][3],
           gridCopy[1][4],

           gridCopy[2][0],
           gridCopy[2][1],
           gridCopy[2][2],
           gridCopy[2][3],
           gridCopy[2][4],

           gridCopy[3][0],
           gridCopy[3][1],
           gridCopy[3][2],
           gridCopy[3][3],
           gridCopy[3][4],

           gridCopy[4][0],
           gridCopy[4][1],
           gridCopy[4][2],
           gridCopy[4][3],
           gridCopy[4][4]); 

    //Find the position 1 behind and 1 above the starting point, and start the loop there
    for(posX = -1;posX <=1; posX  ){
        for(posY = -1; posY <= 1; posY  ){
            if((y   posY) >= 0 amp;amp; (x   posX) >= 0){
                if((y   posY) <= 5 amp;amp; (x   posX) <= 5){
                    if(gridCopy[posY y][posX x] == 1){
                        //Set the starting point to 0 (so it wont get calculated again)
                        gridCopy[posY y][posX x] = 0;



                        y = posY y;
                        x = posX x;

                        sum  ;
                        blob_count(y, x, gridCopy, sum);
                    }
                }
            }
        }
    }

    return sum;



}

int main (void)
{

    int grid[5][5] = {
        {1, 1, 0, 0, 0},
        {0, 1, 1, 0, 0},
        {0, 0, 1, 0, 1},
        {1, 0, 0, 0, 1},
        {0, 1, 0, 1, 1},
    };

    //Create a manipulateable grid
    int gridCopy[5][5];
    memcpy(gridCopy, grid, 5*5*sizeof(int));

    //Start Positions
    int start_x = 0;
    int start_y = 3;

    //If the starting point selected, is not 0, initiate the function:
    if(grid[start_y][start_x] != 0){
        printf("nSum: %d", blob_count(start_y ,start_x, gridCopy, 0));
    }




}
  

Редактировать:

Я обновил приведенный выше код, и теперь у меня новая проблема, он получает правильную сумму (количество пикселей в сочетании друг с другом), однако, когда я распечатываю сумму (в main();), она говорит 1, почему она не переносится из рекурсивной функциик основной функции?

Комментарии:

1. Моя проблема заключалась бы в том, что, похоже, она выходит за пределы сетки, хотя это не должно быть разрешено, я не вижу, как я могу приблизиться, когда я не уверен, в чем именно проблема, кроме того, что она этого не делает.

Ответ №1:

Вы смотрите на всех соседей текущего пикселя:

 for(posX = -1;posX<=1;posX  ){
    for(posY = -1; posY<= 1;posY  ){
  

И вы проверяете, что координаты положительные:

         if((y   posY) >= 0 amp;amp; (x   posX) >= 0){
  

Но вы не проверяете, что координаты не переполняются:

         if((y   posY) < 5 amp;amp; (x   posX) < 5) {
  

И вместо этого получить доступ к неопределенным данным за пределами сетки:

             if(gridCopy[posY y][posX x] == 1){
  

Вероятно, это все равно не сработает, но, поскольку это домашнее задание, я просто дам вам несколько советов: вы игнорируете возвращаемое значение рекурсивного вызова (не делайте этого) и не инициализируете sum (включите предупреждения компилятора, чтобы получать уведомления об этом).). Вы также не копируете всю сетку целиком: memcpy(gridCopy, grid, 5*5); копирует 25 байт, а не 25 целых. Используйте memcpy(gridCopy, grid, 5 * 5 * sizeof(int)); вместо этого.

Комментарии:

1. Спасибо, я изучу эти вещи. Однако это не домашнее задание. Наши лекции состоят из 2 частей: 1 часть лекции и 1 часть групповой работы. Групповые задачи используются только в этих уроках, поэтому я не буду разбираться, как это сделать, если я не исследую себя, и мне не нужно это включать.