public static ImageBuffer Convolution(this ImageBuffer buffer, double[,] xKernel, double[,] yKernel, double factor = 1, int bias = 0) { byte[] source = buffer.Bytes; ImageBuffer output = buffer.CloneFormat(); byte[] target = output.Bytes; double blueX, greenX, redX, blueY, greenY, redY; double blueTotal, greenTotal, redTotal; int filterOffset = 1; int calcOffset = 0; int byteOffset = 0; for (int offsetY = filterOffset; offsetY < buffer.Height - filterOffset; offsetY++) { for (int offsetX = filterOffset; offsetX < buffer.Width - filterOffset; offsetX++) { blueX = greenX = redX = 0; blueY = greenY = redY = 0; blueTotal = greenTotal = redTotal = 0.0; byteOffset = offsetY * buffer.Stride + offsetX * 4; for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * buffer.Stride); blueX += (double)(source[calcOffset + 0]) * xKernel[filterY + filterOffset, filterX + filterOffset]; greenX += (double)(source[calcOffset + 1]) * xKernel[filterY + filterOffset, filterX + filterOffset]; redX += (double)(source[calcOffset + 2]) * xKernel[filterY + filterOffset, filterX + filterOffset]; blueY += (double)(source[calcOffset + 0]) * yKernel[filterY + filterOffset, filterX + filterOffset]; greenY += (double)(source[calcOffset + 1]) * yKernel[filterY + filterOffset, filterX + filterOffset]; redY += (double)(source[calcOffset + 2]) * yKernel[filterY + filterOffset, filterX + filterOffset]; } } blueTotal = Math.Sqrt((blueX * blueX) + (blueY * blueY)); greenTotal = Math.Sqrt((greenX * greenX) + (greenY * greenY)); redTotal = Math.Sqrt((redX * redX) + (redY * redY)); target[byteOffset + 0] = ByteConversion.Bounded(blueTotal); target[byteOffset + 1] = ByteConversion.Bounded(greenTotal); target[byteOffset + 2] = ByteConversion.Bounded(redTotal); target[byteOffset + 3] = 255; } } return(output); }
// See also: http://matlabtricks.com/post-5/3x3-convolution-kernels-with-online-demo#demo public static ImageBuffer Convolution(this ImageBuffer buffer, double[,] kernel, double factor = 1, int bias = 0) { byte[] source = buffer.Bytes; ImageBuffer output = buffer.Fill(Color.Black); byte[] target = output.Bytes; double blue, green, red; int width = kernel.GetLength(0); //int height = kernel.GetLength(1); // ?? wordt (nog?) niet gebruikt (20150101 FH) int matrixOffset = (width - 1) / 2; int calcOffset, byteOffset; for (int offsetY = matrixOffset; offsetY < buffer.Height - matrixOffset; offsetY++) { for (int offsetX = matrixOffset; offsetX < buffer.Width - matrixOffset; offsetX++) { blue = 0; green = 0; red = 0; byteOffset = offsetY * buffer.Stride + offsetX * 4; for (int filterY = -matrixOffset; filterY <= matrixOffset; filterY++) { for (int filterX = -matrixOffset; filterX <= matrixOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * buffer.Stride); blue += (double)(source[calcOffset + 0]) * kernel[filterY + matrixOffset, filterX + matrixOffset]; green += (double)(source[calcOffset + 1]) * kernel[filterY + matrixOffset, filterX + matrixOffset]; red += (double)(source[calcOffset + 2]) * kernel[filterY + matrixOffset, filterX + matrixOffset]; } } blue = factor * blue + bias; green = factor * green + bias; red = factor * red + bias; target[byteOffset + 0] = ByteConversion.Bounded(blue); target[byteOffset + 1] = ByteConversion.Bounded(green); target[byteOffset + 2] = ByteConversion.Bounded(red); target[byteOffset + 3] = 255; } } return(output); }
public static ImageBuffer PureRGB(this ImageBuffer buffer, byte level, Color color) { ImageBuffer output = buffer.CloneFormat(); for (int k = 0; k < buffer.Bytes.Length; k += 4) { output.Bytes[k + 0] = ByteConversion.LevelSplit(buffer.Bytes[k + 0], level, color.B, 0); output.Bytes[k + 1] = ByteConversion.LevelSplit(buffer.Bytes[k + 1], level, color.G, 0); output.Bytes[k + 2] = ByteConversion.LevelSplit(buffer.Bytes[k + 2], level, color.R, 0); output.Bytes[k + 3] = 255; } return(output); }
public static ImageBuffer SuperImpoze(this ImageBuffer image, ImageBuffer impoze) { ImageBuffer output = image.Clone(); for (int k = 0; k < output.Bytes.Length; k += 4) { output.Bytes[k + 0] = ByteConversion.MinAtLevel(impoze.Bytes[k + 0], 1, output.Bytes[k + 0]); output.Bytes[k + 1] = ByteConversion.MinAtLevel(impoze.Bytes[k + 1], 1, output.Bytes[k + 1]); output.Bytes[k + 2] = ByteConversion.MinAtLevel(impoze.Bytes[k + 2], 1, output.Bytes[k + 2]); output.Bytes[k + 3] = 255; } return(output); }
public static ImageBuffer Add(params ImageBuffer[] buffers) { ImageBuffer output = buffers[0].CloneFormat(); for (int k = 0; k < output.Bytes.Length; k += 4) { for (int i = 0; i < buffers.Count(); i++) { output.Bytes[k + 0] = ByteConversion.Max(output.Bytes[k + 0] + buffers[i].Bytes[k + 0]); output.Bytes[k + 1] = ByteConversion.Max(output.Bytes[k + 1] + buffers[i].Bytes[k + 1]); output.Bytes[k + 2] = ByteConversion.Max(output.Bytes[k + 2] + buffers[i].Bytes[k + 2]); output.Bytes[k + 3] = 255; } } return(output); }
public static void AverageOut(this byte[] buffer, int p1, int p2) { int d = Math.Abs(buffer[p1] - buffer[p2]); if (d < 15 && d > 0) { byte value = ByteConversion.Max((buffer[p1] + buffer[p2]) / 2); buffer[p1 + 0] = value; // blue buffer[p1 + 1] = value; // green buffer[p1 + 2] = value; // red buffer[p1 + 3] = 255; // transparency buffer[p2 + 0] = value; // blue buffer[p2 + 1] = value; // green buffer[p2 + 2] = value; // red buffer[p2 + 3] = 255; // transparency } }