private static Matrix3D populateArray(int rows, int columns, int slices, float number) { Matrix3D m = new Matrix3D(columns, rows, slices); for (int i = 0; i < m.Matrix.Length; i++) { m.Matrix[i] = number; } return m; }
public static void padMatrix2D(ref Matrix3D m, int pad) { //Copy OldValues float[] oldMatrix = m.Matrix; int rows = m.Rows; int columns = m.Columns; //Reset Matrix m.Rows = m.Rows + 2 * pad; m.Columns = m.Columns + 2 * pad; m.Matrix = new float[m.Rows * m.Columns * m.Slices]; //Start of padded image int start = pad * m.Columns + pad; //Set Voxels of Pad to value unsafe { fixed (float* padP = m.Matrix) { for (int i = 0; i < m.Matrix.Length; i++) { padP[i] = -1000; } } } //Copy Image to Pad unsafe { fixed (float* padP = m.Matrix) { fixed (float* matrixP = oldMatrix) { for (int s = 0; s < m.Slices; s++) { for (int rn = 0; rn < rows; rn++) { for (int c = 0; c < columns; c++) { //Since the matrix contains all slices have to target slice with s * (rows * columns) padP[start + rn * m.Columns + c] = matrixP[rn * columns + c + s * (rows * columns)]; } } start += m.SliceSize; } } } } }
public static void remove2DPad(ref Matrix3D m, int pad) { //Copy OldValues float[] oldMatrix = m.Matrix; int rows = m.Rows; int columns = m.Columns; //Reset Matrix m.Rows = m.Rows - 2 * pad; m.Columns = m.Columns - 2 * pad; m.Matrix = new float[m.Rows * m.Columns * m.Slices]; //Start of padded image int start = pad * columns + pad; //Copy Pad to Image unsafe { fixed (float* padP = oldMatrix) { fixed (float* matrixP = m.Matrix) { for (int s = 0; s < m.Slices; s++) { for (int rn = 0; rn < m.Rows; rn++) { for (int c = 0; c < m.Columns; c++) { //Since the matrix contains all slices have to target slice with s * (m.Rows * m.Columns) int indexM = rn * columns + c + s * (m.Rows * m.Columns); int indexP = start + rn * columns + c; matrixP[rn * m.Columns + c + s * (m.Rows * m.Columns)] = padP[start + rn * columns + c]; } } start += rows*columns; } } } } }
public static Matrix3D operator +(Matrix3D m1, Matrix3D m2) { if (m1.matrix.Length != m2.matrix.Length) { Console.WriteLine("Matrices are different sizes. Addition not possible!"); return m1; } Matrix3D newM = new Matrix3D(m1.Columns, m1.Rows, m1.Slices); unsafe { fixed (float* newMP = newM.matrix) { fixed (float* m1P = m1.matrix) { fixed (float* m2P = m2.matrix) { for (int i = 0; i < newM.matrix.Length; i++) { newMP[i] = m1P[i] + m2P[i]; } } } } } return newM; }
public void convolve2D_GENERIC(Matrix3D kernel) { if (kernel.Slices != 1 || kernel.Rows != kernel.Columns) { Console.WriteLine("Only square 2D kernels are allowed!"); return; } if (kernel.Rows % 2 == 0) { Console.WriteLine("Kernel has to have an odd number of rows and columns!"); return; } for (int s = 0; s < this.Slices; s++) { //Break off slice for convolution in 2D float[] oldSlice = new float[SliceSize]; float[] newSlice = new float[SliceSize]; Stopwatch stop = new Stopwatch(); stop.Start(); Buffer.BlockCopy(matrix, s * sizeof(float) * this.SliceSize, oldSlice, 0, SliceSize * sizeof(float)); unsafe { fixed (float* sliceP = oldSlice) { fixed (float* kernelP = kernel.matrix) { fixed (float* newSliceP = newSlice) { int edgeStop = kernel.Columns - 1; int kernelHalf = kernel.Columns / 2; //Start convolution for (int k = 0; k < oldSlice.Length - edgeStop * Columns; k += kernel.Columns) { //Current row int cr = k / Columns + 1; for (int j = k; j < cr * Columns - edgeStop; j++) { for (int m = 0; m < kernel.Columns; m++) { for (int n = 0; n < kernel.Columns; n++) { newSliceP[j + kernelHalf * Columns + kernelHalf] += sliceP[j + m * Columns + n] * kernelP[n]; } } k++; } cr++; } } } } } stop.Stop(); //Copy slice back to matrix Buffer.BlockCopy(newSlice, 0, matrix, s * sizeof(float) * this.SliceSize, SliceSize * sizeof(float)); } }
public void convolve2D_3X3(Matrix3D kernel) { if (kernel.Slices != 1 || kernel.Rows != kernel.Columns) { Console.WriteLine("Only square 2D kernels are allowed!"); return; } if (kernel.Rows != 3) { Console.WriteLine("Kernel has to be 3 x 3 matrix!"); return; } for (int s = 0; s < this.Slices; s++) { //Break off slice for convolution in 2D float[] oldSlice = new float[SliceSize]; float[] newSlice = new float[SliceSize]; Buffer.BlockCopy(matrix, s * sizeof(float) * this.SliceSize, oldSlice, 0, SliceSize * sizeof(float)); unsafe { fixed (float* sliceP = oldSlice) { fixed (float* kernelP = kernel.matrix) { fixed (float* newSliceP = newSlice) { //Start convolution for (int k = 0; k < oldSlice.Length - 2 * Columns; k += 3) { int cr = k / Columns + 1; for (int j = k; j < cr * Columns - 2; j++) { newSliceP[j + Columns + 1] = sliceP[j] * kernelP[0] + sliceP[j + 1] * kernelP[1] + sliceP[j + 2] * kernelP[2] + sliceP[j + Columns] * kernelP[3] + sliceP[j + Columns + 1] * kernelP[4] + sliceP[j + Columns + 2] * kernelP[5] + sliceP[j + Columns * 2] * kernelP[6] + sliceP[j + Columns * 2 + 1] * kernelP[7] + sliceP[j + Columns * 2 + 2] * kernelP[8]; k++; } cr++; } } } } } //Copy slice back to matrix Buffer.BlockCopy(newSlice, 0, matrix, s * sizeof(float) * this.SliceSize, SliceSize * sizeof(float)); } }