/// <summary> /// Constructor - transformation RGB vector to HSI /// </summary> /// <param name="vec">RGB vector</param> public VectorHsi(VectorRgb vec) { VectorHsi vecHsi = Cip.Foundations.ColorspaceHelper.RGB2HSI(vec); this.h = vecHsi.h; this.s = vecHsi.s; this.i = vecHsi.i; }
public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; DateTime startTime = DateTime.Now; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster; //stamping filter LinearFilter filter = Cip.Filters.LinearFilter.Stamping(); raster = filter.ProcessRaster(rOriginal, worker); //VectorHSI hsi; int intensity; byte g; //convert to gray image and increase lightness for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { intensity = Cip.Foundations.ColorspaceHelper.RGB2GRAYI(raster[i, j]); intensity += 128; g = VectorRgb.ClampByte(intensity); raster[i, j] = new VectorRgb(g, g, g); } worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } return raster; }
/// <summary> /// Convert RGB colorspace to HSI colorspace. /// </summary> public static VectorHsi RGB2HSI(VectorRgb rgb) { VectorHsi hsi = new VectorHsi(); //method from CxImageLib. ximadsp.cpp file. byte H, S, I; UInt16 Rdelta, Gdelta, Bdelta; //get R, G, and B in 8-bit byte R = rgb.R; byte G = rgb.G; byte B = rgb.B; byte cMax = Math.Max(Math.Max(R, G), B);// calculate lightness (intensity) byte cMin = Math.Min(Math.Min(R, G), B); I = (byte)((((cMax + cMin) * HSIMAX) + RGBMAX) / (2 * RGBMAX)); if (cMax == cMin){ // r=g=b --> achromatic case S = 0; // saturation H = HSIUNDEFINED; // hue } else { // chromatic case if (I <= (HSIMAX / 2)) // saturation S = (byte)((((cMax - cMin) * HSIMAX) + ((cMax + cMin) / 2)) / (cMax + cMin)); else S = (byte)((((cMax - cMin) * HSIMAX) + ((2 * RGBMAX - cMax - cMin) / 2)) / (2 * RGBMAX - cMax - cMin)); // hue Rdelta = (UInt16)((((cMax - R) * (HSIMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin)); Gdelta = (UInt16)((((cMax - G) * (HSIMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin)); Bdelta = (UInt16)((((cMax - B) * (HSIMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin)); if (R == cMax) H = (byte)(Bdelta - Gdelta); else if (G == cMax) H = (byte)((HSIMAX / 3) + Rdelta - Bdelta); else // B == cMax H = (byte)(((2 * HSIMAX) / 3) + Gdelta - Rdelta); //if (H < 0) H += HSIMAX; //always false if (H > HSIMAX) H -= HSIMAX; } hsi.H = (float)(H / 255.0f); hsi.S = (float)(S / 255.0f); hsi.I = (float)(I / 255.0f); return hsi; }
/// <summary> /// Convert RGB colorspace to YUV colorspace. /// </summary> public static VectorRgb RGB2YUV(VectorRgb rgb) { int Y, U, V; byte R = rgb.R; byte G = rgb.G; byte B = rgb.B; Y = (int)(0.299f * R + 0.587f * G + 0.114f * B); U = (int)((B - Y) * 0.565f + 128); V = (int)((R - Y) * 0.713f + 128); Y = Math.Min(255, Math.Max(0, Y)); U = Math.Min(255, Math.Max(0, U)); V = Math.Min(255, Math.Max(0, V)); return new VectorRgb(Y, U, V); }
public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); DateTime startTime = DateTime.Now; //processing float c = (100 + contrast) / 100.0f; brightness += 128; byte[] cTable = new byte[256]; for (int i = 0; i < 256; i++) { cTable[i] = (byte)Math.Max(0, Math.Min(255, (int)((i - 128) * c + brightness + 0.5f))); } VectorRgb newcolor = new VectorRgb();; Color cl; //image processing for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { newcolor = new VectorRgb(); cl = rOriginal[i, j].ToColor(); newcolor.R = cTable[cl.R]; newcolor.G = cTable[cl.G]; newcolor.B = cTable[cl.B]; raster[i, j] = newcolor; } worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } return raster; }
/// <summary> /// Constructor. /// </summary> /// <param name="color"> /// Color of filter (use Color.Empty to set def. color). /// </param> public SepiaFilter(System.Drawing.Color color) { luminance = new VectorRgb(0.3f, 0.59f, 0.11f); if (color == Color.Empty) sepiacolor = new VectorRgb(1.0f, 0.89f, 0.54f); else sepiacolor = new VectorRgb(color); }
/// <summary> /// Function that apply bloom filter to raster. /// </summary> /// <param name="rOriginal">Original raster.</param> /// <param name="worker">Background worker.</param> /// <returns>Modifyed raster.</returns> public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); DateTime startTime = DateTime.Now; byte threshold = (byte)(this.lightThreshold * 255); VectorRgb color; //bright pass for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { color = rOriginal[i, j]; if (color.R > threshold || color.G > threshold || color.B > threshold) raster[i, j] = color; else raster[i, j] = new VectorRgb(0, 0, 0); } worker.ReportProgress((int)(100f * i / width), DateTime.Now - startTime); } //blur SmoothingFilter filterSmoothing = new SmoothingFilter(ColorSpaceMode.RGB, this.blurRadius); raster = filterSmoothing.ProcessRaster(raster, worker); //processing (mixing original raster with blured light raster) for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { color = raster[i, j] * this.bloomBlendFactor; raster[i, j] = rOriginal[i, j] + color; } worker.ReportProgress((int)(100f * i / width), DateTime.Now - startTime); } return raster; }
/// <summary> /// Image processing with linear matrix filter. /// </summary> public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; // define radius of filter by X int radiusX = kernel.GetLength(0) / 2; // define radius of filter by Y int radiusY = kernel.GetLength(1) / 2; //define width and height of image int width = rOriginal.Width; int height = rOriginal.Height; //create result raster Raster raster = new Raster(width, height); float r, g, b; byte R,G,B; VectorRgb rgb; int rk, rl; //save time of beginning processing DateTime startTime = DateTime.Now; //processing for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { r = g = b = 0; for (int l = -radiusY; l <= radiusY; l++) for (int k = -radiusX; k <= radiusX; k++) if ((i + k) >= 0 && (i + k) < width && (j + l) < height && (j + l) >= 0) { rgb = rOriginal[i + k, j + l]; rk = k + radiusX; rl = l + radiusY; r += rgb.R * kernel[rk, rl]; g += rgb.G * kernel[rk, rl]; b += rgb.B * kernel[rk, rl]; } R = VectorRgb.ClampByte(r); G = VectorRgb.ClampByte(g); B = VectorRgb.ClampByte(b); raster[i, j] = new VectorRgb(R, G, B); } worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } //fill bound of raster /*for (int i = 0; i < width; i++) { raster[i, 0] = rOriginal[i, 0]; raster[i, height - 1] = rOriginal[i, height - 1]; } for (int j = 0; j < height; j++) { raster[0, j] = rOriginal[0, j]; raster[width - 1, j] = rOriginal[width - 1, j]; }*/ return raster; }
public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); DateTime startTime = DateTime.Now; VectorRgb color; double dbScaler = 50.0f / height; long x, y; //Scip part of method for GrayScale 8-bit images switch (this.method) { #region 1st case 1: { // <nipper> double[] p = new double[256]; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { color = rOriginal[i, j]; p[color.R]++; p[color.G]++; p[color.B]++; } //worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } double maxh = 0; for (y = 0; y < 255; y++) if (maxh < p[y]) maxh = p[y]; threshold *= maxh; int minc = 0; while (minc < 255 && p[minc] <= threshold) minc++; int maxc = 255; while (maxc > 0 && p[maxc] <= threshold) maxc--; if (minc == 0 && maxc == 255) return null; if (minc >= maxc) return null; // calculate LUT byte[] lut = new byte[256]; for (x = 0; x <256; x++) lut[x] = (byte)Math.Max(0,Math.Min(255,(255 * (x - minc) / (maxc - minc)))); // normalize image for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { color = rOriginal[i, j]; raster[i, j] = new VectorRgb(lut[color.R], lut[color.G], lut[color.B]); } worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } break; } #endregion #region 2nd case 2: { // <nipper> double[] pR = new double[256]; double[] pG = new double[256]; double[] pB = new double[256]; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { color = rOriginal[i, j]; pR[color.R]++; pG[color.G]++; pB[color.B]++; } //worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } double maxh = 0; for (y = 0; y < 255; y++) if (maxh < pR[y]) maxh = pR[y]; double threshold2 = threshold * maxh; int minR = 0; while (minR < 255 && pR[minR] <= threshold2) minR++; int maxR = 255; while (maxR > 0 && pR[maxR] <= threshold2) maxR--; maxh = 0; for (y = 0; y < 255; y++) if (maxh < pG[y]) maxh = pG[y]; threshold2 = threshold * maxh; int minG = 0; while (minG < 255 && pG[minG] <= threshold2) minG++; int maxG = 255; while (maxG > 0 && pG[maxG] <= threshold2) maxG--; maxh = 0; for (y = 0; y < 255; y++) if (maxh < pB[y]) maxh = pB[y]; threshold2 = threshold * maxh; int minB = 0; while (minB < 255 && pB[minB] <= threshold2) minB++; int maxB = 255; while (maxB > 0 && pB[maxB] <= threshold2) maxB--; if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255) return null; // calculate LUT byte[] lutR = new byte[256]; byte range = (byte)(maxR - minR); if (range != 0) { for (x = 0; x <256; x++){ lutR[x] = (byte)Math.Max(0,Math.Min(255,(255 * (x - minR) / range))); } } else lutR[minR] = (byte)minR; byte[] lutG = new byte[256]; range = (byte)(maxG - minG); if (range != 0){ for (x = 0; x < 256; x++){ lutG[x] = (byte)Math.Max(0, Math.Min(255, (255 * (x - minG) / range))); } } else lutG[minG] = (byte)minG; byte[] lutB = new byte[256]; range = (byte)(maxB - minB); if (range != 0){ for (x = 0; x < 256; x++){ lutB[x] = (byte)Math.Max(0, Math.Min(255, (255 * (x - minB) / range))); } } else lutB[minB] = (byte)minB; // normalize image for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { color = rOriginal[i, j]; raster[i, j] = new VectorRgb(lutR[color.R], lutG[color.G], lutB[color.B]); } worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } break; } #endregion #region default default: { // <dave> VectorRgb yuvClr; double[] p = new double[256]; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { color = rOriginal[i, j]; p[Cip.Foundations.ColorspaceHelper.RGB2GRAY(color)]++; } //worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } double maxh = 0; for (y = 0; y < 255; y++) if (maxh < p[y]) maxh = p[y]; threshold *= maxh; int minc = 0; while (minc < 255 && p[minc] <= threshold) minc++; int maxc = 255; while (maxc > 0 && p[maxc] <= threshold) maxc--; if (minc == 0 && maxc == 255) return null; if (minc >= maxc) return null; // calculate LUT byte[] lut = new byte[256]; for (x = 0; x <256; x++){ lut[x] = (byte)Math.Max(0, Math.Min(255, (255 * (x - minc) / (maxc - minc)))); } for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { color = rOriginal[i, j]; yuvClr = Cip.Foundations.ColorspaceHelper.RGB2YUV(color); yuvClr.R = lut[yuvClr.R]; color = Cip.Foundations.ColorspaceHelper.YUV2RGB(yuvClr); raster[i, j] = color; } worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } break; } #endregion } return raster; }
/// <summary> /// Convert RGB colorspace to gray level in float. /// </summary> public static float RGB2GRAYF(VectorRgb rgb) { //return (rgb.B * 0.3f + rgb.G * 0.59f + rgb.R * 0.11f) / 255.0f; return (rgb.R * 0.299f + rgb.G * 0.587f + rgb.B * 0.114f) / 255.0f; }
public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; int width = rOriginal.Width; int height = rOriginal.Height; int iIntensity; Raster raster = new Raster(width, height); VectorHsi hsi; DateTime startTime = DateTime.Now; //get array float[] HistogramNormalized = CipTools.GetHistogramNormalized(rOriginal); //calculates raster for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { hsi = rOriginal[i, j].ToVectorHSI(); //intensity component iIntensity = (int)(hsi.I * 255f); hsi.I = HistogramNormalized[iIntensity]; raster[i, j] = new VectorRgb(hsi); } worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } return raster; }
public override Raster ProcessWithoutWorker(Raster rOriginal) { int width = rOriginal.Width; int height = rOriginal.Height; int iIntensity; Raster raster = new Raster(width, height); VectorHsi hsi; //get array float[] HistogramNormalized = CipTools.GetHistogramNormalized(rOriginal); //calculates raster for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { hsi = rOriginal[i, j].ToVectorHSI(); //intensity component iIntensity = (int)(hsi.I * 255f); hsi.I = HistogramNormalized[iIntensity]; raster[i, j] = new VectorRgb(hsi); } } return raster; }
/// <summary> /// /// </summary> /// <param name="rOriginal"></param> /// <returns></returns> public override Raster ProcessWithoutWorker(Raster rOriginal) { int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); CorrectionFunction func; float r, g, b; //definition of used function //delegates is defined as a named methods. switch (mode) { case IntensityCorrectionMode.LightImage: { func = new CorrectionFunction(LightImageCorrection); //INFORMATION: or use anonymous delegate //func = delegate(float value) {return (float)Math.Pow(value, 2.5f);} break; } case IntensityCorrectionMode.DarkImage: { func = new CorrectionFunction(DarkImageCorrection); break; } case IntensityCorrectionMode.SoftImage: { func = new CorrectionFunction(SoftImageCorrection); break; } default: { func = new CorrectionFunction(SoftImageCorrection); break; } } //processing for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { r = func(rOriginal[i, j].R / 255.0f); g = func(rOriginal[i, j].G / 255.0f); b = func(rOriginal[i, j].B / 255.0f); raster[i, j] = new VectorRgb(r, g, b); } } return raster; }
public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); CorrectionFunction func; float r, g, b; DateTime startTime = DateTime.Now; //definition of used function //delegates is defined as a named methods. switch (mode) { case IntensityCorrectionMode.LightImage: { func = new CorrectionFunction(LightImageCorrection); //INFORMATION: or use anonymous delegate //func = delegate(float value) {return (float)Math.Pow(value, 2.5f);} break; } case IntensityCorrectionMode.DarkImage: { func = new CorrectionFunction(DarkImageCorrection); break; } case IntensityCorrectionMode.SoftImage: { func = new CorrectionFunction(SoftImageCorrection); break; } default: { func = new CorrectionFunction(SoftImageCorrection); break; } } //processing for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { r = func(rOriginal[i, j].R / 255.0f); g = func(rOriginal[i, j].G / 255.0f); b = func(rOriginal[i, j].B / 255.0f); raster[i, j] = new VectorRgb(r, g, b); } worker.ReportProgress((int)(100f * j / height), DateTime.Now - startTime); } return raster; }
public override Raster ProcessWithoutWorker(Raster rOriginal) { int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); //processing float c = (100 + contrast) / 100.0f; brightness += 128; byte[] cTable = new byte[256]; for (int i = 0; i < 256; i++) { cTable[i] = (byte)Math.Max(0, Math.Min(255, (int)((i - 128) * c + brightness + 0.5f))); } VectorRgb newcolor = new VectorRgb(); ; Color cl; //image processing for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { newcolor = new VectorRgb(); cl = rOriginal[i, j].ToColor(); newcolor.R = cTable[cl.R]; newcolor.G = cTable[cl.G]; newcolor.B = cTable[cl.B]; raster[i, j] = newcolor; } } return raster; }
/// <summary> /// Convert YUV colorspace to RGB colorspace. /// </summary> public static VectorRgb YUV2RGB(VectorRgb yuv) { int R, G, B; byte Y = yuv.R; int U = yuv.G - 128; int V = yuv.B - 128; R = (int)(Y + 1.403f * V); G = (int)(Y - 0.344f * U - 0.714f * V); B = (int)(Y + 1.770f * U); R = Math.Min(255, Math.Max(0, R)); G = Math.Min(255, Math.Max(0, G)); B = Math.Min(255, Math.Max(0, B)); return new VectorRgb(R, G, B); }
/// <summary> /// Clamping of RGB vector /// </summary> /// <param name="source"> Source vector</param> /// <param name="min">minimum</param> /// <param name="max">maximum</param> /// <returns></returns> public static VectorRgb Clamp(VectorRgb source, byte min, byte max) { VectorRgb result = source; if (result.r < min) result.r = min; if (result.r > max) result.r = max; if (result.g < min) result.g = min; if (result.g > max) result.g = max; if (result.b < min) result.b = min; if (result.b > max) result.b = max; return result; }
/// <summary> /// Convert RGB colorspace to gray level in byte. /// </summary> public static byte RGB2GRAY(VectorRgb rgb) { //return (byte)(rgb.B * 0.3f + rgb.G * 0.59f + rgb.R * 0.11f); return (byte)(rgb.R * 0.299 + rgb.G * 0.587 + rgb.B * 0.114); }
/// <summary> /// Mix of 2 vectors /// </summary> /// <param name="left">Left vector</param> /// <param name="right">Right vector</param> /// <param name="coeff">coefficient</param> /// <returns></returns> public static VectorRgb Mix(VectorRgb left, VectorRgb right, float coeff) { return left * (1.0f - coeff) + right * coeff; }
/// <summary> /// Convert RGB colorspace to gray level in integer. /// </summary> public static int RGB2GRAYI(VectorRgb rgb) { //return (int)(rgb.B * 0.3f + rgb.G * 0.59f + rgb.R * 0.11f); return (int)(rgb.R * 0.299 + rgb.G * 0.587 + rgb.B * 0.114); }
/// <summary> /// Dot of 2 vectors /// </summary> /// <param name="left">Left vector</param> /// <param name="right">Right vector</param> /// <returns>Double dot value</returns> public static float Dot(VectorRgb left, VectorRgb right) { int r = left.r * right.r; // 65025.0f int g = left.g * right.g; int b = left.b * right.b; return (r + g + b) / 65025.0f; }
/// <summary> /// Image processing with linear matrix filter. /// Without backgroundworker. /// </summary> public override Raster ProcessWithoutWorker(Raster rOriginal) { // define radius of filter by X int radiusX = kernel.GetLength(0) / 2; // define radius of filter by Y int radiusY = kernel.GetLength(1) / 2; //define width and height of image int width = rOriginal.Width; int height = rOriginal.Height; //create result raster Raster raster = new Raster(width, height); float r, g, b; byte R, G, B; VectorRgb rgb; int rk, rl; //processing for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { r = g = b = 0; for (int l = -radiusY; l <= radiusY; l++) for (int k = -radiusX; k <= radiusX; k++) if ((i + k) >= 0 && (i + k) < width && (j + l) < height && (j + l) >= 0) { rgb = rOriginal[i + k, j + l]; rk = k + radiusX; rl = l + radiusY; r += rgb.R * kernel[rk, rl]; g += rgb.G * kernel[rk, rl]; b += rgb.B * kernel[rk, rl]; } R = VectorRgb.ClampByte(r); G = VectorRgb.ClampByte(g); B = VectorRgb.ClampByte(b); raster[i, j] = new VectorRgb(R, G, B); } } //fill bound of raster /*for (int i = 0; i < width; i++) { raster[i, 0] = rOriginal[i, 0]; raster[i, height - 1] = rOriginal[i, height - 1]; } for (int j = 0; j < height; j++) { raster[0, j] = rOriginal[0, j]; raster[width - 1, j] = rOriginal[width - 1, j]; }*/ return raster; }
/// <summary> /// Copy Constructor /// </summary> /// <param name="vec">Color vector</param> public VectorRgb(VectorRgb vec) { r = vec.r; g = vec.g; b = vec.b; }
/// <summary> /// Processing resample without Background Worker. /// </summary> /// <param name="rOriginal"></param> /// <returns></returns> public override Raster ProcessWithoutWorker(Raster rOriginal) { if (newx == 0 || newy == 0) return null; if (rOriginal.Width == newx && rOriginal.Height == newy) return new Raster(rOriginal);//copy float xScale, yScale, fX, fY; int widthOriginal = rOriginal.Width; int heightOriginal = rOriginal.Height; xScale = (float)widthOriginal / (float)newx; yScale = (float)heightOriginal / (float)newy; Raster newImage = new Raster(newx, newy); switch (this.mode) { #region nearest pixel case Cip.Transformations.CipInterpolationMode.NearestPixel: { // nearest pixel for (int y = 0; y < newy; y++) { fY = y * yScale; for (int x = 0; x < newx; x++) { fX = x * xScale; newImage[x, y] = rOriginal[(int)fX, (int)fY]; } } break; } #endregion nearest pixel #region bicubic spline interpolation case Cip.Transformations.CipInterpolationMode.BicubicSpline: { // bicubic interpolation by Blake L. Carlson <blake-carlson(at)uiowa(dot)edu float f_x, f_y, a, b, r1, r2; byte rr, gg, bb; int i_x, i_y, xx, yy; VectorRgb rgb; for (int y = 0; y < newy; y++) { f_y = (float)y * yScale - 0.5f; i_y = (int)Math.Floor(f_y); a = f_y - (float)Math.Floor(f_y); for (int x = 0; x < newx; x++) { f_x = (float)x * xScale - 0.5f; i_x = (int)Math.Floor(f_x); b = f_x - (float)Math.Floor(f_x); rr = gg = bb = 0; for (int m = -1; m < 3; m++) { r1 = CipInterpolationFunctions.KernelBSpline((float)m - a); yy = i_y + m; if (yy < 0) yy = 0; if (yy >= rOriginal.Height) yy = rOriginal.Height - 1; for (int n = -1; n < 3; n++) { r2 = r1 * CipInterpolationFunctions.KernelBSpline(b - (float)n); xx = i_x + n; if (xx < 0) xx = 0; if (xx >= rOriginal.Width) xx = rOriginal.Width - 1; rgb = rOriginal[xx, yy]; rr += (byte)(rgb.R * r2); gg += (byte)(rgb.G * r2); bb += (byte)(rgb.B * r2); }//end for n }//end for m newImage[x, y] = new VectorRgb(rr, gg, bb); }//end for x }//end for y break; } #endregion bicubic spline interpolation #region bilinear interpolation case Cip.Transformations.CipInterpolationMode.Bilinear: { // bilinear interpolation double fraction_x, fraction_y, one_minus_x, one_minus_y; int ceil_x, ceil_y, floor_x, floor_y; VectorRgb c1 = new VectorRgb(); VectorRgb c2 = new VectorRgb(); VectorRgb c3 = new VectorRgb(); VectorRgb c4 = new VectorRgb(); byte red, green, blue; byte b1, b2; for (int x = 0; x < newx; ++x) for (int y = 0; y < newy; ++y) { // Setup floor_x = (int)Math.Floor(x * xScale); floor_y = (int)Math.Floor(y * yScale); ceil_x = floor_x + 1; if (ceil_x >= widthOriginal) ceil_x = floor_x; ceil_y = floor_y + 1; if (ceil_y >= heightOriginal) ceil_y = floor_y; fraction_x = x * xScale - floor_x; fraction_y = y * yScale - floor_y; one_minus_x = 1.0f - fraction_x; one_minus_y = 1.0f - fraction_y; c1 = rOriginal[floor_x, floor_y]; c2 = rOriginal[ceil_x, floor_y]; c3 = rOriginal[floor_x, ceil_y]; c4 = rOriginal[ceil_x, ceil_y]; // Blue b1 = (byte)(one_minus_x * c1.B + fraction_x * c2.B); b2 = (byte)(one_minus_x * c3.B + fraction_x * c4.B); blue = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2)); // Green b1 = (byte)(one_minus_x * c1.G + fraction_x * c2.G); b2 = (byte)(one_minus_x * c3.G + fraction_x * c4.G); green = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2)); // Red b1 = (byte)(one_minus_x * c1.R + fraction_x * c2.R); b2 = (byte)(one_minus_x * c3.R + fraction_x * c4.R); red = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2)); newImage[x, y] = new VectorRgb(red, green, blue); } break; } #endregion bilinear interpolation default:// bilinear interpolation { // nearest pixel for (int y = 0; y < newy; y++) { fY = y * yScale; for (int x = 0; x < newx; x++) { fX = x * xScale; newImage[x, y] = rOriginal[(int)fX, (int)fY]; } } break; } }//end switch return newImage; }
public override Raster ProcessWithoutWorker(Raster rOriginal) { int s;//number of pixels in current mask float CurrentIntensity, intensity; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); VectorHsi hsi; int r, g, b; int mDeltaI, pDeltaI, mDeltaJ, pDeltaJ; int delta = (n - 1) / 2; //mode choose if (mode == ColorSpaceMode.RGB) { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { s = r = b = g = 0; mDeltaI = i - delta; pDeltaI = i + delta; mDeltaJ = j - delta; pDeltaJ = j + delta; for (int k = mDeltaI; k <= pDeltaI; k++) { for (int l = mDeltaJ; l <= pDeltaJ; l++) { if (k >= 0 && k < width && l < height && l >= 0) { r += rOriginal[k, l].R; g += rOriginal[k, l].G; b += rOriginal[k, l].B; s++; } } } raster[i, j] = new VectorRgb((byte)(r / s), (byte)(g / s), (byte)(b / s)); } } } else//if HSI mode { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { CurrentIntensity = 0; s = 0;//number of pixels in current mask mDeltaI = i - delta; pDeltaI = i + delta; mDeltaJ = j - delta; pDeltaJ = j + delta; for (int k = mDeltaI; k <= pDeltaI; k++) { for (int l = mDeltaJ; l <= pDeltaJ; l++) { if (k >= 0 && k < width && l < height && l >= 0) { CurrentIntensity += rOriginal[k, l].ToVectorHSI().I; s++; } } } intensity = CurrentIntensity / s; hsi = rOriginal[i, j].ToVectorHSI(); hsi.I = intensity; raster[i, j] = hsi.ToVectorRGB(); } } } return raster; }
/// <summary> /// Processing without background worker. /// </summary> public override Raster ProcessWithoutWorker(Raster rOriginal) { int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); byte threshold = (byte)(this.lightThreshold * 255); VectorRgb color; //bright pass for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { color = rOriginal[i, j]; if (color.R > threshold || color.G > threshold || color.B > threshold) raster[i, j] = color; else raster[i, j] = new VectorRgb(0, 0, 0); } } //blur SmoothingFilter filterSmoothing = new SmoothingFilter(ColorSpaceMode.RGB, this.blurRadius); raster = filterSmoothing.ProcessWithoutWorker(raster); //processing (mixing original raster with blured light raster) for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { color = raster[i, j] * this.bloomBlendFactor; raster[i, j] = rOriginal[i, j] + color; } } return raster; }
public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; byte r, g, b; VectorRgb c; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); DateTime startTime = DateTime.Now; //processing for (int i = 0; i < width; i++) { //moving by columns for (int j = 0; j < height; j++) { r = g = b = 255; for (int k = i - (n - 1) / 2; k <= i + (n - 1) / 2; k++) { for (int l = j - (n - 1) / 2; l <= j + (n - 1) / 2; l++) { if (k >= 0 && k < width && l < height && l >= 0) { c = rOriginal[k, l]; if (c.R < r) r = c.R; if (c.G < g) g = c.G; if (c.B < b) b = c.B; } } } raster[i, j] = new VectorRgb(r, g, b); } worker.ReportProgress((int)(100f * i / width), DateTime.Now - startTime); } return raster; }
public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; int s;//number of pixels in current mask float CurrentIntensity, intensity; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); VectorHsi hsi; int r, g, b; int mDeltaI, pDeltaI, mDeltaJ, pDeltaJ; DateTime startTime = DateTime.Now; int delta = (n - 1) / 2; //mode choose if (mode == ColorSpaceMode.RGB) { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { s = r = b = g = 0; mDeltaI = i - delta; pDeltaI = i + delta; mDeltaJ = j - delta; pDeltaJ = j + delta; for (int k = mDeltaI; k <= pDeltaI; k++) { for (int l = mDeltaJ; l <= pDeltaJ; l++) { if (k >= 0 && k < width && l < height && l >= 0) { r += rOriginal[k, l].R; g += rOriginal[k, l].G; b += rOriginal[k, l].B; s++; } } } raster[i, j] = new VectorRgb((byte)(r / s), (byte)(g / s), (byte)(b / s)); } worker.ReportProgress((int)(100f * i / width), DateTime.Now - startTime); } } else//if HSI mode { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { CurrentIntensity = 0; s = 0;//number of pixels in current mask mDeltaI = i - delta; pDeltaI = i + delta; mDeltaJ = j - delta; pDeltaJ = j + delta; for (int k = mDeltaI; k <= pDeltaI; k++) { for (int l = mDeltaJ; l <= pDeltaJ; l++) { if (k >= 0 && k < width && l < height && l >= 0) { CurrentIntensity += rOriginal[k, l].ToVectorHSI().I; s++; } } } intensity = CurrentIntensity / s; hsi = rOriginal[i, j].ToVectorHSI(); hsi.I = intensity; raster[i, j] = hsi.ToVectorRGB(); } worker.ReportProgress((int)(100f * i / width), DateTime.Now - startTime); } } return raster; }
public override Raster ProcessRaster(Raster rOriginal, System.ComponentModel.BackgroundWorker worker) { worker.WorkerReportsProgress = true; int width = rOriginal.Width; int height = rOriginal.Height; Raster raster = new Raster(width, height); float lapR, lapG, lapB; byte bLapR, bLapG, bLapB; float dLaplasian; VectorHsi hsi; VectorRgb rgb; DateTime startTime = DateTime.Now; #region Function construction // mask function float[,] f = new float[3, 3]; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) f[i, j] = 1.0f; //diag check if (diag == true) f[1, 1] = -8.0f; else { f[0, 0] = f[0, 2] = f[2, 0] = f[2, 2] = 0.0f; f[1, 1] = -4.0f; } //negative check if (negative == true) { for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) f[i, j] = f[i, j] * (-1); }//else nothing to do #endregion if (mode == ColorSpaceMode.RGB) { //Process for (int k = 1; k < width - 1; k++) { for (int l = 1; l < height - 1; l++) { //laplasian lapR = f[0, 0] * rOriginal[k - 1, l + 1].R + f[0, 1] * rOriginal[k, l + 1].R + f[0, 2] * rOriginal[k + 1, l + 1].R + f[1, 0] * rOriginal[k - 1, l].R + f[1, 1] * rOriginal[k, l].R + f[1, 2] * rOriginal[k + 1, l].R + f[2, 0] * rOriginal[k - 1, l - 1].R + f[2, 1] * rOriginal[k, l - 1].R + f[2, 2] * rOriginal[k + 1, l - 1].R; lapG = f[0, 0] * rOriginal[k - 1, l + 1].G + f[0, 1] * rOriginal[k, l + 1].G + f[0, 2] * rOriginal[k + 1, l + 1].G + f[1, 0] * rOriginal[k - 1, l].G + f[1, 1] * rOriginal[k, l].G + f[1, 2] * rOriginal[k + 1, l].G + f[2, 0] * rOriginal[k - 1, l - 1].G + f[2, 1] * rOriginal[k, l - 1].G + f[2, 2] * rOriginal[k + 1, l - 1].G; lapB = f[0, 0] * rOriginal[k - 1, l + 1].B + f[0, 1] * rOriginal[k, l + 1].B + f[0, 2] * rOriginal[k + 1, l + 1].B + f[1, 0] * rOriginal[k - 1, l].B + f[1, 1] * rOriginal[k, l].B + f[1, 2] * rOriginal[k + 1, l].B + f[2, 0] * rOriginal[k - 1, l - 1].B + f[2, 1] * rOriginal[k, l - 1].B + f[2, 2] * rOriginal[k + 1, l - 1].B; bLapR = VectorRgb.ClampByte(lapR); bLapG = VectorRgb.ClampByte(lapG); bLapB = VectorRgb.ClampByte(lapB); rgb = new VectorRgb(bLapR, bLapB, bLapG); if (f[1, 1] < 0) raster[k, l] = rOriginal[k, l] - rgb; else raster[k, l] = rOriginal[k, l] + rgb; } worker.ReportProgress((int)(100f * k / (width - 1)), DateTime.Now - startTime); } } else//HSI mode { //Process for (int k = 1; k < width - 1; k++) { for (int l = 1; l < height - 1; l++) { hsi = rOriginal[k, l].ToVectorHSI(); //laplasian dLaplasian = f[0, 0] * rOriginal[k - 1, l + 1].ToVectorHSI().I + f[0, 1] * rOriginal[k, l + 1].ToVectorHSI().I + f[0, 2] * rOriginal[k + 1, l + 1].ToVectorHSI().I + f[1, 0] * rOriginal[k - 1, l].ToVectorHSI().I + f[1, 1] * rOriginal[k, l].ToVectorHSI().I + f[1, 2] * rOriginal[k + 1, l].ToVectorHSI().I + f[2, 0] * rOriginal[k - 1, l - 1].ToVectorHSI().I + f[2, 1] * rOriginal[k, l - 1].ToVectorHSI().I + f[2, 2] * rOriginal[k + 1, l - 1].ToVectorHSI().I; if (f[1, 1] < 0) hsi.I = hsi.I - dLaplasian; else hsi.I = hsi.I + dLaplasian; raster[k, l] = VectorHsi.Clamp(hsi, 0.0f, 1.0f).ToVectorRGB(); } worker.ReportProgress((int)(100f * k / (width - 1)), DateTime.Now - startTime); } } //fill bound of raster for (int i = 0; i < width; i++) { raster[i, 0] = rOriginal[i, 0]; raster[i, height - 1] = rOriginal[i, height - 1]; } for (int j = 0; j < height; j++) { raster[0, j] = rOriginal[0, j]; raster[width - 1, j] = rOriginal[width - 1, j]; } return raster; }