Ошибка сегментации (дамп ядра) при создании нескольких матриц - PullRequest
0 голосов
/ 04 декабря 2018

Для моего класса по компьютерному зрению мы сейчас работаем над алгоритмом обнаружения краев Canny Edge.Для тех, кто знаком, алгоритм включает в себя использование оттенков серого изображения для создания вектора градиента для каждого пикселя.Таким образом, в моем коде есть две матрицы для хранения этой информации: одна из величин и один из углов.

double edge[height][width];
double max = 0;
for(int r = 0; r<height; r++)
{
    for(int c = 0; c<width; c++)
    {
        if(r==0||c==0||r+1==height||c+1==width)
        {
            edge[r][c]=0;
        }
        else
        {
            edge[r][c]=sqrt(pow((2*greyscale[r-1][c])+greyscale[r-1][c+1]+greyscale[r-1][c-1]-(2*greyscale[r+1][c])-greyscale[r+1][c+1]-greyscale[r+1][c-1],2.0)+pow((2*greyscale[r][c-1])+greyscale[r+1][c-1]+greyscale[r-1][c-1]-(2*greyscale[r][c+1])-greyscale[r-1][c+1]-greyscale[r+1][c+1],2.0));
            if(edge[r][c]>max)
            {
                max=edge[r][c];
            }
        }
    }
}
//cout<<"makes edge"<<endl;
double atans[height][width]; //should work, but creates memory error when uncommented
for(int r = 0; r<height; r++)
{
    for(int c = 0; c<width; c++)
    {
        cout<<r<<", "<<c<<endl;
        if(r==0||c==0||r+1==height||c+1==width)
        {
            atans[r][c]=0;
        }
        else
        {
            atans[r][c] = atan2(2*greyscale[r-1][c]+greyscale[r-1][c+1]+greyscale[r-1][c-1]-2*greyscale[r+1][c]-greyscale[r+1][c+1]-greyscale[r+1][c-1],2*greyscale[r][c-1]+greyscale[r+1][c-1]+greyscale[r-1][c-1]-2*greyscale[r][c+1]-greyscale[r-1][c+1]-greyscale[r+1][c+1]);
        }
    }
}

Мой код исправляет матрицу ребер, но при попытке вызвать ошибку сегментацииматрица Атана.Любые предложения о том, как это исправить?

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

Выделите ваш массив в векторе, предпочтительно в одномерном векторе.

Проблема в том, что эта строка:

double atans[height][width];

, если вы используете переменные height и width, тогдаэто недопустимый C ++, так как это C99.

Если они постоянные, то это допустимый C ++, но вы размещаете свой массив в стеке и, возможно, взрываете его.

0 голосов
/ 04 декабря 2018

Полагаю, вы определили greyscale[height][width].

Затем в строке

atans[r][c] =   
atan2(2*greyscale[r-1][c]+greyscale[r-1][c+1]+greyscale[r-1][c-1]-2*greyscale[r+1][c]-greyscale[r+1][c+1]
-greyscale[r+1][c-1],2*greyscale[r][c-1]+greyscale[r+1][c-1]+greyscale[r-1][c-1]-2*greyscale[r][c+1]
-greyscale[r-1][c+1]-greyscale[r+1][c+1]);

Вы выходите за пределы.

Условие:

  r+1==height||c+1==width

недостаточно.

Тест должен быть с height-1 и width-1

0 голосов
/ 04 декабря 2018

Наиболее вероятная проблема - доступ к массиву за пределами.Существуют такие инструменты, как valgrind, которые могут обнаружить это без изменений кода.Другие возможности включают пошаговое выполнение кода с помощью отладчика или добавление assert s до всех обращений к массиву.

Другая возможность - перейти от использования простого массива к использованию std::vector из std::vector s.или некоторая другая коллекция C ++, которая может легко поддерживать проверку границ.

Другая возможность состоит в том, что height и width просто очень велики, так что массив требует доступа к большему объему памяти, чем ваша платформа может получить настек.Хорошей идеей будет переключение на динамическое распределение или что-то, что может привести к ошибке, если памяти недостаточно, а не происходит сбой.Вы также можете начать с регистрации их, чтобы увидеть, является ли это вероятной проблемой.

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

...