Ошибка сегментации (дамп ядра) при создании нескольких матриц

Для моего класса по компьютерному зрению мы сейчас работаем над алгоритмом обнаружения краев 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]);
        }
    }
}

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

3 ответа

Я полагаю, вы определили 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

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

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

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

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

Разместите свой массив в векторе, предпочтительно в 1D.

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

double atans[height][width];

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

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

Другие вопросы по тегам