Smorodov 579 Жалоба Опубликовано August 12, 2012 Написал небольшую статейку (3 стр.) о подходе к проблеме проектирования фильтров: EnergyApproach.pdf Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано August 13, 2012 и какие типы фильтров можно сформулировать таким образом? всмысле я имею ввиду можно переформулировать уже заранее известные, например медианный фильтр. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано August 13, 2012 Я думаю там примерно медианный и получится. Постановка задачи тут другая, моделировать таким методом другие существующие фильтры задача не такая уж простая, возможно и не самая нужная. Здесь Вы задаете цели фильтрации,а они могут быть достаточно замысловатыми и фильтр выполняет их согласованно, все сразу. Это, кстати не самый быстрый подход к фильтрации изображений. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано August 31, 2012 Реализация метода (того что в pdf-ке выше) на OpenCV + Eigen У OpenCV и Eigen достаточно теплые отношения Работает, не так уж и медленно, не реалтайм конечно, но у меня меньше секунды на эту картинку ( в релизе с включенным openMP, в дебаге работает заметно дольше). Вот результат при небольшой (alpha=0.5) При большой (alpha=5): При малой отрицательной alpha=-0.11 (повышается резкость (деблюр?) ) (при большой отрицательной alpha решение ищет долго, и оно не похоже на исходное изображение): // #define EIGEN_RUNTIME_NO_MALLOC // Define this symbol to enable runtime tests for allocations #include <Eigen/Dense> #include <Eigen/Sparse> #include <vector> #include <Eigen/IterativeLinearSolvers> #include <iostream> #include "opencv2/core/eigen.hpp" #include "opencv2/opencv.hpp" using namespace Eigen; using namespace cv; using namespace std; int main(int argc, char* argv[]) { namedWindow("image"); namedWindow("result"); Mat img=imread("d:\\ImagesForTest\\lena.jpg",0); // Количество точек в изображении int n_pixels=img.rows*img.cols; imshow("image",img); waitKey(10); // Вытянем изображение в вектор-столбец Mat m=img.reshape(1,n_pixels).clone(); // Преобразуем в double m.convertTo(m,CV_64FC1); // Векторы для Eigen VectorXd I(n_pixels); VectorXd u(n_pixels); // Переведем изображение из openCV в Eigen cv2eigen(m,I); // Разреженная матрица, т.к. она огромная и большинство эл-тов равно нулю SparseMatrix<double> A(n_pixels,n_pixels); // Заполняется разреженная матрица при помощи триплетов typedef Eigen::Triplet<double> T; std::vector<T> tripletList; // Параметр фильтра (величина сглаживания) double alpha=1; // Устанавливаем значения for(int i=0;i<n_pixels;i++) { tripletList.push_back(T(i,i,1+4*alpha)); if((i+1) < n_pixels){tripletList.push_back(T(i,i+1,-alpha));} // +1 if((i-1) >= 0){tripletList.push_back(T(i,i-1,-alpha));} // -1 if((i+img.cols) < n_pixels){tripletList.push_back(T(i,i+img.cols,-alpha));} // +3 if((i-img.cols) >= 0){tripletList.push_back(T(i,i-img.cols,-alpha));} // -3 } // Устанавливаем граничные значения главной диагонали (угол и верхняя строка) tripletList.push_back(T(0,0,1+2*alpha)); for(int i=1;i<img.cols;i++) { tripletList.push_back(T(i,i,1+3*alpha)); } // Устанавливаем граничные значения главной диагонали (угол и нижняя строка) tripletList.push_back(T(n_pixels-1,n_pixels-1,1+2*alpha)); for(int i=1;i<img.cols;i++) { tripletList.push_back(T(i,n_pixels-i-1,1+3*alpha)); } // Инициализируем разреженную матрицу A.setFromTriplets(tripletList.begin(),tripletList.end()); tripletList.clear(); // Инициализация решателя ConjugateGradient<SparseMatrix<double> > cg; cg.compute(A); // Решаем систему лмнейных уравнений u = cg.solve(I); std::cout << "#iterations: " << cg.iterations() << std::endl; std::cout << "estimated error: " << cg.error() << std::endl; // Заберем решение Mat res(n_pixels,1,CV_64FC1); eigen2cv(u,res); res=res.reshape(1,img.rows); res.convertTo(res,CV_8UC1); // покажем результат imshow("result",res); waitKey(0); return 0; } [/code] Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах