Перейти к содержимому
Compvision.ru
Smorodov

Энергетический подход к фильтрации изображений.

Recommended Posts

Написал небольшую статейку (3 стр.) о подходе к проблеме проектирования фильтров:

EnergyApproach.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

и какие типы фильтров можно сформулировать таким образом?

всмысле я имею ввиду можно переформулировать уже заранее известные, например медианный фильтр.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я думаю там примерно медианный и получится.

Постановка задачи тут другая, моделировать таким методом другие существующие фильтры задача не такая уж простая, возможно и не самая нужная.

Здесь Вы задаете цели фильтрации,а они могут быть достаточно замысловатыми и фильтр выполняет их согласованно, все сразу.

Это, кстати не самый быстрый подход к фильтрации изображений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Реализация метода (того что в pdf-ке выше) на OpenCV + Eigen

У OpenCV и Eigen достаточно теплые отношения :)

Работает, не так уж и медленно, не реалтайм конечно, но у меня меньше секунды на эту картинку ( в релизе с включенным openMP, в дебаге работает заметно дольше).

Вот результат при небольшой (alpha=0.5)

post-1-0-69812800-1346405702_thumb.jpg

При большой (alpha=5):

post-1-0-25393900-1346408297_thumb.jpg

При малой отрицательной alpha=-0.11 (повышается резкость (деблюр?) ) (при большой отрицательной alpha решение ищет долго, и оно не похоже на исходное изображение):

post-1-0-04925800-1346408313_thumb.jpg


//
#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]

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×