Неправильная фильтрация изображений

Мне нужно создать функцию, которая фильтрует изображение в оттенках серого в частотной области. Основная проблема заключается в том, что результат выглядит как шум соли и перца.

основная функция:

void FiltroFrequenze::dftMia(){
int rowsExtendedImage = image.rows + kernel.rows - 1;
int colsExtendedImage = image.cols + kernel.cols - 1;
Mat extendedImage(rowsExtendedImage, colsExtendedImage, image.type());
Mat extendedKernel(rowsExtendedImage, colsExtendedImage, image.type());
filtered=extendedImage.clone();

espansione(image,kernel,extendedImage);

Mat trasformata (rowsExtendedImage, colsExtendedImage, image.type());

translation(extendedImage,trasformata);


Mat planes[] ={Mat_<float>(trasformata),Mat::zeros(trasformata.size(),CV_32F)};
Mat complexI;
merge(planes,2,complexI);
dft(complexI,complexI);
cout<<"dft fatto"<<endl;
split(complexI,planes);

Mat magI=planes[0];


Mat moltiplicata(rowsExtendedImage, colsExtendedImage, image.type());

switch (type)
{
case 1:
    kernelPassaBasso(raggio);
    break;
case 2:
    kernelPassaAlto(raggio);
    break;
}
showImage(kernel,"kernel");
waitKey(0);
multiply(magI,kernel,moltiplicata);
//multiply(complexI,kernel,moltiplicata);

cout<<"moltiplicata"<<endl;

Mat inversa (rowsExtendedImage, colsExtendedImage, image.type());

dft(moltiplicata,inversa,DFT_INVERSE+DFT_SCALE);
split(inversa,planes);
    //magnitude(planes[0],planes[1],planes[0]);
     inversa=planes[0];
//inversa.convertTo(inversa,image.type());
cout<<"invertita"<<endl;
showImage(inversa,"inversa");
        waitKey(0);
translation(inversa,filtered);
//filtered.convertTo(filtered,image.type());

чтобы перевести изображение на частоте, которую я использую, в пространственной области:

void FiltroFrequenze::translation(Mat image, Mat traslatedImage){
for(int x=0;x<image.rows;x++)
{
    for(int y=0;y<image.cols;y++)
    {


        if(image.channels()==1)
                {

                    traslatedImage.at<float>(x,y)=image.at<float>(x,y)*pow(-1,x+y);
                }
                else
                {
                    for(int k=0;k<image.channels();k++)
                    {
                        traslatedImage.at<Vec3b>(x,y)[k]=image.at<Vec3b>(x,y)[k]*pow(-1,x+y);
                    }
                }

    }
}

и создать ядра верхних и нижних частот:

void FiltroFrequenze::kernelPassaBasso(int raggio){
Mat kernelNew(kernel.rows+image.rows-1, kernel.cols+image.cols-1, CV_32FC1);
kernel=kernelNew;
drawCircle(kernel, raggio,  1.0, 0.0);

void FiltroFrequenze::kernelPassaAlto(int raggio){ showImage(image,"immagine");

Mat kernelNew(kernel.rows+image.rows-1, kernel.cols+image.cols-1, CV_32FC1);
kernel=kernelNew.clone();
drawCircle(kernel, raggio,  0.0, 1.0);




void FiltroFrequenze::drawCircle(Mat image, int raggio, float colorCircle, float colorBackground){
int center[]={floor(kernel.rows/2)+1,floor(kernel.cols/2)+1};
for(int y = 0; y < image.rows; y++)
    for(int x = 0; x < image.cols; x++)
    {
        if(pow(x-center[1],2)+pow(y-center[0],2)<pow(raggio,2))
        {
            image.at<float>(y,x)=colorCircle;
        }
        else
        {
            image.at<float>(y,x)=colorBackground;
        }
    }

Спасибо за помощь


person Gabriele Bazzotti    schedule 10.04.2015    source источник


Ответы (1)


Я подозреваю, что то, что вы видите, вызвано тем, что изображение, являющееся результатом фильтрации, становится плавающим. OpenCV правильно отображает изображения с плавающей запятой только тогда, когда значения с плавающей запятой находятся в диапазоне ‹0, 1>, поэтому вам придется вернуть результаты к 8-битным или правильно масштабировать.

person mkr    schedule 11.04.2015