예제 #1
0
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            m_FFT.Dispose();
            m_device.Dispose();
        }
예제 #2
0
        /// <summary>
        /// Very wasteful method that computes the spectrum of a source image
        /// </summary>
        /// <param name="_source"></param>
        /// <returns></returns>
        ImageFile       ComputeSpectrum(ImageFile _source, float _scaleFactor)
        {
            uint size   = _source.Width;
            uint offset = size >> 1;
            uint mask   = size - 1;

            Complex[,]      signal = new Complex[size, size];
            _source.ReadPixels((uint _X, uint _Y, ref float4 _color) => {
                signal[_X, _Y].Set(_color.x, 0);
            });

            SharpMath.FFT.FFT2D_GPU FFT = new SharpMath.FFT.FFT2D_GPU(m_device, size);
            Complex[,]      spectrum = FFT.FFT_Forward(signal);
            FFT.Dispose();

            ImageFile result = new ImageFile(size, size, _source.PixelFormat, _source.ColorProfile);

            result.WritePixels((uint _X, uint _Y, ref float4 _color) => {
                float V = _scaleFactor * (float)spectrum[(_X + offset) & mask, (_Y + offset) & mask].r;
                _color.Set(V, V, V, 1.0f);
            });
            return(result);
        }
예제 #3
0
        private void Convert(bool _centralValue, float _signX, float _signY)
        {
            // Initialize gradient filter
            Complex[,]      dx = new Complex[m_size, m_size];
            Complex[,]      dy = new Complex[m_size, m_size];
            Array.Clear(dx, 0, (int)(m_size * m_size));
            Array.Clear(dy, 0, (int)(m_size * m_size));

            if (_centralValue)
            {
                // Central-difference
                dx[m_size - 1, 0].Set(-_signX, 0);
                dx[1, 0].Set(_signX, 0);
                dy[0, m_size - 1].Set(_signY, 0);
                dy[0, 1].Set(-_signY, 0);
            }
            else
            {
                // One-sided difference
                dx[0, 0].Set(-_signX, 0);
                dx[1, 0].Set(_signX, 0);
                dy[0, 0].Set(_signY, 0);
                dy[0, 1].Set(-_signY, 0);
            }

            // Apply forward Fourier transform to obtain spectrum
            SharpMath.FFT.FFT2D_GPU FFT = new SharpMath.FFT.FFT2D_GPU(m_device, m_size);
            Complex[,]      NX = FFT.FFT_Forward(nx);
            Complex[,]      NY = FFT.FFT_Forward(ny);
            Complex[,]      DX = FFT.FFT_Forward(dx);
            Complex[,]      DY = FFT.FFT_Forward(dy);

            // Compute de-convolution
            float factor = m_imageNormal.Width * m_imageNormal.Height;

            Complex[,]      H = new Complex[m_size, m_size];
            Complex temp = new Complex(), sqrtTemp;

            for (uint Y = 0; Y < m_size; Y++)
            {
                for (uint X = 0; X < m_size; X++)
                {
#if !F**K
                    double sqNX = NX[X, Y].SquareMagnitude;
                    double sqNY = NY[X, Y].SquareMagnitude;
                    double num  = sqNX + sqNY;

                    double sqDX = DX[X, Y].SquareMagnitude;
                    double sqDY = DY[X, Y].SquareMagnitude;
                    double den  = factor * (sqDX + sqDY);

                    temp.Set(Math.Abs(den) > 0.0 ? num / den : 0.0, 0.0);
                    sqrtTemp = temp.Sqrt();

                    H[X, Y] = sqrtTemp;
#else
                    Complex Nx  = NX[X, Y];
                    Complex Ny  = NY[X, Y];
                    Complex Dx  = DX[X, Y];
                    Complex Dy  = DY[X, Y];
                    double  den = factor * (DX[X, Y].SquareMagnitude + DY[X, Y].SquareMagnitude);
                    if (Math.Abs(den) > 0.0)
                    {
                        temp    = -(Dx * Nx + Dy * Ny) / den;
                        H[X, Y] = temp;
                    }
                    else
                    {
                        H[X, Y].Zero();
                    }
#endif
                }
            }

            // Apply inverse transform
            Complex[,]      h = FFT.FFT_Inverse(H);

            Complex heightMin = new Complex(double.MaxValue, double.MaxValue);
            Complex heightMax = new Complex(-double.MaxValue, -double.MaxValue);
            for (uint Y = 0; Y < m_size; Y++)
            {
                for (uint X = 0; X < m_size; X++)
                {
                    Complex height = h[X, Y];
                    heightMin.Min(height);
                    heightMax.Max(height);
                }
            }

            // Render result
            if (m_imageHeight != null)
            {
                m_imageHeight.Dispose();
                m_imageHeight = null;
            }

            factor = 1.0f / (float)(heightMax.r - heightMin.r);
// heightMin.r = -1.0f;
// factor = 0.5f;

            m_imageHeight = new ImageFile(m_imageNormal.Width, m_imageNormal.Height, PIXEL_FORMAT.R16, new ColorProfile(ColorProfile.STANDARD_PROFILE.sRGB));
//			m_imageHeight.WritePixels( ( uint X, uint Y, ref float4 _color ) => { _color.x = 1e3f * (float) H[X,Y].Magnitude; } );
//			m_imageHeight.WritePixels( ( uint X, uint Y, ref float4 _color ) => { _color.x = 1e5f * (float) DX[X,Y].Magnitude; } );
            m_imageHeight.WritePixels((uint X, uint Y, ref float4 _color) => { _color.x = factor * (float)(h[X, Y].r - heightMin.r); });

            imagePanelHeight.Bitmap = m_imageHeight.AsBitmap;

            FFT.Dispose();
        }