Ошибка сегментации (дамп ядра) при создании нескольких матриц
Для моего класса по компьютерному зрению мы сейчас работаем над алгоритмом обнаружения краев 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::vector
s или некоторая другая коллекция C++, которая может легко поддерживать проверку границ.
Другая возможность состоит в том, что height
а также width
просто очень большие, так что массив требует доступа к большему объему памяти, чем ваша платформа может получить в стеке. Хорошей идеей будет переключение на динамическое распределение или что-то, что может привести к ошибке, если памяти недостаточно, а не происходит сбой. Вы также можете начать с регистрации их, чтобы увидеть, если это вероятная проблема.
Я бы посоветовал не размещать такие массивы в стеке, потому что разные платформы имеют разные ограничения по размеру стека. Так что это делает ваш код хрупким, даже если он работает.
Разместите свой массив в векторе, предпочтительно в 1D.
Проблема в том, что эта строка:
double atans[height][width];
если вы используете переменную height
а также width
, то это не допустимый C++, так как это C99.
Если они постоянны, то это допустимый C++, но вы размещаете свой массив в стеке и, возможно, взорвали его.