/// <summary> /// Get the histogram of a specific area of the image. /// The histogram is separate for each color channel /// </summary> /// <param name="image"></param> /// <param name="Min"></param> /// <param name="Max"></param> /// <param name="lines"></param> /// <returns></returns> public static void NormalizeImage(FxImages image) { FxVector<float>[] hist = new FxVectorF[image.FXPixelFormat.Length]; for (int i = 0; i < image.FXPixelFormat.Length; i++) { hist[i] = new FxVectorF(256, 0); } // get the size of the image int ImWidth = image.Image.Width; int ImHeight = image.Image.Height; // lock the input memory image.LockImage(); byte[] max = new byte[image.FXPixelFormat.Length]; byte[] min = new byte[image.FXPixelFormat.Length]; for (int g = 0; g < image.FXPixelFormat.Length; g++) { max[g] = Byte.MinValue; min[g] = Byte.MaxValue; } // find max min for (int i = 0; i < ImWidth; i++) { for (int j = 0; j < ImHeight; j++) { for (int g = 0; g < image.FXPixelFormat.Length; g++) { if (min[g] > image[i, j, (RGB)g]) min[g] = image[i, j, (RGB)g]; if (max[g] < image[i, j, (RGB)g]) max[g] = image[i, j, (RGB)g]; } } } // normalize image for (int i = 0; i < ImWidth; i++) { for (int j = 0; j < ImHeight; j++) { for (int g = 0; g < image.FXPixelFormat.Length; g++) { image[i, j, (RGB)g] = (byte)((float)(image[i, j, (RGB)g] - min[g]) / (float)(max[g] - min[g])); } } } // unlock the input and output image image.UnLockImage(); }
/// <summary> /// Supplicant the input image in the specific position /// and for the colors and store the results in the outImage /// </summary> /// <param name="image"></param> /// <param name="xf"></param> /// <param name="yf"></param> /// <param name="color"></param> /// <returns></returns> public static void Bilinear(FxImages InImage, float x_In, float y_In, FxImages OutImage, int x_Out, int y_Out) { // get the integer part of the position int x = (int)Math.Floor(x_In); int y = (int)Math.Floor(y_In); // get the ratio part double x_ratio = x_In - x; double y_ratio = y_In - y; // the inverse ratio double x_opposite = 1 - x_ratio; double y_opposite = 1 - y_ratio; double result = 0; foreach (RGB i in InImage.FXPixelFormat) { result = 0; // interpolate on x if (y_opposite > 0) { if (x_opposite > 0) result += InImage[x, y, i] * x_opposite * y_opposite; if (x_ratio > 0) result += InImage[x + 1, y, i] * x_ratio * y_opposite; } // interpolate on y if (y_ratio > 0) { if (x_opposite > 0) result += InImage[x, y + 1, i] * x_opposite * y_ratio; if (x_ratio > 0) result += InImage[x + 1, y + 1, i] * x_ratio * y_ratio; } // store the result OutImage[x_Out, y_Out, i] = (byte)result; } }
/// <summary> /// interpolate the input image in the specific position /// and specific color, return byte /// </summary> /// <param name="image"></param> /// <param name="xf"></param> /// <param name="yf"></param> /// <param name="color"></param> /// <returns></returns> public static byte Bilinear(FxImages image, float xf, float yf, RGB color) { if (yf + 1>= image.Image.Height) yf = image.Image.Height - 2; if (xf + 1 >= image.Image.Width) xf = image.Image.Width - 2; // get the integer part of the position int x = (int)Math.Floor(xf); int y = (int)Math.Floor(yf); // get the ratio part double x_ratio = xf - x; double y_ratio = yf - y; // the inverse ratio double x_opposite = 1 - x_ratio; double y_opposite = 1 - y_ratio; byte result = 0; // interpolate on x if (y_opposite > 0) { if (x_opposite > 0) result += (byte)(image[x, y, color] * x_opposite * y_opposite); if (x_ratio > 0) result += (byte)(image[x + 1, y, color] * x_ratio * y_opposite); } // interpolate on y if (y_ratio > 0) { if (x_opposite > 0) result += (byte)(image[x, y + 1, color] * x_opposite * y_ratio); if (x_ratio > 0) result += (byte)(image[x + 1, y + 1, color] * x_ratio * y_ratio); } return result; }
public ImageElement(FxImages image) { InitToolStrips(); // set the position and the size of the element Position = new Vector.FxVector2f(0); Size = new Vector.FxVector2f(image.Image.Width, image.Image.Height); // set the size of the image Width = image.Image.Width; Height = image.Image.Height; // allocate the memory for the internal image internalImage = new byte[Width * Height * 4]; Pitch = Width * 4; image.LockImage(); image.Copy_to_Array(ref internalImage, ColorChannels.RGBA); image.UnLockImage(); }
/// <summary> /// Get the histogram of a specific area of the image. /// The histogram is separate for each color channel /// </summary> /// <param name="image"></param> /// <param name="Min"></param> /// <param name="Max"></param> /// <param name="lines"></param> /// <returns></returns> public static FxVector<float>[] GetHistogram(FxImages image, FxVector2i Min, FxVector2i Max) { FxVector<float>[] hist = new FxVectorF[image.FXPixelFormat.Length]; for (int i = 0; i < image.FXPixelFormat.Length; i++) { hist[i] = new FxVectorF(256,0); } int pixelCount = 0; // lock the input memory //image.LockImage(); for (int i = Min.X; i < Max.X; i++) { for (int j = Min.Y; j < Max.Y; j++) { for (int g = 0; g < image.FXPixelFormat.Length; g++) { hist[g][image[i, j, (RGB)g]]++; } // count the pixels pixelCount++; } } // unlock the input and output image //image.UnLockImage(); // normalize the image for (int i = 0; i < image.FXPixelFormat.Length; i++) { hist[i].Divide(pixelCount); } return hist; }
public void UpdateInternalImage(FxImages image) { int size = Width * Height; image.LockImage(); image.Copy_to_Array(ref internalImage, ColorChannels.RGBA); image.UnLockImage(); // write to the specific bitmap not create a new one mImageBitmap.CopyFromMemory(internalImage, Pitch); }
/// <summary> /// Get the histogram of the image. /// The histogram is separate for each color channel /// </summary> /// <param name="image"></param> /// <param name="lanes"></param> /// <returns></returns> public static FxVector<float>[] GetHistogram(FxImages image) { return GetHistogram(image, new FxVector2i(0, 0), new FxVector2i(image.Image.Width, image.Image.Height)); }
private static void ColorSpaceConverter_FromRGB_ToHSV(FxImages image) { // base on http://en.wikipedia.org/wiki/HSL_and_HSV // get the size of the image int ImWidth = image.Image.Width; int ImHeight = image.Image.Height; // lock the input memory image.LockImage(); // temp variables double R, G, B, H, S, V, C, min, MAX; for (int i = 0; i < ImWidth; i++) { for (int j = 0; j < ImHeight; j++) { // set the local RGB R = image[i, j, RGB.R]; G = image[i, j, RGB.G]; B = image[i, j, RGB.B]; // find the min and max colors min = Math.Min(Math.Min(R, G), B); MAX = Math.Max(Math.Max(R, G), B); // find the diff C = MAX - min; // set the V V = MAX; // check if the max is zero if (V == 0) { S = 0; H = 0; } else { // calc the S S = 255 * C / V; // check if S is zero if (S == 0) { H = 0; } else { // calc the H if (MAX == R) { H = 42.5 * (((G - B) / C) % 6); } else if (MAX == G) { H = 42.5 * ((B - R) / C + 2); } else /* MAX == B */ { H = 42.5 * ((R - G) / C + 4); } } } // store the result image[i, j, RGB.R] = (byte)H; image[i, j, RGB.G] = (byte)S; image[i, j, RGB.B] = (byte)V; } } // unlock the input and output image image.UnLockImage(); }
private static void ColorSpaceConverter_FromHSV_ToRGB(FxImages image) { // base on http://en.wikipedia.org/wiki/HSL_and_HSV // get the size of the image int ImWidth = image.Image.Width; int ImHeight = image.Image.Height; // lock the input memory image.LockImage(); // temp variables double R, G, B, H, S, V, C, X,diff; for (int i = 0; i < ImWidth; i++) { for (int j = 0; j < ImHeight; j++) { // set the local RGB H = image[i, j, RGB.R]; S = image[i, j, RGB.G] / 255.0; V = image[i, j, RGB.B] / 255.0; // find the chroma C = V * S; // find H' H = H / 42.5; X = C * (1 - Math.Abs(H % 2 - 1)); // calc the diff between V and C diff = V - C; if (H < 1) { R = C + diff; G = X + diff; B = diff; } else if (H < 2) { R = X + diff; G = C + diff; B = diff; } else if (H < 3) { R = diff; G = C + diff; B = X + diff; } else if (H < 4) { R = diff; G = X + diff; B = C + diff; } else if (H < 5) { R = X + diff; G = diff; B = C + diff; } else if (H < 6) { R = C + diff; G = diff; B = X + diff; } else { R = diff; G = diff; B = diff; } // store the result image[i, j, RGB.R] = (byte)(R * 255.0); image[i, j, RGB.G] = (byte)(G * 255.0); image[i, j, RGB.B] = (byte)(B * 255.0); } } // unlock the input and output image image.UnLockImage(); }
/// <summary> /// Convert input Image to other ColorSpace /// </summary> /// <param name="image"></param> /// <param name="from"></param> /// <param name="to"></param> public static void ColorSpaceConverter(FxImages image, ColorSpace from, ColorSpace to) { switch (from) { case ColorSpace.RGB: switch (to) { case ColorSpace.HSV: ColorSpaceConverter_FromRGB_ToHSV(image); break; } break; case ColorSpace.HSV: switch (to) { case ColorSpace.RGB: ColorSpaceConverter_FromHSV_ToRGB(image); break; } break; } }