예제 #1
0
        /// <summary>
        /// Convert from HSV to RGB color space.
        /// </summary>
        ///
        /// <param name="hsl">Source color in <b>HSV</b> color space.</param>
        /// <param name="rgb">Destination color in <b>RGB</b> color space.</param>
        ///
        public static void ToRGB(HSV hsv, RGB rgb)
        {
            double rr = 0.0, gg = 0.0, bb = 0.0;
            double hh, ss, vv;
            double SCALE  = 255.0;
            double hSCALE = 256.0;
            double GETA   = 2.0;
            double hGETA  = 2.0;

            if (hsv.Hue == 6 * hGETA * (hSCALE))
            {
                hsv.Hue = 0;
            }
            hh = (double)hsv.Hue / hGETA;
            ss = (double)hsv.Saturation / GETA;
            vv = (double)hsv.Value / GETA;

            switch ((int)(hh / hSCALE))
            {
            case 0:
                rr = 1.0 * SCALE;
                gg = hh;
                bb = 0.0;
                break;

            case 1:
                rr = 2.0 * hSCALE - hh;
                gg = 1.0 * SCALE;
                bb = 0.0;
                break;

            case 2:
                rr = 0.0;
                gg = 1.0 * SCALE;
                bb = hh - 2.0 * hSCALE;
                break;

            case 3:
                rr = 0.0;
                gg = 4.0 * hSCALE - hh;
                bb = 1.0 * SCALE;
                break;

            case 4:
                rr = hh - 4.0 * hSCALE;
                gg = 0.0;
                bb = 1.0 * SCALE;
                break;

            case 5:
                rr = 1.0 * SCALE;
                gg = 0.0;
                bb = 6.0 * hSCALE - hh;
                break;
            }

            rr = (rr + (1.0 * SCALE - rr) * (1.0 * SCALE - ss) / (SCALE)) * vv / SCALE;
            gg = (gg + (1.0 * SCALE - gg) * (1.0 * SCALE - ss) / (SCALE)) * vv / SCALE;
            bb = (bb + (1.0 * SCALE - bb) * (1.0 * SCALE - ss) / (SCALE)) * vv / SCALE;

            if (rr < 0)
            {
                rgb.Red = 0;
            }
            else if (rr > 255)
            {
                rgb.Red = 255;
            }
            else
            {
                rgb.Red = (byte)rr;
            }

            if (gg < 0)
            {
                rgb.Green = 0;
            }
            else if (gg > 255)
            {
                rgb.Green = 255;
            }
            else
            {
                rgb.Green = (byte)gg;
            }

            if (bb < 0)
            {
                rgb.Blue = 0;
            }
            else if (bb > 255)
            {
                rgb.Blue = 255;
            }
            else
            {
                rgb.Blue = (byte)bb;
            }
        }
예제 #2
0
        /// <summary>
        /// Selection based on pixel similarity in HSV color space
        /// </summary>
        public static unsafe Bitmap Similiar_HSV(Bitmap image, Rectangle rect, List <HSV> hsvs, int similarity)
        {
            Bitmap dest = (Bitmap)image.Clone();

            if (hsvs.Count == 0)
            {
                return(dest);
            }

            BitmapData srcDat = image.LockBits(rect, ImageLockMode.ReadOnly, image.PixelFormat);
            BitmapData dstDat = dest.LockBits(rect, ImageLockMode.ReadWrite, dest.PixelFormat);

            int width  = rect.Width;
            int height = rect.Height;
            int stride = srcDat.Stride;

            // get pixel size
            int pixelSize = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;

            int offset = stride - width * pixelSize;

            // do the job
            byte *src = (byte *)srcDat.Scan0.ToPointer();
            byte *dst = (byte *)dstDat.Scan0.ToPointer();

            //H = 0 ~ 3066
            //S = 0 ~ 511
            //V = 0 ~ 511
            const int HSV_num = 3067 + 512 + 512;

            int[] table_mix = new int[HSV_num];
            for (int i = 0; i < HSV_num; i++)
            {
                table_mix[i] = -1;
            }

            int total_l;

            foreach (HSV hsv in hsvs)
            {
                total_l = hsv.Hue + hsv.Saturation + hsv.Value;

                for (int i = 0; i < similarity / 2; i++)
                {
                    if ((total_l + i) < HSV_num)
                    {
                        table_mix[total_l + i] = 1;
                    }
                    if ((total_l - i) >= 0)
                    {
                        table_mix[total_l - i] = 1;
                    }
                }
            }

            int koba;

            // for each row
            for (int y = 0; y < height; y++)
            {
                // for each pixel
                for (int x = 0; x < width; x++, src += pixelSize, dst += pixelSize)
                {
                    HSV hsv = HSV.FromRGB(new RGB(src[RGB.R], src[RGB.G], src[RGB.B]));
                    koba = hsv.Hue + hsv.Saturation + hsv.Value;

                    if (table_mix[koba] == 1)
                    {
                        dst[RGB.R] = dst[RGB.G] = dst[RGB.B] = 0;
                    }
                    else
                    {
                        dst[RGB.R] = dst[RGB.G] = dst[RGB.B] = 255;
                    }
                }
                src += offset;
                dst += offset;
            }

            image.UnlockBits(srcDat);
            dest.UnlockBits(dstDat);

            return(dest);
        }
예제 #3
0
        /// <summary>
        /// Convert from RGB to HSV color space.
        /// </summary>
        ///
        /// <param name="rgb">Source color in <b>RGB</b> color space.</param>
        /// <param name="hsl">Destination color in <b>HSV</b> color space.</param>
        ///
        /// <remarks><para>See <a href="http://en.wikipedia.org/wiki/HSI_color_space#Conversion_from_RGB_to_HSV_or_HSV">HSV and HSV Wiki</a>
        /// for information about the algorithm to convert from RGB to HSV.</para></remarks>
        ///
        public static void FromRGB(RGB rgb, HSV hsv)
        {
            double rr, gg, bb;
            double hh, ss, vv;
            double cmax, cmin, cdes;
            double SCALE  = 255.0;
            double hSCALE = 256.0;
            double GETA   = 2.0;
            double hGETA  = 2.0;

            rr = (double)rgb.Red;
            gg = (double)rgb.Green;
            bb = (double)rgb.Blue;

            cmax = gg;
            if (rr > cmax)
            {
                cmax = rr;
            }
            if (bb > cmax)
            {
                cmax = bb;
            }

            cmin = gg;
            if (rr < cmin)
            {
                cmin = rr;
            }
            if (bb < cmin)
            {
                cmin = bb;
            }

            cdes = cmax - cmin;
            vv   = cmax;

            hh = 0.0;
            if (cdes != 0.0)
            {
                ss = cdes * SCALE / cmax;
                if (cmax == rr)
                {
                    hh = (gg - bb) * SCALE / cdes;
                }
                if (cmax == gg)
                {
                    hh = (bb - rr) * SCALE / cdes + 2.0 * hSCALE;
                }
                if (cmax == bb)
                {
                    hh = (rr - gg) * SCALE / cdes + 4.0 * hSCALE;
                }
            }
            else if (cdes != 0.0)
            {
                ss = cdes * SCALE / cmax;
                hh = 0.0;
            }
            else
            {
                ss = 0.0;
                hh = 0.0;
            }
            if (hh < 0.0)
            {
                hh += 6.0 * hSCALE;
            }

            hsv.Hue        = (int)(hh * hGETA);
            hsv.Saturation = (int)(ss * GETA);
            hsv.Value      = (int)(vv * GETA);
        }
예제 #4
0
        /// <summary>
        /// Stretch HSV histogram to create new image
        /// </summary>
        public static unsafe Bitmap HistogramStretchHSV(Bitmap image, Rectangle rect)
        {
            Bitmap     dest   = (Bitmap)image.Clone();
            BitmapData srcDat = image.LockBits(rect, ImageLockMode.ReadOnly, image.PixelFormat);
            BitmapData dstDat = dest.LockBits(rect, ImageLockMode.ReadWrite, dest.PixelFormat);

            int width  = rect.Width;
            int height = rect.Height;
            int stride = srcDat.Stride;

            // get pixel size
            int pixelSize = (image.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;

            int offset = stride - width * pixelSize;

            // do the job
            byte *src = (byte *)srcDat.Scan0.ToPointer();
            byte *dst = (byte *)dstDat.Scan0.ToPointer();

            int pix_num = width * height;           //縦×横

            int[] num_b = new int[512];
            int   min_per, max_per;
            int   per1  = pix_num / 100;
            int   per99 = pix_num / 100 * 99;

            int[] aryH = new int[pix_num];
            int[] aryS = new int[pix_num];
            int[] aryV = new int[pix_num];
            int   maxH, maxS, maxV;
            int   minV;

            maxH = maxS = maxV = 0;
            minV = 255;

            int    tmp_pix, last_pix;
            double ratio;
            int    pos;
            int    count_i = 0;
            int    sum     = 0;

            RGB rgb = new RGB();
            HSV hsv = new HSV();

            // RGB histograms
            // for each row
            for (int y = 0; y < height; y++)
            {
                // for each pixel
                for (int x = 0; x < width; x++, src += pixelSize)
                {
                    rgb.Red   = src[RGB.R];
                    rgb.Green = src[RGB.G];
                    rgb.Blue  = src[RGB.B];
                    hsv       = HSV.FromRGB(rgb);

                    pos       = y * width + x;
                    aryH[pos] = hsv.Hue;
                    aryS[pos] = hsv.Saturation;
                    aryV[pos] = hsv.Value;

                    if (hsv.Hue > maxH)
                    {
                        maxH = hsv.Hue;
                    }
                    if (hsv.Saturation > maxS)
                    {
                        maxS = hsv.Saturation;
                    }
                    if (hsv.Value > maxV)
                    {
                        maxV = hsv.Value;
                    }
                    if (hsv.Value < minV)
                    {
                        minV = hsv.Value;
                    }
                }
                src += offset;
            }

            // histogram
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++, src += pixelSize)
                {
                    num_b[aryV[y * width + x]]++;
                }
            }

            do
            {
                sum += num_b[count_i++];
            } while (sum < per1);
            min_per = count_i - 1;

            do
            {
                sum += num_b[count_i++];
            } while (sum < per99);
            max_per = count_i - 1;
            ratio   = (double)(511.0 / (max_per - min_per));

            // stretch histogram
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++, src += pixelSize)
                {
                    pos     = y * width + x;
                    tmp_pix = aryV[pos];

                    if (tmp_pix <= min_per)
                    {
                        last_pix = 0;
                    }
                    else if (tmp_pix >= max_per)
                    {
                        last_pix = 511;
                    }
                    else
                    {
                        last_pix = (int)((tmp_pix - min_per) * ratio);
                    }

                    if (last_pix < 0)
                    {
                        aryV[pos] = 0;
                    }
                    else if (last_pix >= 511)
                    {
                        aryV[pos] = 511;
                    }
                    else
                    {
                        aryV[pos] = last_pix;
                    }
                }
            }

            // for each row
            for (int y = 0; y < height; y++)
            {
                // for each pixel
                for (int x = 0; x < width; x++, src += pixelSize, dst += pixelSize)
                {
                    pos            = y * width + x;
                    hsv.Hue        = aryH[pos];
                    hsv.Saturation = aryS[pos];
                    hsv.Value      = aryV[pos];

                    HSV.ToRGB(hsv, rgb);

                    dst[RGB.R] = rgb.Red;
                    dst[RGB.G] = rgb.Green;
                    dst[RGB.B] = rgb.Blue;
                }
                src += offset;
                dst += offset;
            }

            image.UnlockBits(srcDat);
            dest.UnlockBits(dstDat);

            return(dest);
        }