Exemple #1
0
        // Function calculates PSD(Power spectrum density) by fft with two flags
        // flag = 0 means to return PSD
        // flag = 1 means to return log(PSD)
        public static void calcPSD(ref Mat inputImg, ref Mat outputImg, bool flag = false)
        {
            Mat[] planes   = { new Mat <float>(inputImg.Clone()), Mat.Zeros(inputImg.Size(), MatType.CV_32F) };
            Mat   complexI = new Mat();

            Cv2.Merge(planes, complexI);
            Cv2.Dft(complexI, complexI);
            Cv2.Split(complexI, out planes);            // planes[0] = Re(DFT(I)), planes[1] = Im(DFT(I))
            planes[0].Set <float>(0, 0);
            planes[1].Set <float>(0, 0);
            // compute the PSD = sqrt(Re(DFT(I))^2 + Im(DFT(I))^2)^2
            Mat imgPSD = new Mat();

            Cv2.Magnitude(planes[0], planes[1], imgPSD);        //imgPSD = sqrt(Power spectrum density)
            Cv2.Pow(imgPSD, 2, imgPSD);                         //it needs ^2 in order to get PSD
            outputImg = imgPSD;
            // logPSD = log(1 + PSD)
            if (flag)
            {
                Mat imglogPSD = new Mat();
                imglogPSD = imgPSD + Scalar.All(1);
                Cv2.Log(imglogPSD, imglogPSD);
                outputImg = imglogPSD;
            }
        }
Exemple #2
0
        public static void filter2DFreq(ref Mat inputImg, ref Mat outputImg, ref Mat H)
        {
            Mat[] planes   = { new Mat <float>(inputImg.Clone()), Mat.Zeros(inputImg.Size(), MatType.CV_32F) };
            Mat   complexI = new Mat();

            Cv2.Merge(planes, complexI);
            Cv2.Dft(complexI, complexI, DftFlags.Scale);
            Mat[] planesH  = { new Mat <float>(H.Clone()), Mat.Zeros(H.Size(), MatType.CV_32F) };
            Mat   complexH = new Mat();

            Cv2.Merge(planesH, complexH);
            Mat complexIH = new Mat();

            Cv2.MulSpectrums(complexI, complexH, complexIH, 0);
            Cv2.Idft(complexIH, complexIH);
            Cv2.Split(complexIH, out planes);
            outputImg = planes[0];
        }
Exemple #3
0
        public void Run()
        {
            Mat img = Cv2.ImRead(FilePath.Image.Lenna, ImreadModes.GrayScale);

            // expand input image to optimal size
            Mat padded = new Mat();
            int m      = Cv2.GetOptimalDFTSize(img.Rows);
            int n      = Cv2.GetOptimalDFTSize(img.Cols); // on the border add zero values

            Cv2.CopyMakeBorder(img, padded, 0, m - img.Rows, 0, n - img.Cols, BorderTypes.Constant, Scalar.All(0));

            // Add to the expanded another plane with zeros
            Mat paddedF32 = new Mat();

            padded.ConvertTo(paddedF32, MatType.CV_32F);
            Mat[] planes  = { paddedF32, Mat.Zeros(padded.Size(), MatType.CV_32F) };
            Mat   complex = new Mat();

            Cv2.Merge(planes, complex);

            // this way the result may fit in the source matrix
            Mat dft = new Mat();

            Cv2.Dft(complex, dft);

            // compute the magnitude and switch to logarithmic scale
            // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
            Mat[] dftPlanes;
            Cv2.Split(dft, out dftPlanes);  // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))

            // planes[0] = magnitude
            Mat magnitude = new Mat();

            Cv2.Magnitude(dftPlanes[0], dftPlanes[1], magnitude);

            magnitude += Scalar.All(1);  // switch to logarithmic scale
            Cv2.Log(magnitude, magnitude);

            // crop the spectrum, if it has an odd number of rows or columns
            Mat spectrum = magnitude[
                new Rect(0, 0, magnitude.Cols & -2, magnitude.Rows & -2)];

            // rearrange the quadrants of Fourier image  so that the origin is at the image center
            int cx = spectrum.Cols / 2;
            int cy = spectrum.Rows / 2;

            Mat q0 = new Mat(spectrum, new Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
            Mat q1 = new Mat(spectrum, new Rect(cx, 0, cx, cy));  // Top-Right
            Mat q2 = new Mat(spectrum, new Rect(0, cy, cx, cy));  // Bottom-Left
            Mat q3 = new Mat(spectrum, new Rect(cx, cy, cx, cy)); // Bottom-Right

            // swap quadrants (Top-Left with Bottom-Right)
            Mat tmp = new Mat();

            q0.CopyTo(tmp);
            q3.CopyTo(q0);
            tmp.CopyTo(q3);

            // swap quadrant (Top-Right with Bottom-Left)
            q1.CopyTo(tmp);
            q2.CopyTo(q1);
            tmp.CopyTo(q2);

            // Transform the matrix with float values into a
            Cv2.Normalize(spectrum, spectrum, 0, 1, NormTypes.MinMax);

            // Show the result
            Cv2.ImShow("Input Image", img);
            Cv2.ImShow("Spectrum Magnitude", spectrum);

            // calculating the idft
            Mat inverseTransform = new Mat();

            Cv2.Dft(dft, inverseTransform, DftFlags.Inverse | DftFlags.RealOutput);
            Cv2.Normalize(inverseTransform, inverseTransform, 0, 1, NormTypes.MinMax);
            Cv2.ImShow("Reconstructed by Inverse DFT", inverseTransform);
            Cv2.WaitKey();
        }
Exemple #4
0
        /// <summary>
        /// 离散傅里叶变换
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static Bitmap Dft(this Bitmap source)
        {
            var fileName = Path.GetTempPath() + "\\" + Guid.NewGuid().ToString() + ".bmp";

            File.WriteAllBytes(fileName, source.GetBitmapFileData());

            using (var img = Cv2.ImRead(fileName, ImreadModes.Grayscale))
            {
                fileName = Path.GetTempPath() + "\\" + Guid.NewGuid().ToString() + ".bmp";

                var padded = new Mat();

                // 计算最佳 DFT 尺寸
                var m = Cv2.GetOptimalDFTSize(img.Rows);
                var n = Cv2.GetOptimalDFTSize(img.Cols);
                Cv2.CopyMakeBorder(img, padded, 0, m - img.Rows, 0, n - img.Cols, BorderTypes.Constant, Scalar.All(0));

                var paddedF32 = new Mat();
                padded.ConvertTo(paddedF32, MatType.CV_32F);
                Mat[] planes  = { paddedF32, Mat.Zeros(padded.Size(), MatType.CV_32F) };
                var   complex = new Mat();
                Cv2.Merge(planes, complex);

                // 执行 dft
                var dft = new Mat();
                Cv2.Dft(complex, dft);

                // log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
                Cv2.Split(dft, out var dftPlanes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))

                // planes[0] = magnitude
                var magnitude = new Mat();
                Cv2.Magnitude(dftPlanes[0], dftPlanes[1], magnitude);

                magnitude += Scalar.All(1);
                Cv2.Log(magnitude, magnitude);

                var spectrum = magnitude[
                    new Rect(0, 0, magnitude.Cols & -2, magnitude.Rows & -2)];

                // 交换象限
                var cx = spectrum.Cols / 2;
                var cy = spectrum.Rows / 2;

                var q0 = new Mat(spectrum, new Rect(0, 0, cx, cy));   // 左上
                var q1 = new Mat(spectrum, new Rect(cx, 0, cx, cy));  // 右上
                var q2 = new Mat(spectrum, new Rect(0, cy, cx, cy));  // 左下
                var q3 = new Mat(spectrum, new Rect(cx, cy, cx, cy)); // 右下

                var tmp = new Mat();
                q0.CopyTo(tmp);
                q3.CopyTo(q0);
                tmp.CopyTo(q3);
                q1.CopyTo(tmp);
                q2.CopyTo(q1);
                tmp.CopyTo(q2);

                // 归一化到 0~255
                Cv2.Normalize(spectrum, spectrum, 0, 255, NormTypes.MinMax);
                var result = new Mat();
                spectrum.ConvertTo(result, MatType.CV_8U);

                result.SaveImage(fileName);

                return(new Bitmap(fileName));
            }
        }
Exemple #5
0
        public Mat fourier(Mat img)
        {
            Mat padded = new Mat();
            int m      = Cv2.GetOptimalDFTSize(img.Rows);
            int n      = Cv2.GetOptimalDFTSize(img.Cols); // on the border add zero values

            Cv2.CopyMakeBorder(img, padded, 0, m - img.Rows, 0, n - img.Cols, BorderTypes.Constant, Scalar.All(0));

            // Add to the expanded another plane with zeros
            Mat paddedF32 = new Mat();

            padded.ConvertTo(paddedF32, MatType.CV_32F);
            Mat[] planes  = { paddedF32, Mat.Zeros(padded.Size(), MatType.CV_32F) };
            Mat   complex = new Mat();

            Cv2.Merge(planes, complex);

            // this way the result may fit in the source matrix
            Mat dft = new Mat();

            Cv2.Dft(complex, dft);

            // compute the magnitude and switch to logarithmic scale
            // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
            Mat[] dftPlanes;
            Cv2.Split(dft, out dftPlanes);  // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))

            // planes[0] = magnitude
            Mat magnitude = new Mat();

            Cv2.Magnitude(dftPlanes[0], dftPlanes[1], magnitude);

            magnitude += Scalar.All(1);  // switch to logarithmic scale
            Cv2.Log(magnitude, magnitude);

            // crop the spectrum, if it has an odd number of rows or columns
            Mat spectrum = magnitude[
                new OpenCvSharp.Rect(0, 0, magnitude.Cols & -2, magnitude.Rows & -2)];

            // rearrange the quadrants of Fourier image  so that the origin is at the image center
            int cx = spectrum.Cols / 2;
            int cy = spectrum.Rows / 2;

            Mat q0 = new Mat(spectrum, new OpenCvSharp.Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
            Mat q1 = new Mat(spectrum, new OpenCvSharp.Rect(cx, 0, cx, cy));  // Top-Right
            Mat q2 = new Mat(spectrum, new OpenCvSharp.Rect(0, cy, cx, cy));  // Bottom-Left
            Mat q3 = new Mat(spectrum, new OpenCvSharp.Rect(cx, cy, cx, cy)); // Bottom-Right

            // swap quadrants (Top-Left with Bottom-Right)
            Mat tmp = new Mat();

            q0.CopyTo(tmp);
            q3.CopyTo(q0);
            tmp.CopyTo(q3);

            // swap quadrant (Top-Right with Bottom-Left)
            q1.CopyTo(tmp);
            q2.CopyTo(q1);
            tmp.CopyTo(q2);

            // Transform the matrix with float values into a
            Cv2.Normalize(spectrum, spectrum, 0, 1, NormTypes.MinMax);

            // calculating the idft
            Mat inverseTransform = new Mat();

            Cv2.Dft(dft, inverseTransform, DftFlags.Inverse | DftFlags.RealOutput);
            Cv2.Normalize(inverseTransform, inverseTransform, 0, 1, NormTypes.MinMax);

            double minVal = 0.0, maxVal = 0.0;

            Cv2.MinMaxIdx(inverseTransform, out minVal, out maxVal);
            Cv2.ConvertScaleAbs(inverseTransform, inverseTransform, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));

            return(inverseTransform);
        }