Здравствуйте.
Я хотел бы реализовать двухмерные свертки для работы с изображениями. Ну, например, границы выделять, не суть.
Для понимания - я не имею опыта в таких задачах ВООБЩЕ. Собственно, "решение в лоб" я сделал. После этого я погуглил и обнаружил ускоренный вариант через дискретное преобразование Фурье. Вот оно вкратце:
1) сделать прямое ДПФ на изображении
2) сделать прямое ДПФ на ядре (фильтре)
3) поэлементно перемножить получившиеся комплексные числа
4) на перемноженном - сделать обратное ДПФ
и утверждается, что результат должен быть тот же самый, что и в "наивном" случае. Однако, у меня это не так.
Привожу псведокод C# + AForge.NET:
Код:
//двумерное прямое ДПФ
FourierTransform.DFT2(
imgcomplex2d, //изображение в виде массива комплексных чисел с мнимой частью = 0
FourierTransform.Direction.Forward
);
//двумерное прямое ДПФ
FourierTransform.DFT2(
kcomplex2d, //ядро в виде массива комплексных чисел с мнимой частью = 0
FourierTransform.Direction.Forward
);
//перемножаем поэлементно
for (var x = 0; x < imgcomplex2d.GetLength(0); x++)
{
for (var y = 0; y < imgcomplex2d.GetLength(1); y++)
{
imgcomplex2d[x, y] = imgcomplex2d[x, y]*kcomplex2d[x, y];
}
}
//обратное преобразование
FourierTransform.DFT2(
imgcomplex2d,
FourierTransform.Direction.Backward
);
Прошу подсказать. Ситуация в том, что я решаю гораздо более общую задачу, соотв. 2д свертка это очень маленькая часть моей задачи. Поэтому хотелось бы получить подсказку по возможности конкретнее, без архиглубокого погружения в теоремы и суровый матан.
Прошу войти в положение.
доп. вопрос: также мне известно, что этот алгоритм требует модификации, если ядро и изображение разных размеров. у меня (пока) для тестов - размер одинаковый. как необходимо изменить алгоритм в случае, если размеры станут разные?