/// <summary> /// Get the histogram of a specific area of the image. /// The histogram is separate for each color channel /// </summary> /// <param name="image"></param> /// <param name="Min"></param> /// <param name="Max"></param> /// <param name="lines"></param> /// <returns></returns> public static void NormalizeImage(FxImages image) { FxVector<float>[] hist = new FxVectorF[image.FXPixelFormat.Length]; for (int i = 0; i < image.FXPixelFormat.Length; i++) { hist[i] = new FxVectorF(256, 0); } // get the size of the image int ImWidth = image.Image.Width; int ImHeight = image.Image.Height; // lock the input memory image.LockImage(); byte[] max = new byte[image.FXPixelFormat.Length]; byte[] min = new byte[image.FXPixelFormat.Length]; for (int g = 0; g < image.FXPixelFormat.Length; g++) { max[g] = Byte.MinValue; min[g] = Byte.MaxValue; } // find max min for (int i = 0; i < ImWidth; i++) { for (int j = 0; j < ImHeight; j++) { for (int g = 0; g < image.FXPixelFormat.Length; g++) { if (min[g] > image[i, j, (RGB)g]) min[g] = image[i, j, (RGB)g]; if (max[g] < image[i, j, (RGB)g]) max[g] = image[i, j, (RGB)g]; } } } // normalize image for (int i = 0; i < ImWidth; i++) { for (int j = 0; j < ImHeight; j++) { for (int g = 0; g < image.FXPixelFormat.Length; g++) { image[i, j, (RGB)g] = (byte)((float)(image[i, j, (RGB)g] - min[g]) / (float)(max[g] - min[g])); } } } // unlock the input and output image image.UnLockImage(); }
/// <summary> /// Result = A (*) B /// By using DFT for calculations /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <param name="Result"></param> public static void Convolution_DFT_F( FxVectorF A, FxVectorF B, out FxVectorF Result ) { FxVectorF A_dftReal,A_dftImag,B_dftReal,B_dftImag; TimeStatistics.ClockLap( "Enter" ); // get the max size from A,B int maxSize = ( A.Size > B.Size ) ? A.Size : B.Size; // check for padding if ( A.Size == maxSize && B.Size != maxSize ) { // increase the size of B B.Padding( maxSize - B.Size, true, 0 ); } else if ( B.Size == maxSize && A.Size != maxSize ) { A.Padding( maxSize - A.Size, true, 0 ); } TimeStatistics.ClockLap( "AfterPadding" ); // calc the DFT of the signal SignalTools.DFT_F( A, true, out A_dftReal, out A_dftImag ); TimeStatistics.ClockLap( "After DFT A" ); // calc the DFT of the signal SignalTools.DFT_F( B, true, out B_dftReal, out B_dftImag ); TimeStatistics.ClockLap( "After DFT B" ); // allocate result vector Result = new FxVectorF( maxSize ); float real,imag; // do the multiplication for ( int i=0; i < maxSize; i++ ) { // complex multiplication real = A_dftReal[i] * B_dftReal[i] - A_dftImag[i] * B_dftImag[i]; imag = A_dftReal[i] * B_dftImag[i] + A_dftImag[i] * B_dftReal[i]; // set the new values A_dftReal[i] = real; A_dftImag[i] = imag; } TimeStatistics.ClockLap( "After multiplication" ); // calc the DFT of the signal SignalTools.DFT_F( A_dftReal, A_dftImag, false, out Result, out B_dftImag ); TimeStatistics.ClockLap( "After iDFT" ); }
public Form1() { InitializeComponent(); FxVectorF vec1 = new FxVectorF(10, 6f); FxVectorF vec2 = new FxVectorF(10, 4f); vec1 /= vec2; var c = vec1/vec2; Console.WriteLine(c.Size); Console.WriteLine(c[0]); }
/// <summary> /// Complex Division. /// Result=A/B=(realA+i*imagA)/(realB+i*imagB) /// </summary> /// <param name="realA"></param> /// <param name="imagA"></param> /// <param name="realB"></param> /// <param name="imagB"></param> /// <param name="resultReal"></param> /// <param name="resultImag"></param> public static void Division(FxVectorF realA, FxVectorF imagA, FxVectorF realB, FxVectorF imagB, out FxVectorF resultReal, out FxVectorF resultImag) { int size = realA.Size; // allocate return result resultImag = new FxVectorF(size); resultReal = new FxVectorF(size); double bb; for (int i = 0; i < size; i++) { // calc the H=(realB + i * imagB) / (realA + i * imagA) // http://mathworld.wolfram.com/ComplexDivision.html bb = realB[i] * realB[i] + imagB[i] * imagB[i]; resultReal[i] = (float)((realA[i] * realB[i] + imagA[i] * imagB[i]) / bb); resultImag[i] = (float)((imagA[i] * realB[i] - realA[i] * imagB[i]) / bb); } }
/// <summary> /// Result = A (*) B /// By using direct form for calculations /// faster for small size filter /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <param name="Result"></param> public static void Convolution_F( FxVectorF A, FxVectorF B, out FxVectorF Result ) { // get the max size from A,B int maxSize = ( A.Size > B.Size ) ? A.Size : B.Size; int minSize = ( A.Size < B.Size ) ? A.Size : B.Size; // allocate for result Result = new FxVectorF( A.Size + B.Size - 1 ); int n_lo,n_hi; for ( int i=0; i < Result.Size; i++ ) { float s=0; n_lo = ( 0 > ( i - B.Size + 1 ) ) ? 0 : i - B.Size + 1; n_hi = ( A.Size - 1 < i ) ? A.Size - 1 : i; for ( int n=n_lo; n <= n_hi; n++ ) { s += A[n_lo] * B[i - n_lo]; n_lo++; } Result[i] = s; } }
public FxVectorF GetFrequencyResponse(int resolution) { FxVectorF inFilter = new FxVectorF(4096); FxVectorF FreqResponse = new FxVectorF(resolution); FxVectorF tmpImag, tmpReal, power; FxVectorF filter; // calc the sinc for the size of the filter for (int i = 0; i < inFilter.Size; i++) { if (i == inFilter.Size / 2) inFilter[i] = 1; else inFilter[i] = 0; } // calc the impulse of the filter this.Transform(inFilter, out filter); power = new FxVectorF(256); int mod = (int)Math.Ceiling(filter.Size / ((double)power.Size * 2)); // calc the fft of the filter SignalTools.FFT_Safe_F(filter, null, true, out tmpReal, out tmpImag); for (int i = 0; i < mod; i++) { // calc the power of the filter for (int j = 0; j < power.Size; j++) { FreqResponse[j] += (float)(Math.Sqrt(tmpReal[j * mod + i] * tmpReal[j * mod + i] + tmpImag[j * mod + i] * tmpImag[j * mod + i])); } } // normalize FreqResponse.Divide((float)(mod * Math.Sqrt(2))); return FreqResponse; }
/// <summary> /// Create a new filter base on existing data /// </summary> /// <param name="filter"></param> public FIR_GenericFilter( FxVectorF filter ) { p_Impulse = filter.GetCopy() as FxVectorF; // normalize the filter p_Impulse.Divide( (float)p_Impulse.Norms( NormVectorType.Manhattan ) ); // check that is power of 2 ( we do that for speed ) if ( Math.Pow( 2, Math.Log( p_Impulse.Size, 2 ) ) != p_Impulse.Size ) { // calc the size of log2 extence int sizeLog2 = (int)Math.Floor( Math.Log( p_Impulse.Size, 2 ) ) + 1; // calc the new maxSize int newSize = (int)Math.Pow( 2, sizeLog2 ); // increase the size of Impulse p_Impulse.Padding( newSize - p_Impulse.Size, true, 0 ); } // calc the fft of impulse TransformImpulseToFFT(); }
/// <summary> /// Get the histogram of a specific area of the image. /// The histogram is separate for each color channel /// </summary> /// <param name="image"></param> /// <param name="Min"></param> /// <param name="Max"></param> /// <param name="lines"></param> /// <returns></returns> public static FxVector<float>[] GetHistogram(FxImages image, FxVector2i Min, FxVector2i Max) { FxVector<float>[] hist = new FxVectorF[image.FXPixelFormat.Length]; for (int i = 0; i < image.FXPixelFormat.Length; i++) { hist[i] = new FxVectorF(256,0); } int pixelCount = 0; // lock the input memory //image.LockImage(); for (int i = Min.X; i < Max.X; i++) { for (int j = Min.Y; j < Max.Y; j++) { for (int g = 0; g < image.FXPixelFormat.Length; g++) { hist[g][image[i, j, (RGB)g]]++; } // count the pixels pixelCount++; } } // unlock the input and output image //image.UnLockImage(); // normalize the image for (int i = 0; i < image.FXPixelFormat.Length; i++) { hist[i].Divide(pixelCount); } return hist; }
/// <summary> /// Create a new filter base on existing data /// </summary> /// <param name="A_Data">Feedback filter coefficients</param /// <param name="B_Data">Feedforward filter coefficients</param> public IIR_GenericFilter(FxVectorF A_Data,FxVectorF B_Data) { // create copy of the data for internal use this.A_Data = A_Data.GetCopy() as FxVectorF; this.B_Data = B_Data.GetCopy() as FxVectorF; // normalize base on a0 coefficients this.A_Data.Divide(this.A_Data[0]); this.B_Data.Divide(this.A_Data[0]); // set the max offset maxOffset = (A_Data.Size > B_Data.Size) ? A_Data.Size : B_Data.Size; float maxManhattan = (float)this.A_Data.Norms(NormVectorType.Manhattan); if (maxManhattan < (float)this.B_Data.Norms(NormVectorType.Manhattan)) { maxManhattan = (float)this.B_Data.Norms(NormVectorType.Manhattan); } // normalize base on a0 coefficients this.A_Data.Divide(maxManhattan); this.B_Data.Divide(maxManhattan); }
public void Transform( float[] inBuffer, float[] outBuffer ) { FxVectorF outBufferTmp,inBufferTmp; // copy the input data to vector inBufferTmp = new FxVectorF( inBuffer ); // make the convolution SignalTools.Convolution_FFT_F( inBufferTmp, p_Impulse, out outBufferTmp ); // copy the result to the data outBufferTmp.GetValue(ref outBuffer ); }
private void button6_Click( object sender, EventArgs e ) { FxVectorF convResultFFT; // create a filter for testing FxVectorF filter = new FxVectorF( 1024 ); filter[0] = 0.1f; filter[1] = 0.5f; filter[2] = 1.5f; filter[3] = 0.5f; filter[4] = 0.1f; TimeStatistics.StartClock(); // execute the conv SignalTools.Convolution_FFT_F( signal, filter, out convResultFFT ); //SignalTools.Convolution_DFT_F( signal, filter, out convResultDFT ); TimeStatistics.StopClock( 1 ); // create a plot base on signal PloterElement plot = new PloterElement( signal ); plot.Position.X = 600; plot.Position.Y = 50; plot.Origin = new FxVector2f(10, 100); plot.FitPlots(); // add the signal to the same plot plot.AddPlot( convResultFFT, PlotType.Lines, Color.RoyalBlue ); //plot.AddPlot( convResultDFT, PlotType.Lines, Color.MistyRose ); // add the signal to canva Signal_Canva.AddElements( plot ); // add text for the signal plot TextElement text = new TextElement( "Conv Signal:" ); text.Position.X = 610; text.Position.Y = 10; // add the text to canva Signal_Canva.AddElements( text ); }
/// <summary> /// Use the filter in the input data /// </summary> /// <param name="inBuffer"></param> /// <param name="outBuffer"></param> public void Transform(FxVectorF inBuffer, FxVectorF outBuffer) { // calc the actual parameter of filter float h0 = (float)(b0 / a0); float h1 = (float)(b1 / a0); float h2 = (float)(b2 / a0); float h3 = (float)(a1 / a0); float h4 = (float)(a2 / a0); // canv the filter for (int n = 2; n < inBuffer.Size; n++) { outBuffer[n] = h0 * inBuffer[n] + h1 * inBuffer[n - 1] + h2 * inBuffer[n - 2] - h3 * outBuffer[n - 1] - h4 * outBuffer[n - 2]; } }
/// <summary> /// Radix-2 Step /// </summary> /// <param name="real">The real part of input</param> /// <param name="imag">The imag part of input</param> /// <param name="exponentSign">Fourier series exponent sign.</param> /// <param name="levelSize">Level Group Size.</param> /// <param name="k">Index inside of the level.</param> private static void Radix2Step( FxVectorF real, FxVectorF imag, int exponentSign, int levelSize, int k ) { // Twiddle Factor var exponent = ( exponentSign * k ) * Math.PI / levelSize; float wR = (float)Math.Cos( exponent ); float wI = (float)Math.Sin( exponent ); var step = levelSize << 1; for ( var i = k; i < real.Size; i += step ) { float aiR = real[i]; float aiI = imag[i]; // complex multiplication float tR = wR * real[i + levelSize] - wI * imag[i + levelSize]; float tI = wR * imag[i + levelSize] + wI * real[i + levelSize]; real[i] = aiR + tR; real[i + levelSize] = aiR - tR; imag[i] = aiI + tI; imag[i + levelSize] = aiI - tI; } }
/// <summary> /// FFT algorithm /// </summary> /// <param name="real">The real part of input</param> /// <param name="imag">The imag part of input</param> /// <param name="Forward">The </param> /// <param name="resultReal">The real part of the result</param> /// <param name="resultImag">The real imag of the result</param> public static void FFT_F( FxVectorF real, FxVectorF imag, Boolean Forward, out FxVectorF resultReal, out FxVectorF resultImag ) { // find the size and log2(size) int size = real.Size; int sizeLog2 = (int)Math.Log( size, 2 ); // allocate result FxVectorF resultRealTmp = new FxVectorF( size ); FxVectorF resultImagTmp = new FxVectorF( size ); // Do the bit reversal int i2 = size >> 1; var j = 0; for ( var i = 0; i < size - 1; i++ ) { if ( i < j ) { resultRealTmp[i] = real[j]; resultRealTmp[j] = real[i]; if ( imag == null ) { resultImagTmp[i] = 0; resultImagTmp[j] = 0; } else { resultImagTmp[i] = imag[j]; resultImagTmp[j] = imag[i]; } } var m = size; do { m >>= 1; j ^= m; } while ( ( j & m ) == 0 ); } // set the sign of exponents int exponentSign = ( Forward ) ? 1 : -1; // pass all the level of fft tree and compute the fourier for ( var levelSize = 1; levelSize < size; levelSize *= 2 ) { Parallel.For( 0, levelSize, index => Radix2Step( resultRealTmp, resultImagTmp, exponentSign, levelSize, index ) ); } // set the out result resultReal = resultRealTmp; resultImag = resultImagTmp; // normalize when we have reverce if ( !Forward ) { resultReal.Divide( size ); resultImag.Divide( size ); } }
void init_buffers(int len) { tmpVecOrig = new FxVectorF( len ); tmpVec = new FxVectorF( len ); power = new FxVectorF( 256 ); }
/// <summary> /// Result = A (*) B /// By using FFT for calculations /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <param name="Result"></param> public static void Convolution_FFT_F( FxVectorF A, FxVectorF B, out FxVectorF Result ) { FxVectorF A_dftReal,A_dftImag,B_dftReal,B_dftImag; // copy local the inputs FxVectorF A_local = A.GetCopy() as FxVectorF; FxVectorF B_local = B.GetCopy() as FxVectorF; // get the max size from A,B int maxSize = ( A_local.Size > B_local.Size ) ? A_local.Size : B_local.Size; // check that is power of 2 if ( Math.Pow( 2, Math.Log( maxSize, 2 ) ) != maxSize ) { // calc the size of log2 extence int sizeLog2 = (int)Math.Floor( Math.Log( maxSize, 2 ) ) + 1; // calc the new maxSize maxSize = (int)Math.Pow( 2, sizeLog2 ); // increase the size of A,B A_local.Padding( maxSize - A_local.Size, true, 0 ); B_local.Padding( maxSize - B_local.Size, true, 0 ); } // allocate temp file FxVectorF tmp = new FxVectorF( maxSize ); // check for padding if ( A_local.Size == maxSize && B_local.Size != maxSize ) { // increase the size of B B_local.Padding( maxSize - B_local.Size, true, 0 ); } else if ( B_local.Size == maxSize && A_local.Size != maxSize ) { A_local.Padding( maxSize - A_local.Size, true, 0 ); } // calc the DFT of the signal SignalTools.FFT_F( A_local, tmp, true, out A_dftReal, out A_dftImag ); // calc the DFT of the signal SignalTools.FFT_F( B_local, tmp, true, out B_dftReal, out B_dftImag ); // allocate result vector Result = new FxVectorF( maxSize ); float real,imag; // do the multiplication for ( int i=0; i < maxSize; i++ ) { // complex multiplication real = A_dftReal[i] * B_dftReal[i] - A_dftImag[i] * B_dftImag[i]; imag = A_dftReal[i] * B_dftImag[i] + A_dftImag[i] * B_dftReal[i]; // set the new values A_dftReal[i] = real; A_dftImag[i] = imag; } // calc the DFT of the signal SignalTools.FFT_F( A_dftReal, A_dftImag, false, out Result, out B_dftImag ); // cat the padding int maxInputSize = ( A.Size > B.Size ) ? A.Size : B.Size; Result = Result.GetSubVector( maxSize - maxInputSize, Result.Size) as FxVectorF; }
private void button12_Click( object sender, EventArgs e ) { openFileDialog1.Filter = "White noise data file|*.dat"; openFileDialog1.FilterIndex = 1; if ( openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK ) { TimeStatistics.StartClock(); // read the file to the memmory and then parse the file List<string> lines = new List<string>(); lines.AddRange( File.ReadAllLines( openFileDialog1.FileName ) ); Console.WriteLine( lines.Count ); // create the vector for white noise data wn = new FxVectorF( lines.Count ); int wnIndex =0; // parse the lines foreach ( string str in lines ) { // parse the float wn[wnIndex] = float.Parse( str.Replace('.',',')); // increase the index for the wn vector wnIndex++; } TimeStatistics.ClockLap( "File Load Parse Complete" ); TimeStatistics.StopClock( 1 ); } }
/// <summary> /// Result = A (*) B /// By using FFT for calculations /// The second vector is allready in fft form /// The two vectors must have the same size and be power of 2 /// </summary> /// <param name="A"></param> /// <param name="B_dftReal"></param> /// <param name="B_dftImag"></param> /// <param name="Result"></param> public static void Convolution_FFT_F( FxVectorF A, FxVectorF B_dftReal, FxVectorF B_dftImag, out FxVectorF Result ) { FxVectorF A_dftReal,A_dftImag; // copy local the inputs FxVectorF A_local = A.GetCopy() as FxVectorF; // get the max size from A,B int maxSize = ( A_local.Size > B_dftReal.Size ) ? A_local.Size : B_dftReal.Size; // calc the DFT of the signal SignalTools.FFT_F( A_local, null, true, out A_dftReal, out A_dftImag ); // allocate result vector Result = new FxVectorF( maxSize ); float real,imag; // do the multiplication for ( int i=0; i < maxSize; i++ ) { // complex multiplication real = A_dftReal[i] * B_dftReal[i] - A_dftImag[i] * B_dftImag[i]; imag = A_dftReal[i] * B_dftImag[i] + A_dftImag[i] * B_dftReal[i]; // set the new values A_dftReal[i] = real; A_dftImag[i] = imag; } // calc the DFT of the signal SignalTools.FFT_F( A_dftReal, A_dftImag, false, out Result, out B_dftImag ); // cat the padding int maxInputSize = ( A.Size > B_dftReal.Size ) ? A.Size : B_dftReal.Size; Result = Result.GetSubVector( maxSize - maxInputSize, Result.Size ) as FxVectorF; }
public FxVectorF GetFrequencyResponse(int resolution) { // copy local the coefficiens FxVectorF A_Data_Local = A_Data.GetCopy() as FxVectorF; FxVectorF B_Data_Local = B_Data.GetCopy() as FxVectorF; // padding A if (2 * resolution > A_Data_Local.Size) A_Data_Local.Padding(2 * resolution - A_Data_Local.Size, true, 0); // padding B if (2 * resolution > B_Data_Local.Size) B_Data_Local.Padding(2 * resolution - B_Data_Local.Size, true, 0); FxVectorF tmpRealA, tmpRealB, tmpImagA, tmpImagB,resultReal,resultImag; // fft of A SignalTools.FFT_F(A_Data_Local, null, true, out tmpRealA, out tmpImagA); // fft of A SignalTools.FFT_F(B_Data_Local, null, true, out tmpRealB, out tmpImagB); // complex division Complex.ComplexTools.Division(tmpRealB, tmpImagB, tmpRealA, tmpImagA, out resultReal, out resultImag); FxVectorF result = new FxVectorF(resolution); // calc the arg for (int j = 0; j < resolution; j++) { result[j] = (float)(Math.Sqrt(resultReal[j] * resultReal[j] + resultImag[j] * resultImag[j])); } return result; }
/// <summary> /// DFT /// </summary> /// <param name="real"></param> /// <param name="imag"></param> /// <param name="Forward"></param> /// <param name="resultReal"></param> /// <param name="resultImag"></param> public static void DFT_F( FxVectorF real, FxVectorF imag, Boolean Forward, out FxVectorF resultReal, out FxVectorF resultImag ) { // set the direction of the DFT double dir = ( Forward ) ? -1 : 1; double arg, cosarg,sinarg; int size = real.Size; // allocate result FxVectorF resultRealTmp = new FxVectorF( size ); FxVectorF resultImagTmp = new FxVectorF( size ); // pass all the datas Parallel.For( 0, size, ( i ) => { arg = -dir * 2.0 * Math.PI * (double)i / size; for ( int k = 0; k < size; k++ ) { cosarg = Math.Cos( k * arg ); sinarg = Math.Sin( k * arg ); resultRealTmp[i] += (float)( real[k] * cosarg - imag[k] * sinarg ); resultImagTmp[i] += (float)( real[k] * sinarg + imag[k] * cosarg ); } } ); // pass the result to the output resultReal = resultRealTmp; resultImag = resultImagTmp; // normalize when we have reverce if ( !Forward ) { resultReal.Divide( size ); resultImag.Divide( size ); } }
private void toolStripButton_ellipse_extract_Click(object sender, EventArgs e) { // extract the rectangle that contain if ((imMat as object != null) && (rect != null)) { int numLabels; // get the sub matrix var subMat = imMat.GetSubMatrix(rect.StartPoint, rect.EndPoint) as FxMatrixF; // make binary the image based on the start and end point of rectangle float t = subMat[0, 0]; if (t > subMat[subMat.Width - 1, subMat.Height - 1]) t = subMat[subMat.Width - 1, subMat.Height - 1]; var binMat = subMat < t - 0.02f; // find the labels of the image var labels = binMat.Labeling(out numLabels); var imSub = new ImageElement(binMat.ToFxMatrixF(), new ColorMap(ColorMapDefaults.Jet)); imSub._Position.x = ieEllipseImage.Size.x + ieEllipseImage.Position.x; imSub.lockMoving = true; canvas_ellipse.AddElement(imSub, false, false); var imSub2 = new ImageElement(labels, new ColorMap(ColorMapDefaults.Jet)); imSub2._Position.x = ieEllipseImage.Size.x + ieEllipseImage.Position.x; imSub2._Position.y = imSub.Size.y + imSub.Position.y; imSub2.lockMoving = true; canvas_ellipse.AddElement(imSub2, false, false); WriteLine("Num Labels : " + numLabels.ToString()); var contours = new FxContour(binMat, 10, 300); WriteLine("Num Contours : " + contours.NumChains); results = new FxMatrixF(3, contours.NumChains); int i=0; foreach (var x in contours.ChainList) { float delta = 1; // draw the rectanges in the sub image FxVector2f start = x.RectStart + imSub2._Position + new FxVector2f(1, 1); FxVector2f end = start + x.RectSize; FxMaths.Geometry.Rectangle r = new FxMaths.Geometry.Rectangle(start, end); gpeEllipseImage.AddGeometry(r, false); // draw the rectanges in main image start = x.RectStart + rect.StartPoint + new FxVector2f(-delta, -delta); end = start + x.RectSize + new FxVector2f(2 * delta, 2 * delta); r = new FxMaths.Geometry.Rectangle(start, end); gpeEllipseImage.AddGeometry(r, false); // draw the centroids FxVector2f cen = x.GetCentroid() + rect.StartPoint; var l = new FxMaths.Geometry.Line(cen - new FxVector2f(0, 2), cen + new FxVector2f(0, 2)); l.LineWidth = 0.5f; gpeEllipseImage.AddGeometry(l, false); l = new FxMaths.Geometry.Line(cen - new FxVector2f(2, 0), cen + new FxVector2f(2, 0)); l.LineWidth = 0.5f; gpeEllipseImage.AddGeometry(l, false); // calculate the depth float[] depth = new float[4]; FxVector2f pos = x.RectStart + rect.StartPoint; depth[0] = imMat[pos.x - delta, pos.y - delta]; depth[1] = imMat[pos.x + x.RectSize.x + delta, pos.y - delta]; depth[2] = imMat[pos.x - delta, pos.y + x.RectSize.y + delta]; depth[3] = imMat[pos.x + x.RectSize.x + delta, pos.y + x.RectSize.y + delta]; results[2, i] = (depth[0] + depth[1] + depth[2] + depth[3]) / 4.0f; // save centroid results[0, i] = cen.x; results[1, i] = cen.y; // print the centroid WriteLine("[" + i.ToString() + "] Depth:" + results[2, i].ToString() + " Pixels:" + x.Count + " Centroid: " + cen.ToString()); i++; // show the vector of one blob if (i == 1) { FxVectorF vec_i = new FxVectorF(x.Count); FxVectorF vec_r = new FxVectorF(x.Count); vec_i[0] = x[0].i; vec_r[0] = x[0].r; for (int j = 1; i < x.Count; j++) { vec_i[j] = vec_i[j - 1] + x[j].i; vec_r[j] = vec_r[j - 1] + x[j].r; } } } canvas_ellipse.ReDraw(); results.SaveCsv("ellipseResults.csv"); } }
/// <summary> /// FFT algorithm with internal padding to power of 2 /// </summary> /// <param name="real">The real part of input</param> /// <param name="imag">The imag part of input</param> /// <param name="Forward">The </param> /// <param name="resultReal">The real part of the result</param> /// <param name="resultImag">The real imag of the result</param> public static void FFT_Safe_F( FxVectorF real, FxVectorF imag, Boolean Forward, out FxVectorF resultReal, out FxVectorF resultImag ) { // copy local the inputs FxVectorF real_local = real.GetCopy() as FxVectorF; FxVectorF imag_local = ( imag != null ) ? imag.GetCopy() as FxVectorF : null; // get the max size from A,B int maxSize; if ( imag_local != null ) maxSize = ( real_local.Size > imag_local.Size ) ? real_local.Size : imag_local.Size; else maxSize = real_local.Size; // check that is power of 2 if ( Math.Pow( 2, Math.Floor( Math.Log( maxSize, 2 ) ) ) != maxSize ) { // calc the size of log2 extence int sizeLog2 = (int)Math.Floor( Math.Log( maxSize, 2 ) ) + 1; // calc the new maxSize maxSize = (int)Math.Pow( 2, sizeLog2 ); // increase the size of A,B real_local.Padding( maxSize - real_local.Size, true, 0 ); if ( imag_local != null ) imag_local.Padding( maxSize - imag_local.Size, true, 0 ); } // call the unsafe fft FFT_F( real_local, imag_local, Forward, out resultReal, out resultImag ); }
private void ellipseDetectionToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { // load image imMat = FxMatrixF.Load(ofd.FileName); ieEllipseImage = new ImageElement(imMat, new ColorMap(ColorMapDefaults.Jet)); ieEllipseImage.lockMoving = true; canvas_ellipse.AddElement(ieEllipseImage); // add plot element gpeEllipseImage = new GeometryPlotElement(); canvas_ellipse.AddElement(gpeEllipseImage); var contours = new FxContour(imMat<0.2f); WriteLine("Num Contours : " + contours.NumChains); int i = 0; float pe_pos_y = ieEllipseImage._Position.y; foreach (var cont in contours.ChainList) { // draw the rectanges in main image FxVector2f start = cont.RectStart ; FxVector2f end = start + cont.RectSize; FxMaths.Geometry.Rectangle r = new FxMaths.Geometry.Rectangle(start, end); gpeEllipseImage.AddGeometry(r, false); // draw the centroids FxVector2f cen = cont.GetCentroid(); var l = new FxMaths.Geometry.Line(cen - new FxVector2f(0, 2), cen + new FxVector2f(0, 2)); l.LineWidth = 0.5f; gpeEllipseImage.AddGeometry(l, false); l = new FxMaths.Geometry.Line(cen - new FxVector2f(2, 0), cen + new FxVector2f(2, 0)); l.LineWidth = 0.5f; gpeEllipseImage.AddGeometry(l, false); // add the numbering of the contours var t = new TextElement(i.ToString()); t._Position = cen; t.FontColor = SharpDX.Color.Green; t._TextFormat.fontSize = 16.0f; canvas_ellipse.AddElement(t); // show the chain vector in plot { FxVectorF vec_i = new FxVectorF(cont.Count); FxVectorF vec_r = new FxVectorF(cont.Count); vec_i[0] = cont[0].i; vec_r[0] = cont[0].r; for (int j = 1; j < cont.Count; j++) { vec_i[j] = vec_i[j - 1] + cont[j].i; vec_r[j] = vec_r[j - 1] + cont[j].r; } // show the plot of this vector var pe = new PloterElement(vec_i, PlotType.Lines, System.Drawing.Color.Blue); pe._Position.x = ieEllipseImage._Position.x + ieEllipseImage.Size.x; pe._Position.y = pe_pos_y; pe.AddPlot(vec_r, PlotType.Lines, System.Drawing.Color.Red); pe.CenterYOrigin(); pe.FitPlots(); canvas_ellipse.AddElement(pe); // update the y of pe for the next one pe_pos_y += pe.Size.y; // debug the ellipse for (int j = 0; j < cont.Count; j++) { imMat[(int)(vec_r[j] + cont.StartPoint.x), (int)(vec_i[j] + cont.StartPoint.y)] = 0.8f/contours.NumChains + 0.1f; } ieEllipseImage.UpdateInternalImage(imMat, new ColorMap(ColorMapDefaults.Jet)); } i++; } canvas_ellipse.ReDraw(); } }
/// <summary> /// Use the filter in the input data /// </summary> /// <param name="inBuffer"></param> /// <param name="outBuffer"></param> public void Transform( FxVectorF inBuffer, out FxVectorF outBuffer ) { // make the convolution SignalTools.Convolution_FFT_F( inBuffer, p_Impulse, out outBuffer ); }
public void Transform( FxVectorF inBuffer, FxVectorF outBuffer ) { FxVectorF outBufferTmp; FxVectorF inBuffer_local = inBuffer; if ( inBuffer.Size > p_Impulse.Size ) { // add zeros to the end of the impulse p_Impulse.Padding( inBuffer.Size - p_Impulse.Size, true, 0 ); // update fft TransformImpulseToFFT(); } if ( inBuffer.Size < p_Impulse.Size ) { // copy the input buffer local inBuffer_local = inBuffer.GetCopy() as FxVectorF; // add zero sto teh end of the input buffer inBuffer_local.Padding( p_Impulse.Size - inBuffer_local.Size, true, 0 ); } // make the convolution SignalTools.Convolution_FFT_F( inBuffer_local, p_ImpulseFFT_Real, p_ImpulseFFT_Imag, out outBufferTmp ); if ( inBuffer_local != inBuffer ) { // copy the result to the data outBuffer.SetValue( outBufferTmp.GetSubVector( inBuffer_local.Size - inBuffer.Size, outBufferTmp.Size ) ); } else { // copy the result to the data outBuffer.SetValue( outBufferTmp ); } }
public void Transform(FxVectorF inBuffer, out FxVectorF outBuffer) { // allocate the output filter outBuffer = new FxVectorF(inBuffer.Size); this.Transform(inBuffer, outBuffer); }
private void button13_Click( object sender, EventArgs e ) { // process the white noise data with the dsp if ( wn != null ) { tmpWn = new FxVectorF( wn.Size ); // create the signal spectrum graphs if ( plot_signal_spectrum == null ) { power = new FxVectorF( 256 ); #region Plot Creation signal_spectrum = new FxVectorF( 256 ); // insert the plot of the time filter filterPlot = new PloterElement( signal_spectrum ); filterPlot.Position.X = 0; filterPlot.Position.Y = 410; filterPlot.Origin = new FxVector2f(10, 100); filterPlot.FitPlots(); canvas_audio.AddElements( filterPlot ); // create the plot for the spectrum plot_signal_spectrum = new PloterElement( signal_spectrum ); plot_signal_spectrum.Position.X = 0; plot_signal_spectrum.Position.Y = 10; plot_signal_spectrum.Origin = new FxVector2f(10, 100); plot_signal_spectrum.FitPlots(); plot_signal_spectrum.AddPlot( signal_spectrum, PlotType.Lines, Color.Aqua ); // add the signal to canva canvas_audio.AddElements( plot_signal_spectrum ); // create the plot for the spectrum plot_signal_spectrum_original = new PloterElement( signal_spectrum ); plot_signal_spectrum_original.Position.X = 600; plot_signal_spectrum_original.Position.Y = 10; plot_signal_spectrum_original.Origin = new FxVector2f(10, 100); plot_signal_spectrum_original.FitPlots(); // add the signal to canva canvas_audio.AddElements( plot_signal_spectrum_original ); // create the plot for the spectrum plot_filter_spectrum = new PloterElement( signal_spectrum ); plot_filter_spectrum.Position.X = 600; plot_filter_spectrum.Position.Y = 410; plot_filter_spectrum.Origin = new FxVector2f(10, 100); plot_filter_spectrum.FitPlots(); // add the signal to canva canvas_audio.AddElements( plot_filter_spectrum ); #endregion // add filter UpdateFilter( BiQuadFilter.BandPassFilterConstantPeakGain( 44100, 20000, 0.5f ) ); } if ( this.fil != null ) { // use the filter directly this.fil.Transform( wn, tmpWn ); } FxVectorF tmpImag,tmpReal; // calc spectrum int mod = (int)Math.Ceiling( tmpWn.Size / ( (double)power.Size * 2 ) ); // =============================================================================================== if ( ShowOutputAudioSpectrum ) { power.SetValue( 0.0f ); FxVectorF local=tmpWn; if ( Math.Pow( 2, Math.Floor( Math.Log( local.Size, 2 ) ) ) != local.Size ) { int newSize; // calc the size of log2 int sizeLog2 = (int)Math.Floor( Math.Log( local.Size, 2 ) ) - 1; // calc the new size newSize = (int)Math.Pow( 2, sizeLog2 ); if ( newSize < 512 ) newSize = 512; local = tmpWn.GetSubVector( 0, newSize ) as FxVectorF; } mod = (int)Math.Ceiling( local.Size / ( (double)power.Size * 2 ) ); // calc the fft SignalTools.FFT_F( local, null, true, out tmpReal, out tmpImag ); // pass all the data in form of blocks for ( int i = 0; i < mod; i++ ) { for ( int j = 0; j < power.Size; j++ ) { power[j] += (float)( Math.Sqrt( tmpReal[j * mod + i] * tmpReal[j * mod + i] + tmpImag[j * mod + i] * tmpImag[j * mod + i] ) ); } } // normalize the result power.Divide( power.Max() ); // refresh the plot plot_signal_spectrum.RefreshPlot( power, 0 ); plot_signal_spectrum.FitPlots(); // redraw canvas if we are not going to show output spectrum if ( !ShowInputAudioSpectrum ) canvas_audio.ReDraw(); } // =============================================================================================== if ( ShowInputAudioSpectrum ) { // calc spectrum // reset the power power.SetValue( 0.0f ); FxVectorF local=wn; if ( Math.Pow( 2, Math.Floor( Math.Log( local.Size, 2 ) ) ) != local.Size ) { int newSize; // calc the size of log2 int sizeLog2 = (int)Math.Floor( Math.Log( local.Size, 2 ) ) - 1; // calc the new size newSize = (int)Math.Pow( 2, sizeLog2 ); if ( newSize < 512 ) newSize = 512; local = wn.GetSubVector( 0, newSize ) as FxVectorF; } mod = (int)Math.Ceiling( local.Size / ( (double)power.Size * 2 ) ); // calc the fft SignalTools.FFT_Safe_F( local, null, true, out tmpReal, out tmpImag ); // pass all the data in form of blocks for ( int i = 0; i < mod; i++ ) { for ( int j = 0; j < power.Size; j++ ) { power[j] += (float)( Math.Sqrt( tmpReal[j * mod + i] * tmpReal[j * mod + i] + tmpImag[j * mod + i] * tmpImag[j * mod + i] ) ); } } // normalize the result power.Divide( power.Max() ); // refresh the plot plot_signal_spectrum_original.RefreshPlot( power, 0 ); plot_signal_spectrum_original.FitPlots(); // redraw canvas canvas_audio.ReDraw(); } } }