private void performOneIteration(int angleIndex, GrayscaleBitmap bmp) { double[] projection = projectionHandler.CreateProjection(bmp, angleIndex * angleBetweenProjections); double[] error = new double[projection.Length]; for (int i = 0; i < projection.Length; i++) { error[i] = projections[angleIndex][i] - projection[i]; } GrayscaleBitmap errorBmp = projectionHandler.ExtrudeProjection(error, angleIndex * angleBetweenProjections); for (int i = 0; i < bmp.Width; i++) { for (int j = 0; j < bmp.Height; j++) { bmp[i, j] += errorBmp[i, j]; if (!allowNegativeValues && bmp[i, j] < 0) bmp[i, j] = 0; } } }
public List <double[]> GenerateProjections(GrayscaleBitmap bmp, int sliceCount, ProgressCounter progressCounter = null) { if (sliceCount < 1) { throw new ArgumentOutOfRangeException("sliceCount", "sliceCount must be at least 1"); } List <double[]> projections = new List <double[]>(sliceCount); double angleStep = 180.0 / sliceCount; for (int i = 0; i < sliceCount; i++) { double angle = i * angleStep; projections.Add(CreateProjection(bmp, angle)); progressCounter?.AddStep(); } return(projections); }
/// <summary> /// Reconstructs the image from projections specified in constructor /// </summary> /// <param name="progressCounter"></param> /// <returns>Reconstructed image</returns> public GrayscaleBitmap Reconstruct(ProgressCounter progressCounter = null) { int size = projections[0].Length; GrayscaleBitmap bmp = new GrayscaleBitmap(size, size); for (int i = 0; i < projections.Count; i++) { double angle = angleBetweenProjections * i; //Extrude projection in given angle GrayscaleBitmap extrudedProjection = projectionHandler.ExtrudeProjection(projections[i], angle); //add given extruded projection to the result bmp += extrudedProjection; progressCounter?.AddStep(); } bmp.Stretch(); return(bmp); }
/// <summary> /// Converts given sinogram bitmap to projections /// </summary> /// <param name="bmp">Input sinogram</param> /// <returns>List of projections</returns> public static List <double[]> SinogramToProjections(GrayscaleBitmap bmp) { int projectionCount = bmp.Height / 3; int projectionSize = bmp.Width; List <double[]> projections = new List <double[]>(projectionCount); for (int i = 0; i < projectionCount; i++) { double[] projection = new double[projectionSize]; for (int j = 0; j < projectionSize; j++) { //valuable data is placed in the second third of the image projection[j] = bmp[projectionCount + i, j]; } projections.Add(projection); } return(projections); }
public GrayscaleBitmap Reconstruct(int iterationCount, ProgressCounter progressCounter = null) { int size = projections[0].Length; double avrg = 0; for (int i = 0; i < projections[0].Length; i++) avrg += projections[0][i]; avrg /= (size * size); GrayscaleBitmap bmp = new GrayscaleBitmap(size, size); for (int i = 0; i < bmp.Width; i++) { for (int j = 0; j < bmp.Height; j++) { bmp[i, j] = avrg; } } for (int i = 0; i < iterationCount; i++) { Console.WriteLine("Iteration: " + i); performOneIteration(i % projections.Count, bmp); lastIterationNumber = i; progressCounter?.AddStep(); } GrayscaleBitmap ret = new GrayscaleBitmap(bmp.Width, bmp.Height); for (int i = 0; i < bmp.Width; i++) { for (int j = 0; j < bmp.Height; j++) { if (bmp[i, j] < 0) ret[i, j] = 0; else if (bmp[i, j] > 1) ret[i, j] = 1; else ret[i, j] = bmp[i, j]; } } currentReconstruction = bmp; return ret; }