/// <summary> /// Converts 8-bit Hsv color to the 8-bit Bgr color. /// </summary> public unsafe Bgr8 ToBgr() { Hsv8 hsv = this; Bgr8 bgr; ConvertHsvToBgr(&hsv, &bgr); return(bgr); }
private static unsafe void convertBgrToHsv_Byte(Bgr8* bgr, Hsv8* hsv) { byte rgbMin, rgbMax; rgbMin = bgr->R < bgr->G ? (bgr->R < bgr->B ? bgr->R : bgr->B) : (bgr->G < bgr->B ? bgr->G : bgr->B); rgbMax = bgr->R > bgr->G ? (bgr->R > bgr->B ? bgr->R : bgr->B) : (bgr->G > bgr->B ? bgr->G : bgr->B); hsv->V = rgbMax; if (hsv->V == 0) { hsv->H = 0; hsv->S = 0; return; } hsv->S = (byte)(255 * (rgbMax - rgbMin) / rgbMax); if (hsv->S == 0) { hsv->H = 0; return; } int hue = 0; if (rgbMax == bgr->R) { hue = 0 + 60 * (bgr->G - bgr->B) / (rgbMax - rgbMin); if (hue < 0) hue += 360; } else if (rgbMax == bgr->G) { hue = 120 + 60 * (bgr->B - bgr->R) / (rgbMax - rgbMin); } else //rgbMax == bgr->B { hue = 240 + 60 * (bgr->R - bgr->G) / (rgbMax - rgbMin); } hsv->H = (byte)(hue / 2); //scale [0-360] -> [0-180] (only needed for byte!) Debug.Assert(hue >= 0 && hue <= 360); }
/// <summary> /// Draws lines in various colors regarding their angle. /// </summary> /// <param name="image">Input image.</param> /// <param name="lines">Line segments (treated as vectors)</param> /// <param name="thickness">Line thickness.</param> public static void Draw <TColor>(this Image <TColor, byte> image, IEnumerable <LineSegment> lines, float thickness) where TColor : IColor3 { Func <LineSegment, Bgr> colorFunc = (segment) => { /************** calculate angle ************/ var diff = segment.End - segment.Start; var angle = System.Math.Atan2(diff.Y, diff.X); angle = angle * 180 / System.Math.PI; //to degrees angle = (angle < 0) ? angle + 360 : angle; /************** calculate angle ************/ Hsv8 hsv = new Hsv8 { H = (byte)(angle / 2), S = Byte.MaxValue / 2, V = Byte.MaxValue / 2 }; return(hsv.ToBgr()); }; Draw(image, lines, thickness, colorFunc); }
public static unsafe void ConvertHsvToBgr(Hsv8* hsv, Bgr8* bgr) { if (hsv->S == 0) { bgr->R = hsv->V; bgr->G = hsv->V; bgr->B = hsv->V; return; } int hue = hsv->H * 2; //move to [0-360 range] (only needed for byte!) int hQuadrant = hue / 60; // Hue quadrant 0 - 5 (60deg) int hOffset = hue % 60; // Hue position in quadrant int vs = hsv->V * hsv->S; byte p = (byte)(hsv->V - (vs / 255)); byte q = (byte)(hsv->V - (vs / 255 * hOffset) / 60); byte t = (byte)(hsv->V - (vs / 255 * (60 - hOffset)) / 60); switch (hQuadrant) { case 0: bgr->R = hsv->V; bgr->G = t; bgr->B = p; break; case 1: bgr->R = q; bgr->G = hsv->V; bgr->B = p; break; case 2: bgr->R = p; bgr->G = hsv->V; bgr->B = t; break; case 3: bgr->R = p; bgr->G = q; bgr->B = hsv->V; break; case 4: bgr->R = t; bgr->G = p; bgr->B = hsv->V; break; default: bgr->R = hsv->V; bgr->G = p; bgr->B = q; break; } }