static public Bitmap Spectrum2Img(BGRComplexImg Source, Spectrum Type) { BGR[,] Result = new BGR[Source.Height, Source.Width]; double Scale = Math.Sqrt(Source.Height * Source.Width); int X, Y, T; for (Y = 0; Y < Source.Height; ++Y) { for (X = 0; X < Source.Width; ++X) { Result[Y, X] = new BGR(); for (T = 0; T < 3; ++T) { if (Type == Spectrum.Magnitude) { Result[Y, X][T] = Source[T][Y, X].Magnitude; } else if (Type == Spectrum.Phase) { Result[Y, X][T] = Source[T][Y, X].Phase; } Result[Y, X][T] = DoubleToByte(Math.Log(Result[Y, X][T] + 1) * Scale); } } } return(BGR2Img(Result)); }
static public BGRComplexImg Img2BGRComplexImg(Bitmap Source, bool Compress = false) { int Width = Source.Width, Height = Source.Height; BitmapData SourceData = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); BGRComplexImg Result = new BGRComplexImg(Width, Height); byte * SourcePointer = (byte *)SourceData.Scan0.ToPointer(); int X, Y, T; for (Y = 0; Y < Height; ++Y) { for (X = 0; X < Width; ++X) { for (T = 0; T < 3; ++T) { Result[T][Y, X] = new AMComplex(SourcePointer[0], 0); if (Compress) { Result[T][Y, X] /= 255; } ++SourcePointer; } ++SourcePointer; } } Source.UnlockBits(SourceData); return(Result); }
static public Bitmap HomomorphicFilter(Bitmap Source, double GammaHigh = 2, double GammaLow = 0.25, double C = 1, double D0 = 80) { int OWidth = Source.Width, OHeight = Source.Height; Source = ImgExtend(Source); int Width = Source.Width, Height = Source.Height; int X, Y, T; double D = GammaHigh - GammaLow, P, W, G; BGRComplexImg ComplexSource = Img2BGRComplexImg(Source); //ComplexSource.ToDouble(); ComplexSource.BFFTShift(); ComplexSource.Ln(); ComplexSource.FFT2(); for (Y = 0; Y < Height; ++Y) { for (X = 0; X < Width; ++X) { P = -C * ((Math.Pow(Y - (Height / 2), 2) + Math.Pow(X - (Width / 2), 2)) / (Math.Pow(D0, 2))); W = (1 - Math.Exp(P)); G = (D * W) + GammaLow; for (T = 0; T < 3; ++T) { ComplexSource[T][Y, X] *= G; } } } ComplexSource.IFFT2(); ComplexSource.Exp(); ComplexSource.BFFTShift(); //ComplexSource.Range(); Bitmap Result = BGRComplexImg2Img(ComplexSource); return(ImgUnExtend(Result, OWidth, OHeight)); }
static public Bitmap SimpleMotionBlur(Bitmap Source, float Length) { int OWidth = Source.Width, OHeight = Source.Height; Source = ImgExtend(Source, true); int Width = Source.Width, Height = Source.Height; var ComplexKernel = SimpleComplexKernel(Width, Height, Length, true); int X, Y, T; BGRComplexImg ComplexSource = Img2BGRComplexImg(Source, true); BGRComplexImg ComplexResult = new BGRComplexImg(Width, Height); ComplexSource.FFT2(); AMFT.FFT2(ComplexKernel, AMFT.Direction.Forward); for (Y = 0; Y < Height; ++Y) { for (X = 0; X < Width; ++X) { for (T = 0; T < 3; ++T) { ComplexResult[T][Y, X] = ComplexSource[T][Y, X] * ComplexKernel[Y, X]; } } } ComplexResult.BFFTShift(); ComplexResult.IFFT2(); Bitmap Result = BGRComplexImg2Img(ComplexResult); return(ImgUnExtend(Result, OWidth, OHeight)); }
static public Bitmap Deconvolution(Bitmap SourceA, Bitmap SourceB, double Lambda = 10, bool Zero = false) { int OWidth = SourceA.Width, OHeight = SourceA.Height; if (OWidth != SourceB.Width || OHeight != SourceB.Height) { throw new Exception("圖片大小不一"); } SourceA = ImgExtend(SourceA, Zero); SourceB = ImgExtend(SourceB, Zero); int Width = SourceA.Width, Height = SourceA.Height; int X, Y, T; BGRComplexImg ComplexSourceA = Img2BGRComplexImg(SourceA); BGRComplexImg ComplexSourceB = Img2BGRComplexImg(SourceB); BGRComplexImg ComplexResult = new BGRComplexImg(Width, Height); ComplexSourceA.FFT2(); ComplexSourceB.FFT2(); for (Y = 0; Y < Height; ++Y) { for (X = 0; X < Width; ++X) { for (T = 0; T < 3; ++T) { ComplexResult[T][Y, X] = AMComplex.MaxDivide(ComplexSourceA[T][Y, X], ComplexSourceB[T][Y, X]) * (ComplexSourceA[T][Y, X].Magnitude / (ComplexSourceA[T][Y, X].Magnitude + Lambda)); } } } ComplexResult.BFFTShift(); ComplexResult.IFFT2(); Bitmap Result = BGRComplexImg2Img(ComplexResult); return(ImgUnExtend(Result, OWidth, OHeight)); }
static public Bitmap PhaseDisplay(Bitmap Source) { Source = ImgExtend(Source); BGRComplexImg ComplexSource = Img2BGRComplexImg(Source); ComplexSource.BFFTShift(); ComplexSource.FFT2(); return(Spectrum2Img(ComplexSource, Spectrum.Phase)); }
static public Bitmap SimpleMotionDeblur(Bitmap Source, float Length, double Lambda = 10) { int OWidth = Source.Width, OHeight = Source.Height; Source = ImgExtend(GrayScale(Source), true); int Width = Source.Width, Height = Source.Height; var ComplexKernel = AM2EDSP(SimpleComplexKernel(Width, Height, Length, true)); var ComplexSource = Img2BGRComplexImg(Source, false); var ComplexResult = new BGRComplexImg(Width, Height); ComplexSource.FFT2(); //AMFT.FFT2( ComplexKernel, AMFT.Direction.Forward ); EDSPFT.FFT2(ComplexKernel, Width, Height, EDSPFD.Forward); Console.WriteLine(); Console.WriteLine("-----Source FFT--------------------------"); Console.WriteLine(Max(ComplexSource, BGRModel.R)); Console.WriteLine("-----------------------------------------"); Console.WriteLine(); Console.WriteLine("-----Kernel FFT--------------------------"); Console.WriteLine(Max(ComplexKernel)); Console.WriteLine("-----------------------------------------"); return(Source); /* * int X, Y, T; * double D2; * double Scale; * for( Y = 0 ; Y < Height ; ++Y ) { * for( X = 0 ; X < Width ; ++X ) { * D2 = ComplexKernel[ Y, X ].SquaredMagnitude; * Scale = D2 / ( D2 + Lambda ); * for( T = 0 ; T < 3 ; ++T ) { * ComplexResult[ T ][ Y, X ] = ComplexSource[ T ][ Y, X ] * Scale / ComplexKernel[ Y, X ]; * } * } * } * * Console.WriteLine(); * Console.WriteLine( "-----Result FFT--------------------------" ); * Console.WriteLine( Max( ComplexResult, BGRModel.R ) ); * Console.WriteLine( "-----------------------------------------" ); * * ComplexResult.BFFTShift(); * ComplexResult.IFFT2(); * * Console.WriteLine(); * Console.WriteLine( "-----Result------------------------------" ); * Console.WriteLine( Max( ComplexResult, BGRModel.R ) ); * Console.WriteLine( "-----------------------------------------" ); * * Bitmap Result = BGRComplexImg2Img( ComplexResult ); * return ImgUnExtend( Result, OWidth, OHeight ); */ }
static public double Max(BGRComplexImg Source, BGRModel Model) { int X, Y, Width = Source.Width, Height = Source.Height; double M = 0; int I = (int)Model / 2; for (Y = 0; Y < Height; ++Y) { for (X = 0; X < Width; ++X) { M = M < Source[I][Y, X].Magnitude ? Source[I][Y, X].Magnitude : M; } } return(M); }
static public BGRComplexImg HSI2BGR(HSIComplexImg Source) { BGRComplexImg Result = new BGRComplexImg(Source.Width, Source.Height); HSI TmpHSI = new HSI(); BGR TmpBGR = null; int X, Y; for (Y = 0; Y < Source.Height; ++Y) { for (X = 0; X < Source.Width; ++X) { TmpHSI.H = Source.H[Y, X].Re; TmpHSI.S = Source.S[Y, X].Re; TmpHSI.I = Source.I[Y, X].Re; TmpBGR = TmpHSI.ToBGR(); Result.R[Y, X].Re = TmpBGR.R; Result.G[Y, X].Re = TmpBGR.G; Result.B[Y, X].Re = TmpBGR.B; } } return(Result); }
static public HSIComplexImg BGR2HSI(BGRComplexImg Source) { HSIComplexImg Result = new HSIComplexImg(Source.Width, Source.Height); BGR TmpBGR = new BGR(); HSI TmpHSI = null; int X, Y; for (Y = 0; Y < Source.Height; ++Y) { for (X = 0; X < Source.Width; ++X) { TmpBGR.R = DoubleToByte(Source.R[Y, X].Re); TmpBGR.B = DoubleToByte(Source.B[Y, X].Re); TmpBGR.G = DoubleToByte(Source.G[Y, X].Re); TmpHSI = TmpBGR.ToHSI(); Result.H[Y, X].Re = TmpHSI.H; Result.S[Y, X].Re = TmpHSI.S; Result.I[Y, X].Re = TmpHSI.I; } } return(Result); }
static public Bitmap BGRComplexImg2Img(BGRComplexImg Source) { Bitmap Result = new Bitmap(Source.Width, Source.Height); BitmapData ResultData = Result.LockBits(new Rectangle(0, 0, Source.Width, Source.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); byte * ResultPointer = (byte *)ResultData.Scan0.ToPointer(); int X, Y, T; double Scale = 1; double Max = 0; for (Y = 0; Y < Source.Height; ++Y) { for (X = 0; X < Source.Width; ++X) { for (T = 0; T < 3; ++T) { Max = Max < Source[T][Y, X].Magnitude ? Source[T][Y, X].Magnitude : Max; } } } Scale = 255 / Max; for (Y = 0; Y < Source.Height; ++Y) { for (X = 0; X < Source.Width; ++X) { for (T = 0; T < 3; ++T) { ResultPointer[0] = DoubleToByte(Source[T][Y, X].Magnitude * Scale); ++ResultPointer; } ResultPointer[0] = 255; ++ResultPointer; } } Result.UnlockBits(ResultData); return(Result); }