private RgbImage ScaleWithBilinearInterpolation(double kx, double ky) { var res = new RgbImage((PixelWidth * kx).Round(), (PixelHeight * ky).Round()); for (int x = 0; x < PixelWidth - 1; x++) { for (int y = 0; y < PixelHeight - 1; y++) { int nx1 = (kx * x).Round(), ny1 = (ky * y).Round(); int nx2 = (kx * (x + 1)).Round(), ny2 = (ky * (y + 1)).Round(); RgbPixel p11 = this[x, y].Value, p12 = this[x, y + 1].Value, p21 = this[x + 1, y].Value, p22 = this[x + 1, y + 1].Value; for (int nx = nx1; nx <= nx2; nx++) { for (int ny = ny1; ny <= ny2; ny++) { double k = (nx2 - nx1) * (ny2 - ny1); double m1 = nx2 - nx, m2 = nx - nx1; double n1 = ny2 - ny, n2 = ny - ny1; res[nx, ny] = m2 * n2 / k * p11 + m1 * n2 / k * p21 + m2 * n1 / k * p12 + m1 * n1 / k * p22; } } } } return(res); }
public RgbImage(byte[] bgraPixels, int pixelWidth, int pixelHeight) : base(pixelWidth, pixelHeight) { for (int x = 0; x < pixelWidth; x++) { for (int y = 0; y < pixelHeight; y++) { int offset = y * PixelWidth * 4 + x * 4; // offset + 0: B // offset + 1: G // offset + 2: R // offset + 3: A Pixels[x, y] = new RgbPixel(bgraPixels[offset + 2], bgraPixels[offset + 1], bgraPixels[offset + 0], bgraPixels[offset + 3]); } } }
public IFilterableImage BilateralFilterRgb(int size, double sigmaD, double sigmaR) { var origin = new Point(size / 2, size / 2); return(ParallelMap((pixel, position) => { double weightR = 0, weightG = 0, weightB = 0, sumR = 0, sumG = 0, sumB = 0; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { var neighborPos = position - origin + new Point(x, y); neighborPos.X = neighborPos.X.LimitTo(0, PixelWidth - 1); neighborPos.Y = neighborPos.Y.LimitTo(0, PixelHeight - 1); RgbPixel neighborPixel = this[neighborPos].Value; double distFactor = -position.GetSquaredDistance(neighborPos) / (2 * sigmaD); double rw = Math.Exp(distFactor - (pixel.Value.R - neighborPixel.R).Squared() / (2 * sigmaR)); double gw = Math.Exp(distFactor - (pixel.Value.G - neighborPixel.G).Squared() / (2 * sigmaR)); double bw = Math.Exp(distFactor - (pixel.Value.B - neighborPixel.B).Squared() / (2 * sigmaR)); weightR += rw; weightG += gw; weightB += bw; sumR += rw * neighborPixel.R; sumG += gw * neighborPixel.G; sumB += bw * neighborPixel.B; } } return new RgbPixel( (byte)Math.Round(sumR / weightR).LimitTo(0, 255), (byte)Math.Round(sumG / weightG).LimitTo(0, 255), (byte)Math.Round(sumB / weightB).LimitTo(0, 255), pixel.Value.A ); })); }