image - 如何在open-cv或emgu-cv中使用傅立叶变换对图像进行模糊处理?

标签 image opencv image-processing emgucv

我看了这段视频,关于在Matlab中使用傅立叶变换对图像进行模糊处理
video

我想在emgu cv中转换代码

我在emgucv中的代码:

  string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        Image<Bgr, byte> img = new Image<Bgr, byte>(@"lal.png");


        //blur the image
        Image<Gray, byte> gray = img.Convert<Gray, byte>().SmoothBlur(31,31);

        //convert image to float and get the fourier transform
        Mat g_fl = gray.Convert<Gray, float>().Mat;
        Matrix<float> dft_image = new Matrix<float>(g_fl.Size);
        CvInvoke.Dft(g_fl, dft_image, Emgu.CV.CvEnum.DxtType.Forward, 0);

        //here i make an image of kernel with size of the original 


        Image<Gray, float> ker = new Image<Gray, float>(img.Size);
        ker.SetZero();

        for (int x = 0; x < 31; x++)
        {
            for (int y = 0; y < 31; y++)
            {

                //31 * 31= 961
                    ker[y, x] = new Gray(1/961);


            }
        }

        //get the fourier of the kernel
        Matrix<float> dft_blur = new Matrix<float>(g_fl.Size);
        CvInvoke.Dft(ker, dft_blur, Emgu.CV.CvEnum.DxtType.Forward, 0);


        // fouier image / fourier blur
        Matrix<float> res = new Matrix<float>(g_fl.Size);
        for (int x=0;x<g_fl.Cols;x++)
        {
            for (int y = 0; y < g_fl.Rows; y++)
            {

                    res[y, x] = dft_image[y, x] / dft_blur[y, x];
            }
        }

        //get the inverse of fourier
        Image<Gray, float> ready = new Image<Gray, float>(g_fl.Size);

        CvInvoke.Dft(res, ready, Emgu.CV.CvEnum.DxtType.Inverse, 0);

        CvInvoke.Imshow("deblur", ready.Convert<Gray,byte>());


        CvInvoke.Imshow("original", gray);



        CvInvoke.WaitKey(0);

但是结果是黑色并且无法正常工作,我的代码中的错误在哪里?
如果您在opencv python中有代码,可以将其发布:)?

谢谢 :)

最佳答案

我以前的维纳过滤器实现:

#include "stdafx.h"
#pragma once
#pragma comment(lib, "opencv_legacy220.lib")
#pragma comment(lib, "opencv_core220.lib")
#pragma comment(lib, "opencv_highgui220.lib")
#pragma comment(lib, "opencv_imgproc220.lib")
#include "c:\Users\Andrey\Documents\opencv\include\opencv\cv.h"
#include "c:\Users\Andrey\Documents\opencv\include\opencv\cxcore.h"
#include "c:\Users\Andrey\Documents\opencv\include\opencv\highgui.h"
#include <string>
#include <iostream>
#include <complex>

using namespace std;
using namespace cv;

//----------------------------------------------------------
// Compute real and implicit parts of FFT for given image
//----------------------------------------------------------
void ForwardFFT(Mat &Src, Mat *FImg)
{
    int M = getOptimalDFTSize( Src.rows );
    int N = getOptimalDFTSize( Src.cols );
    Mat padded;    
    copyMakeBorder(Src, padded, 0, M - Src.rows, 0, N - Src.cols, BORDER_CONSTANT, Scalar::all(0));
    // Create complex representation of our image
    // planes[0] Real part, planes[1] Implicit part (zeros)
    Mat planes[] = {Mat_<double>(padded), Mat::zeros(padded.size(), CV_64F)};
    Mat complexImg;
    merge(planes, 2, complexImg); 
    dft(complexImg, complexImg);    
    // As result, we also have Re and Im planes
    split(complexImg, planes);
    // Crop specter, if it have odd number of rows or cols
    planes[0] = planes[0](Rect(0, 0, planes[0].cols & -2, planes[0].rows & -2));
    planes[1] = planes[1](Rect(0, 0, planes[1].cols & -2, planes[1].rows & -2));
    FImg[0]=planes[0].clone();
    FImg[1]=planes[1].clone();
}
//----------------------------------------------------------
// Restore our image using specter
//----------------------------------------------------------
void InverseFFT(Mat *FImg,Mat &Dst)
{
    Mat complexImg;
    merge(FImg, 2, complexImg);
    // Apply inverse FFT
    idft(complexImg, complexImg);
    split(complexImg, FImg);
    Dst=FImg[0];
}
//----------------------------------------------------------
// Wiener filter 
//----------------------------------------------------------
void wienerFilter(Mat &src,Mat &dst,Mat &_h,double k)
{
//---------------------------------------------------
// small number for numeric stability
//---------------------------------------------------
    const double eps=1E-8;
//---------------------------------------------------
    int ImgW=src.size().width;
    int ImgH=src.size().height;
//--------------------------------------------------
    Mat Yf[2];
    ForwardFFT(src,Yf); 
//--------------------------------------------------
    Mat h;
    h.create(ImgH,ImgW,CV_64F);
    h=0;    
    _h.copyTo(h(Rect(0, 0, _h.size().width, _h.size().height)));
    Mat Hf[2];
    ForwardFFT(h,Hf);
//--------------------------------------------------
    Mat Fu[2];
    Fu[0].create(ImgH,ImgW,CV_64F);
    Fu[1].create(ImgH,ImgW,CV_64F);

    complex<double> a;
    complex<double> b;
    complex<double> c;

    double Hf_Re;
    double Hf_Im;
    double Phf;
    double hfz;
    double hz;
    double A;

    for (int i=0;i<Hf[0].size().height;i++)
    {
        for (int j=0;j<Hf[0].size().width;j++)
        {
            Hf_Re=Hf[0].at<double>(i,j);
            Hf_Im=Hf[1].at<double>(i,j);
            Phf = Hf_Re*Hf_Re+Hf_Im*Hf_Im;
            hfz=(Phf<eps)*eps;
            hz =(h.at<double>(i,j)>0);
            A=Phf/(Phf+hz+k);
            a=complex<double>(Yf[0].at<double>(i,j),Yf[1].at<double>(i,j));
            b=complex<double>(Hf_Re+hfz,Hf_Im+hfz);
            c=a/b; // Deconvolution
                   // Other we do to remove division by 0
            Fu[0].at<double>(i,j)=(c.real()*A);
            Fu[1].at<double>(i,j)=(c.imag()*A); 
        }
    }
//--------------------------------------------------    
    Fu[0]/=(ImgW*ImgH);
    Fu[1]/=(ImgW*ImgH);
//--------------------------------------------------
    InverseFFT(Fu,dst);
    // remove out of rane values
    for (int i=0;i<Hf[0].size().height;i++)
    {
        for (int j=0;j<Hf[0].size().width;j++)
        {
            if(dst.at<double>(i,j)>215){dst.at<double>(i,j)=215;}
            if(dst.at<double>(i,j)<(-40)){dst.at<double>(i,j)=(-40);}
        }
    }
}
//----------------------------------------------------------
// Main
//----------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
// Input image
    Mat img;
// Load it from drive
    img=imread("data/motion_fuzzy_lena.bmp",0);
//---------------------------------------------
    imshow("Src image", img);
// Image size
    int ImgW=img.size().width;
    int ImgH=img.size().height;
// Deconvolution kernel (coefficient sum must be 1)
// Image was blurred using same kernel
    Mat h;
    h.create(1,10,CV_64F);
    h=1/double(h.size().width*h.size().height);
// Apply filter
    wienerFilter(img,img,h,0.05);
    normalize(img,img, 0, 1, CV_MINMAX);
    imshow("Result image", img);
    cvWaitKey(0);
    return 0;
}

结果:

enter image description here

关于image - 如何在open-cv或emgu-cv中使用傅立叶变换对图像进行模糊处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61767716/

相关文章:

python - 从OpenCV中的图像定位和提取(未知)书籍

python - 如果给定原始图像,如何将经过 Photoshop 处理的部分与图像的其余部分分开?

opencv从任意区域提取路径(中心线)

javascript - 在 JavaScript 上创建 SimpleImage

html - 图片在您的网站上的下载顺序是什么?

c# - 使用EMGU的两个图像之间的相关性

image - 计算机如何将图像转换为二进制?

html - Safari CSS 问题/背景图片

android - 从画廊中删除专辑封面

Android图像处理算法性能