【问题标题】:OpenCV deconvolution with DFT使用 DFT 的 OpenCV 反卷积
【发布时间】:2014-09-19 20:09:03
【问题描述】:

我正在使用 OpenCVSharp(OpenCV 的 C# 包装)实现反卷积算法(用于 DIC 图像)。由于某些原因,在我对 deltaPhiXY(见下文)使用 Cv2.Dft 算法后,傅里叶变换的实部和虚部始终为零; deltaPhiXY 始终在 -pi/2 到 pi/2 的范围内,如预期(和必需)。你有什么提示我为什么不能在 deltaPhiXY 上计算 DFT 吗?如果有人对数学理论感兴趣,这是论文http://dare.uva.nl/document/2/3308

非常感谢您的帮助。

// deconvolve the frame
            int deltaX = Session.Params.ParamsPreprocessing.DeltaX;
            int deltaY = Session.Params.ParamsPreprocessing.DeltaY;
            float s = Session.Params.ParamsPreprocessing.S;
            float sigma = Session.Params.ParamsPreprocessing.Sigma;
            if (deltaX != 0 && deltaY != 0 && s != 0 && sigma != 0)
            {
                // initialize deconvolution variables
                MatOfDouble
                    deltaPhiXY = new MatOfDouble(frame.Size()),
                    realW = new MatOfDouble(frame.Size(), 0),
                    imgW = new MatOfDouble(frame.Size());

                frame.ConvertTo(frame, MatType.CV_64FC1);
                MatIndexer<double>
                    indexerFrame = (new MatOfDouble(frame)).GetIndexer(),
                    indexerDeltaPhiXY = deltaPhiXY.GetIndexer(),
                    indexerImgW = imgW.GetIndexer();

                double
                    IMax,
                    IMin;
                frame.MinMaxIdx(out IMin, out IMax);

                double
                    phi = 0,
                    G = 0,
                    SN = 0,
                    w = 0;

                // build deltaPhi (in x, y) and W (in u, v)
                for(int row = 0; row < frame.Rows; row++)
                {
                    for(int col = 0; col < frame.Cols; col++)
                    {
                        // set deltaPhi
                        phi =
                       Math.Acos
                        (
                            (2 * (indexerFrame[row, col] - IMin)
                            /
                            (IMax - IMin))
                            - 1
                        )
                        - Math.PI / 2;

                        indexerDeltaPhiXY[row, col] =
                            phi;


                        // set complex G in u, v
                        G = 
                            2*Math.Sin(Math.PI * (row * deltaX + col * deltaY));

                        // set SN in u, v (spectral distribution of the signal to noise ratio)
                        SN = 
                            s * Math.Exp(-2 * Math.PI * Math.PI * sigma * sigma * (row * row + col * col));

                        // set W in u, v
                        w = 
                            -G / (G * G + (1 / SN));

                        indexerImgW[row, col] =
                            w;

                    }
                }

                // build deltaPhi
                Mat deltaPhi = new Mat();
                Cv2.Dft(deltaPhiXY, deltaPhi, DftFlag2.Scale | DftFlag2.ComplexOutput); // here I had used other flags but the final result is always 0
                // Cv2.Merge(new Mat[] { deltaPhiXY, new Mat(deltaPhiXY.Size(), MatType.CV_64FC1, Scalar.All(0)) }, deltaPhi);
                // deltaPhi = deltaPhi.Dft();
                Mat[] planesDeltaPhi = deltaPhi.Split();
                Mat realDeltaPhi = planesDeltaPhi[0];
                Mat imgDeltaPhi = planesDeltaPhi[1];

                // get phi = W*deltaPhi (deconvolution)
                Mat
                    realPhi = -imgW.Mul(imgDeltaPhi),
                    imgPhi = imgW.Mul(realDeltaPhi);

                // get deconvolved frame (inverse Fourier's transform)
                Cv2.Merge(new Mat[] { realPhi, imgPhi }, frame);
                frame = frame.Dft(DftFlag2.Inverse | DftFlag2.RealOutput);
                frame = frame.Normalize(IMin, IMax, NormType.MinMax, MatType.CV_32FC1);

}

【问题讨论】:

    标签: c# c++ opencv fft dft


    【解决方案1】:

    已修复, 出于某种原因,有必要在对 Mat 变量(至少对于上述代码)执行 DFT(和 IDFT)之前使用这个 sn-p:

              double
                    min,
                    max;
    
                    toTransform.MinMaxIdx(out min, out max);
                    toTransform = toTransform.Normalize(0, int.MaxValue, NormType.MinMax, MatType.CV_32SC1);
                    toTransform = toTransform.Normalize(min, max, NormType.MinMax, MatType.CV_64FC1);
    

    我不知道问题是否与我的 Mat 变量或 OpenCV 库中的值有关,但这种解决方法(至少)在我的情况下是有效的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 2017-10-20
      • 2013-06-08
      • 2021-10-20
      • 1970-01-01
      相关资源
      最近更新 更多