Ejemplo n.º 1
0
        private bool DFT_Remove_Texture_Filter(Mat inputImg, ref Mat resultImg, int ksize, int crossBias)
        {
            if (ksize % 2 == 0)
            {
                return(false);
            }
            if (crossBias > inputImg.Width || crossBias > inputImg.Height)
            {
                return(false);
            }

            int m = CvInvoke.GetOptimalDFTSize(inputImg.Rows);
            int n = CvInvoke.GetOptimalDFTSize(inputImg.Cols);

            Mat padded = new Mat();

            CvInvoke.CopyMakeBorder(inputImg, padded, 0, m - inputImg.Rows, 0, n - inputImg.Cols, BorderType.Constant);
            padded.ConvertTo(padded, DepthType.Cv32F);
            Mat         zeroMat   = Mat.Zeros(padded.Rows, padded.Cols, DepthType.Cv32F, 1);
            VectorOfMat matVector = new VectorOfMat();

            matVector.Push(padded);
            matVector.Push(zeroMat);

            // make a complex mat
            Mat complexI = new Mat(padded.Size, DepthType.Cv32F, 2);

            CvInvoke.Merge(matVector, complexI);

            Mat fourier = new Mat(complexI.Size, DepthType.Cv32F, 2);

            // do dft
            CvInvoke.Dft(complexI, fourier, DxtType.Forward, complexI.Rows);


            /* temp is to show result of dft
             *
             * DEBUG ONLY
             *
             * Mat temp = Magnitude(fourier);
             * temp = new Mat(temp, new Rectangle(0, 0, temp.Cols & -2, temp.Rows & -2));
             * SwitchQuadrants(ref temp);
             * CvInvoke.Normalize(temp, temp, 1.0, 0.0, NormType.MinMax, DepthType.Cv32F);
             * CvInvoke.Imshow("Fourier Transform", temp);
             *
             *
             */

            Mat Real      = new Mat(fourier.Size, DepthType.Cv32F, 1);
            Mat Imaginary = new Mat(fourier.Size, DepthType.Cv32F, 1);

            VectorOfMat channels = new VectorOfMat();

            CvInvoke.Split(fourier, channels);
            Real      = channels.GetOutputArray().GetMat(0);
            Imaginary = channels.GetOutputArray().GetMat(1);


            SwitchQuadrants(ref Real);
            //CvInvoke.Normalize(Real, Real, 1.0, 0.0, NormType.MinMax, DepthType.Cv32F);
            SwitchQuadrants(ref Imaginary);
            //CvInvoke.Normalize(Imaginary, Imaginary, 1.0, 0.0, NormType.MinMax, DepthType.Cv32F);

            // Array data
            // convert to image instead of using Mat's data pointer
            Image <Gray, float> img_R = Real.ToImage <Gray, float>();
            Image <Gray, float> img_I = Real.ToImage <Gray, float>();

            Array tmpR = Real.GetData();
            // make a Real Image copy
            Array realCopy             = Real.GetData();
            Image <Gray, float> copy_R = Real.ToImage <Gray, float>();

            for (int i = 0; i < img_R.Width; i++)
            {
                for (int j = 0; j < img_R.Height; j++)
                {
                    copy_R.Data[j, i, 0] = (float)realCopy.GetValue(j, i);
                }
            }

            try
            {
                CvInvoke.MedianBlur(copy_R, copy_R, ksize);
            }
            catch
            {
                return(false);
            }

            Array tmpI = Imaginary.GetData();

            int Center_w = img_R.Width / 2;
            int Center_h = img_I.Height / 2;

            for (int i = 0; i < img_R.Width; i++)
            {
                for (int j = 0; j < img_R.Height; j++)
                {
                    if ((i >= Center_w - crossBias && i <= Center_w + crossBias))
                    {
                        img_R.Data[j, i, 0] = (float)tmpR.GetValue(j, i);
                        img_I.Data[j, i, 0] = (float)tmpI.GetValue(j, i);
                    }
                    else if ((j >= Center_h - crossBias && j <= Center_h + crossBias))
                    {
                        img_R.Data[j, i, 0] = (float)tmpR.GetValue(j, i);
                        img_I.Data[j, i, 0] = (float)tmpI.GetValue(j, i);
                    }
                    else
                    {
                        img_R.Data[j, i, 0] = copy_R.Data[j, i, 0];
                        img_I.Data[j, i, 0] = 0;
                    }
                }
            }

            // Image back to Mat
            // make some merge
            Mat temp1 = new Mat(img_R.Size, DepthType.Cv32F, 1);
            Mat temp2 = new Mat(img_R.Size, DepthType.Cv32F, 1);

            temp1 = img_R.Mat;
            temp2 = img_I.Mat;
            VectorOfMat matVectorTemp = new VectorOfMat();

            matVectorTemp.Push(temp1);
            matVectorTemp.Push(temp2);
            Mat merge_mat = new Mat(img_R.Size, DepthType.Cv32F, 2);

            CvInvoke.Merge(matVectorTemp, merge_mat);

            // DFT inverse
            CvInvoke.Dft(merge_mat, merge_mat, DxtType.Inverse, merge_mat.Rows);
            Mat magnitudeImage = MagnitudeInverse(merge_mat);

            CvInvoke.Normalize(magnitudeImage, magnitudeImage, 1.0, 0.0, NormType.MinMax, DepthType.Cv32F);
            //CvInvoke.Imshow("Fourier Transform Inverse", magnitudeImage);
            CvInvoke.Normalize(magnitudeImage, magnitudeImage, 0, 255, NormType.MinMax, DepthType.Cv8U);
            //CvInvoke.Imshow("Fourier Normalize", magnitudeImage);

            resultImg = magnitudeImage;

            return(true);
        }