Win8 Metro(C#)数字图像处理--4图像颜色空间描述

简介: 原文:Win8 Metro(C#)数字图像处理--4图像颜色空间描述  图像颜色空间是图像颜色集合的数学表示,本小节将针对几种常见颜色空间做个简单介绍。
原文: Win8 Metro(C#)数字图像处理--4图像颜色空间描述



图像颜色空间是图像颜色集合的数学表示,本小节将针对几种常见颜色空间做个简单介绍。


       /// <summary>
        /// Get rgba value from source image.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <returns></returns>
        public static byte[] RGBValue(WriteableBitmap src)
        {
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                byte[] rgbaValue = new byte[w * h * 3];
                WriteableBitmap srcImage = new WriteableBitmap(w, h);
                byte[] temp = src.PixelBuffer.ToArray();
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        rgbaValue[x * 3 + y * w * 3] = (byte)temp[x * 4 + y * w * 4];
                        rgbaValue[x * 3 + 1 + y * w * 3] = (byte)temp[x * 4 + 1 + y * w * 4];
                        rgbaValue[x * 3 + 2 + y * w * 3] = (byte)temp[x * 4 + 2 + y * w * 4];
                    }
                }            
                Stream sTemp = srcImage.PixelBuffer.AsStream();
                sTemp.Seek(0, SeekOrigin.Begin);
                sTemp.Write(temp, 0, w * 4 * h);
                return rgbaValue;
            }
            else
            {
                return null;
            }
        }

4.2 XYZ颜色空间

[空间解析]

XYZ颜色空间:国际照明委员会(CIE)在进行了大量正常人视觉测量和统计,1931年建立了标准色度观察者, 从而奠定了现代CIE标准色度学的定量基础。由于"标准色度观察者"用来标定光谱色时出现负 刺激值,计算不便,也不易理解,因此1931CIERGB系统基础上,改用三个假想的原色XY、 Z建立了一个新的色度系统。将它匹配等能光谱的三刺激值,定名为"CIE1931 标准色度观察者 光谱三刺激值",简称为"CIE1931标准色度观察者"。这一系统叫做"CIE1931标准色度系统"或称为2视场XYZ色度系统"其中Y表示亮度,XY反映颜色的色度特性,色度图如下所示。

        /// <summary>
        /// Get XYZ value from source image.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <returns></returns>
        public static double[] XYZValue(WriteableBitmap src)
        {
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                double[] xyzValue = new double[w * h * 3];
                WriteableBitmap srcImage = new WriteableBitmap(w, h);
                byte[] temp = src.PixelBuffer.ToArray();
                int r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = temp[x * 4 + y * w * 4];
                        g = temp[x * 4 + 1 + y * w * 4];
                        r = temp[x * 4 + 2 + y * w * 4];
                        xyzValue[x * 3 + y * w * 3] = (double)(0.5767309 * (double)r + 0.1855540 * (double)g + 0.1881852 * (double)b);
                        xyzValue[x * 3 + 1 + y * w * 3] = (double)(0.2973769 * (double)r + 0.6273491 * (double)g + 0.0752741 * (double)b);
                        xyzValue[x * 3 + 2 + y * w * 3] = (double)(0.0270343 * (double)r + 0.0706872 * (double)g + 0.9911085 * (double)b);
                    }
                }
                Stream sTemp = srcImage.PixelBuffer.AsStream();
                sTemp.Seek(0, SeekOrigin.Begin);
                sTemp.Write(temp, 0, w * 4 * h);
                return xyzValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert rgb to xyz.
        /// </summary>
        /// <param name="rgbValue">The rgb value.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] RGBtoXYZ(byte[]rgbValue,int w,int h)
        {
            if (rgbValue != null)
            {
                double[] xyzValue = new double[w * h * 3];
                int r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = rgbValue[x * 3 + y * w * 3];
                        g = rgbValue[x * 3 + 1 + y * w * 3];
                        r = rgbValue[x * 3 + 2 + y * w * 3];
                        xyzValue[x * 3 + y * w * 3] = (double)(0.5767309 * (double)r + 0.1855540 * (double)g + 0.1881852 * (double)b);
                        xyzValue[x * 3 + 1 + y * w * 3] = (double)(0.2973769 * (double)r + 0.6273491 * (double)g + 0.0752741 * (double)b);
                        xyzValue[x * 3 + 2 + y * w * 3] = (double)(0.0270343 * (double)r + 0.0706872 * (double)g + 0.9911085 * (double)b);
                    }
                }
                return xyzValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert xyz to rgb.
        /// </summary>
        /// <param name="xyzValue">The xyz value.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] XYZtoRGB(byte[] xyzValue, int w, int h)
        {
            if (xyzValue != null)
            {
                double[] rgbValue = new double[w * h * 3];
                double xV = 0, yV = 0, zV = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        xV = xyzValue[x * 3 + y * w * 3];
                        yV = xyzValue[x * 3 + 1 + y * w * 3];
                        zV = xyzValue[x * 3 + 2 + y * w * 3];
                        rgbValue[x * 3 + y * w * 3] = (byte)(0.0134474 * xV - 0.1183897 * yV + 1.0154096 * zV);
                        rgbValue[x * 3 + 1 + y * w * 3] = (byte)(-0.9692660 * xV + 1.8760108 * yV + 0.0415560 * zV);
                        rgbValue[x * 3 + 2 + y * w * 3] = (byte)(2.0413690 * xV - 0.5649464 * yV - 0.3446944 * zV);
                    }
                }
                return rgbValue;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Get yuv information.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <returns></returns>
        public static double[] YUVValue(WriteableBitmap src)
        {
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                double[] yuvValue = new double[w * h * 3];
                WriteableBitmap srcImage = new WriteableBitmap(w, h);
                byte[] temp = src.PixelBuffer.ToArray();
                int r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = temp[x * 4 + y * w * 4];
                        g = temp[x * 4 + 1 + y * w * 4];
                        r = temp[x * 4 + 2 + y * w * 4];
                        yuvValue[x * 3 + y * w * 3] = (double)(0.299 * (double)r + 0.587 * (double)g + 0.114 * (double)b);
                        yuvValue[x * 3 + 1 + y * w * 3] = (double)(-0.148 * (double)r - 0.289 * (double)g + 0.437 * (double)b);
                        yuvValue[x * 3 + 2 + y * w * 3] = (double)(0.615 * (double)r - 0.515 * (double)g - 0.100 * (double)b);
                    }
                }
                Stream sTemp = srcImage.PixelBuffer.AsStream();
                sTemp.Seek(0, SeekOrigin.Begin);
                sTemp.Write(temp, 0, w * 4 * h);
                return yuvValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert RGB to YUV.
        /// </summary>
        /// <param name="rgbValue">The rgb information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] RGBtoYUV(byte[] rgbValue, int w, int h)
        {
            if (rgbValue != null)
            {
                double[] yuvValue = new double[w * h * 3];
                int r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = rgbValue[x * 3 + y * w * 3];
                        g = rgbValue[x * 3 + 1 + y * w * 3];
                        r = rgbValue[x * 3 + 2 + y * w * 3];
                        yuvValue[x * 3 + y * w * 3] = (double)(0.299 * (double)r + 0.587 * (double)g + 0.114 * (double)b);
                        yuvValue[x * 3 + 1 + y * w * 3] = (double)(-0.148 * (double)r - 0.289 * (double)g + 0.437 * (double)b);
                        yuvValue[x * 3 + 2 + y * w * 3] = (double)(0.615 * (double)r - 0.515 * (double)g - 0.100 * (double)b);
                    }
                }
                return yuvValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert yuv to rgb.
        /// </summary>
        /// <param name="yuvValue">The yuv information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] YUVtoRGB(byte[] yuvValue, int w, int h)
        {
            if (yuvValue != null)
            {
                double[] rgbValue = new double[w * h * 3];
                double yV = 0, uV = 0, vV = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        yV = yuvValue[x * 3 + y * w * 3];
                        uV = yuvValue[x * 3 + 1 + y * w * 3];
                        vV = yuvValue[x * 3 + 2 + y * w * 3];
                        rgbValue[x * 3 + y * w * 3] = (byte)(1 * yV + 2.032 * uV + 0 * vV);
                        rgbValue[x * 3 + 1 + y * w * 3] = (byte)(1 * yV - 0.395 * uV - 0.581 * vV);
                        rgbValue[x * 3 + 2 + y * w * 3] = (byte)(1 * yV + 0 * uV + 1.140 * vV);
                    }
                }
                return rgbValue;
            }
            else
            {
                return null;
            }
        }

4.4 HIS颜色空间

 [空间解析]

  HIS颜色空间是从人的视觉系统出发,用色调(Hue)、色饱和度(SaturationChroma)和亮度 (IntensityBrightness)来描述色彩。HSI色彩空间可以用一个圆锥空间模型来描述。用这种 描述HIS色彩空间的圆锥模型相当复杂,但确能把色调、亮度和色饱和度的变化情形表现得很清楚。通常把色调和饱和度通称为色度,用来表示颜色的类别与深浅程度,HS包含了颜色信息,而I则与颜色信息无关。

  HIS颜色空间模型如下图所示:

        /// <summary>
        /// Get his information.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <returns></returns>
        public static double[] HISValue(WriteableBitmap src)
        {
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                double[] hisValue = new double[w * h * 3];
                WriteableBitmap srcImage = new WriteableBitmap(w, h);
                byte[] temp = src.PixelBuffer.ToArray();
                double r = 0, g = 0, b = 0;
                double hV = 0, degree = 0, iV = 0, sV = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = (double)temp[x * 4 + y * w * 4]/255.0;
                        g = (double)temp[x * 4 + 1 + y * w * 4]/255.0;
                        r = (double)temp[x * 4 + 2 + y * w * 4]/255.0;
                        degree = Math.Acos(0.5 * ((r - g) + (r - b)) / Math.Sqrt((r - g) * (r - g) + (r - b) * (g - b) + 0.0000001)) / (2 * Math.PI);
                        hV = (b <= g) ? degree : 1.0 - degree;
                        iV = (double)(r + g + b) / 3.0;
                        sV = 1.0 - 3.0 * (double)Math.Min(r, Math.Min(g, b)) / (double)(r + g + b + 0.00000001);
                        hisValue[x * 3 + y * w * 3] = hV;
                        hisValue[x * 3 + 1 + y * w * 3] = iV;
                        hisValue[x * 3 + 2 + y * w * 3] = sV;
                    }
                }
                Stream sTemp = srcImage.PixelBuffer.AsStream();
                sTemp.Seek(0, SeekOrigin.Begin);
                sTemp.Write(temp, 0, w * 4 * h);
                return hisValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert rgb to his.
        /// </summary>
        /// <param name="rgbValue">The rgb information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] RGBtoHIS(byte[] rgbValue, int w, int h)
        {
            if (rgbValue != null)
            {
                double[] hisValue = new double[w * h * 3];
                double r = 0, g = 0, b = 0;
                double hV = 0, degree = 0, iV = 0, sV = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = (double)rgbValue[x * 3 + y * w * 3]/255.0;
                        g = (double)rgbValue[x * 3 + 1 + y * w * 3]/255.0;
                        r = (double)rgbValue[x * 3 + 2 + y * w * 3]/255.0;
                        degree = Math.Acos(0.5 * ((r - g) + (r - b)) / Math.Sqrt((r - g) * (r - g) + (r - b) * (g - b) + 0.0000001)) / (2 * Math.PI);
                        hV = (b <= g) ? degree : 1.0 - degree;
                        iV = (double)(r + g + b) / 3.0;
                        sV = 1.0 - 3.0 * (double)Math.Min(r, Math.Min(g, b)) / (double)(r + g + b + 0.00000001);
                        hisValue[x * 3 + y * w * 3] = hV;
                        hisValue[x * 3 + 1 + y * w * 3] = iV;
                        hisValue[x * 3 + 2 + y * w * 3] = sV;
                    }
                }
                return hisValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert his to rgb.
        /// </summary>
        /// <param name="hisValue">The his information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] HIStoRGB(byte[] hisValue, int w, int h)
        {
            if (hisValue != null)
            {
                double[] rgbValue = new double[w * h * 3];
                double hV = 0, iV = 0, sV = 0;
                double r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        hV = hisValue[x * 3 + y * w * 3];
                        iV = hisValue[x * 3 + 1 + y * w * 3];
                        sV = hisValue[x * 3 + 2 + y * w * 3];
                        hV = hV * 2 * Math.PI;
                        if (hV >= 0 && hV < 2 * Math.PI / 3)
                        {
                            r = (double)(iV * (1.0 + (sV * Math.Cos(hV) / Math.Cos(Math.PI / 3 - hV))));
                            b = (double)(iV * (1.0 - sV));
                            g = (double)(3.0 * iV - r - b);
                        }
                        else if (hV >= 2 * Math.PI / 3 && hV < 4 * Math.PI / 3)
                        {
                            g = (double)(iV * (1.0 + sV * Math.Cos(hV - 2 * Math.PI / 3) / Math.Cos(Math.PI - hV)));
                            r = (double)(iV * (1.0 - sV));
                            b = (double)(3.0 * iV - r - g);
                        }
                        else
                        {
                            g = (double)(iV * (1.0 - sV));
                            b = (double)(iV * (1.0 + sV * Math.Cos(hV - 4 * Math.PI / 3) / Math.Cos(5 * Math.PI / 3 - hV)));
                            r = (double)(3.0 * iV - g - b);
                        }
                        rgbValue[x * 3 + y * w * 3] = (byte)(Math.Min(255, b * 255.0));
                        rgbValue[x * 3 + 1 + y * w * 3] = (byte)(Math.Min(255, g * 255.0));
                        rgbValue[x * 3 + 2 + y * w * 3] = (byte)(Math.Min(255, r * 255.0));
                    }
                }
                return rgbValue;
            }
            else
            {
                return null;
            }
        }


        /// <summary>
        /// Get YIQ information.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <returns></returns>
        public static double[] YIQValue(WriteableBitmap src)
        {
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                double[] yiqValue = new double[w * h * 3];
                WriteableBitmap srcImage = new WriteableBitmap(w, h);
                byte[] temp = src.PixelBuffer.ToArray();
                int r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = temp[x * 4 + y * w * 4];
                        g = temp[x * 4 + 1 + y * w * 4];
                        r = temp[x * 4 + 2 + y * w * 4];
                        yiqValue[x * 3 + y * w * 3] = (double)(0.299 * (double)r + 0.587 * (double)g + 0.114 * (double)b);
                        yiqValue[x * 3 + 1 + y * w * 3] = (double)(0.596 * (double)r - 0.275 * (double)g - 0.321 * (double)b);
                        yiqValue[x * 3 + 2 + y * w * 3] = (double)(0.212 * (double)r - 0.523 * (double)g + 0.311 * (double)b);
                    }
                }
                Stream sTemp = srcImage.PixelBuffer.AsStream();
                sTemp.Seek(0, SeekOrigin.Begin);
                sTemp.Write(temp, 0, w * 4 * h);
                return yiqValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert rgb to yiq.
        /// </summary>
        /// <param name="rgbValue">The rgb information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] RGBtoYIQ(byte[] rgbValue, int w, int h)
        {
            if (rgbValue != null)
            {
                double[] yiqValue = new double[w * h * 3];
                int r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = rgbValue[x * 3 + y * w * 3];
                        g = rgbValue[x * 3 + 1 + y * w * 3];
                        r = rgbValue[x * 3 + 2 + y * w * 3];
                        yiqValue[x * 3 + y * w * 3] = (double)(0.299 * (double)r + 0.587 * (double)g + 0.114 * (double)b);
                        yiqValue[x * 3 + 1 + y * w * 3] = (double)(0.596 * (double)r - 0.275 * (double)g - 0.321 * (double)b);
                        yiqValue[x * 3 + 2 + y * w * 3] = (double)(0.212 * (double)r - 0.523 * (double)g + 0.311 * (double)b);
                    }
                }
                return yiqValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert yiq to rgb.
        /// </summary>
        /// <param name="yiqValue">The yiq information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] YIQtoRGB(byte[] yiqValue, int w, int h)
        {
            if (yiqValue != null)
            {
                double[] rgbValue = new double[w * h * 3];
                double yV = 0, iV = 0, qV = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        yV = yiqValue[x * 3 + y * w * 3];
                        iV = yiqValue[x * 3 + 1 + y * w * 3];
                        qV = yiqValue[x * 3 + 2 + y * w * 3];
                        rgbValue[x * 3 + 2 + y * w * 3] = (byte)(1 * yV + 0.9560 * iV + 0.6210 * qV);
                        rgbValue[x * 3 + 1 + y * w * 3] = (byte)(1 * yV - 0.2720 * iV - 0.6470 * qV);
                        rgbValue[x * 3 + y * w * 3] = (byte)(1 * yV - 1.1070 * iV + 1.7040 * qV);
                    }
                }
                return rgbValue;
            }
            else
            {
                return null;
            }
        }

4.6 HSV颜色空间

[空间解析]

  HSV彩色空间是一种适合肉眼分辨的模型。
  H—色相,表示色彩信息,即所处的光谱颜色的位置。该参数用角度量来表示,红、绿、蓝分别相隔120度。互补色分别相差180度。
  S—饱和度,该参数为一比例值,范围从01,它表示成所选颜色的纯度和该颜色最大的纯度之间的比率。S=0时,只有灰度。
  V—亮度,表示色彩的明亮程度,范围从01

  HSV颜色空间模型如下图所示:

        /// <summary>
        /// Get HSV information.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <returns></returns>
        public static double[] HSVValue(WriteableBitmap src)
        {
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                double[] hsvValue = new double[w * h * 3];
                WriteableBitmap srcImage = new WriteableBitmap(w, h);
                byte[] temp = src.PixelBuffer.ToArray();
                double r = 0, g = 0, b = 0;
                double min = 0, max = 0;
                double hV = 0, sV = 0, vV = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = (double)temp[x * 4 + y * w * 4]/255.0;
                        g = (double)temp[x * 4 + 1 + y * w * 4]/255.0;
                        r = (double)temp[x * 4 + 2 + y * w * 4]/255.0;
                        min = Math.Min(r, Math.Min(g, b));
                        max = Math.Max(r, Math.Max(g, b));
                        if (max == min)
                            hV = 0;
                        if (max == r && g >= b)
                            hV = 60.0 * (g - b) / (max - min);
                        if (max == r && g < b)
                            hV = 60.0 * (g - b) / (max - min) + 360.0;
                        if (max == g)
                            hV = 60.0 * (b - r) / (max - min) + 120.0;
                        if (max == b)
                            hV = 60.0 * (r - g) / (max - min) + 240.0;
                        if (max == 0)
                            sV = 0;
                        else
                            sV = (max - min) / max;
                        vV = max;
                        hsvValue[x * 3 + y * w * 3] = (double)(hV);
                        hsvValue[x * 3 + 1 + y * w * 3] = (double)(sV);
                        hsvValue[x * 3 + 2 + y * w * 3] = (double)(vV);
                    }
                }
                Stream sTemp = srcImage.PixelBuffer.AsStream();
                sTemp.Seek(0, SeekOrigin.Begin);
                sTemp.Write(temp, 0, w * 4 * h);
                return hsvValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert rgb to hsv.
        /// </summary>
        /// <param name="rgbValue">The rgb information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] RGBtoHSV(byte[] rgbValue, int w, int h)
        {
            if (rgbValue != null)
            {
                double[] hsvValue = new double[w * h * 3];
                double r = 0, g = 0, b = 0;
                double min = 0, max = 0;
                double hV = 0, sV = 0, vV = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        r = (double)rgbValue[x * 3 + 2 + y * w * 3] / 255.0;
                        g = (double)rgbValue[x * 3 + 1 + y * w * 3] / 255.0;
                        b = (double)rgbValue[x * 3 + y * w * 3] / 255.0;
                        min = Math.Min(r, Math.Min(g, b));
                        max = Math.Max(r, Math.Max(g, b));
                        if (max == min)
                            hV = 0;
                        if (max == r && g >= b)
                            hV = 60.0 * (g - b) / (max - min);
                        if (max == r && g < b)
                            hV = 60.0 * (g - b) / (max - min) + 360.0;
                        if (max == g)
                            hV = 60.0 * (b - r) / (max - min) + 120.0;
                        if (max == b)
                            hV = 60.0 * (r - g) / (max - min) + 240.0;
                        if (max == 0)
                            sV = 0;
                        else
                            sV = (max - min) / max;
                        vV = max;
                        hsvValue[x * 3 + y * w * 3] = (double)(hV);
                        hsvValue[x * 3 + 1 + y * w * 3] = (double)(sV);
                        hsvValue[x * 3 + 2 + y * w * 3] = (double)(vV);
                    }
                }
                return hsvValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert hsv to rgb.
        /// </summary>
        /// <param name="hsvValue">The hsv information.</param>
        /// <param name="w">The width of souce image.</param>
        /// <param name="h">The height of souce image.</param>
        /// <returns></returns>
        public static double[] HSVtoRGB(byte[] hsvValue, int w, int h)
        {
            if (hsvValue != null)
            {
                double[] rgbValue = new double[w * h * 3];
                double hV = 0, sV = 0, vV = 0, r = 0, g = 0, b = 0, p = 0, q = 0, t = 0;
                int hN = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        hV = hsvValue[x * 3 + y * w * 3];
                        sV = hsvValue[x * 3 + 1 + y * w * 3];
                        vV = hsvValue[x * 3 + 2 + y * w * 3];
                        if (hV < 0)
                            hV = 360 + hV;
                        hN = (int)(hV / 60);
                        p = vV * (1.0 - sV);
                        q = vV * (1.0 - (hV / 60.0 - hN) * sV);
                        t = vV * (1.0 - (1.0 - (hV / 60.0 - hN)) * sV);
                        switch (hN)
                        {
                            case 0:
                                r = vV;
                                g = t;
                                b = p;
                                break;
                            case 1:
                                r = q;
                                g = vV;
                                b = p;
                                break;
                            case 2:
                                r = p;
                                g = vV;
                                b = t;
                                break;
                            case 3:
                                r = p;
                                g = q;
                                b = vV;
                                break;
                            case 4:
                                r = t;
                                g = p;
                                b = vV;
                                break;
                            case 5:
                                r = vV;
                                g = p;
                                b = q;
                                break;
                            default:
                                break;
                        }
                        rgbValue[x * 3 + y * w * 3] = (byte)(255.0 * b);
                        rgbValue[x * 3 + 1 + y * w * 3] = (byte)(255.0 * g);
                        rgbValue[x * 3 + 2 + y * w * 3] = (byte)(255.0 * r);
                    }
                }
                return rgbValue;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Get cmyk information.
        /// </summary>
        /// <param name="src">The source image.</param>
        /// <returns></returns>
        public static double[] CMYKValue(WriteableBitmap src)
        {
            if (src != null)
            {
                int w = src.PixelWidth;
                int h = src.PixelHeight;
                double[] cmykValue = new double[w * h * 4];
                WriteableBitmap srcImage = new WriteableBitmap(w, h);
                byte[] temp = src.PixelBuffer.ToArray();
                int r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = temp[x * 4 + y * w * 4];
                        g = temp[x * 4 + 1 + y * w * 4];
                        r = temp[x * 4 + 2 + y * w * 4];
                        cmykValue[x * 4 + y * w * 4] = (double)(g + b);
                        cmykValue[x * 4 + 1 + y * w * 4] = (double)(r + b);
                        cmykValue[x * 4 + 2 + y * w * 4] = (double)(r + g);
                        cmykValue[x * 4 + 3 + y * w * 4] = (double)(Math.Min((g + b), Math.Min((r + b), (r + g))));
                    }
                }
                Stream sTemp = srcImage.PixelBuffer.AsStream();
                sTemp.Seek(0, SeekOrigin.Begin);
                sTemp.Write(temp, 0, w * 4 * h);
                return cmykValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert rgb to cmyk.
        /// </summary>
        /// <param name="rgbValue">The rgb information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] RGBtoCMYK(byte[] rgbValue, int w, int h)
        {
            if (rgbValue != null)
            {
                double[] cmykValue = new double[w * h * 4];
                int r = 0, g = 0, b = 0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        b = rgbValue[x * 3 + y * w * 3];
                        g = rgbValue[x * 3 + 1 + y * w * 3];
                        r = rgbValue[x * 3 + 2 + y * w * 3];
                        cmykValue[x * 4 + y * w * 4] = (double)(g + b);
                        cmykValue[x * 4 + 1 + y * w * 4] = (double)(r + b);
                        cmykValue[x * 4 + 2 + y * w * 4] = (double)(r + g);
                        cmykValue[x * 4 + 3 + y * w * 4] = (double)(Math.Min((g + b), Math.Min((r + b), (r + g))));
                    }
                }
                return cmykValue;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Convert cmyk to rgb.
        /// </summary>
        /// <param name="cmykValue">The cmyk information.</param>
        /// <param name="w">The width of source image.</param>
        /// <param name="h">The height of source image.</param>
        /// <returns></returns>
        public static double[] CMYKtoRGB(byte[] cmykValue, int w, int h)
        {
            if (cmykValue != null)
            {
                double[] rgbValue = new double[w * h * 3];
                double cV = 0, mV = 0, yV = 0,kV=0;
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        cV = cmykValue[x * 4 + y * w * 3];
                        mV = cmykValue[x * 4 + 1 + y * w * 3];
                        yV = cmykValue[x * 4 + 2 + y * w * 3];
                        kV = cmykValue[x * 4 + 3 + y * w * 3];
                        rgbValue[x * 3 + y * w * 3] = (byte)(0.5 * (mV + cV - yV));
                        rgbValue[x * 3 + 1 + y * w * 3] = (byte)(0.5 * (yV + cV - mV));
                        rgbValue[x * 3 + 2 + y * w * 3] = (byte)(0.5 * (mV + yV - cV));
                    }
                }
                return rgbValue;
            }
            else
            {
                return null;
            }
        }

最后,分享一个专业的图像处理网站(微像素),里面有很多源代码下载:

目录
相关文章
|
C# 计算机视觉
Win8 Metro(C#) 数字图像处理--1 图像打开,保存
原文:Win8 Metro(C#) 数字图像处理--1 图像打开,保存 作为本专栏的第一篇,必不可少的需要介绍一下图像的打开与保存,一便大家后面DEMO的制作。
1126 0
|
算法 C# 计算机视觉
C#数字图像处理算法详解大全
原文:C#数字图像处理算法详解大全 C#数字图像处理算法详解大全 网址http://dongtingyueh.blog.
1485 0
|
算法 C# 计算机视觉
Win8Metro(C#)数字图像处理--2.3图像反色
原文:Win8Metro(C#)数字图像处理--2.3图像反色 [函数名称] 图像反色函数ContraryProcess(WriteableBitmap src) [算法说明]     反色公式如下:       P'(x,y) = 255 - P(x,y);     P'(x,y)为反色后的像素值,P(x,y)是原始像素值。
1086 0
|
算法 数据挖掘 C#
Win8Metro(C#)数字图像处理--2.4图像颜色聚类
原文:Win8Metro(C#)数字图像处理--2.4图像颜色聚类  [函数名称] 图像颜色聚类函数ClusterProcess(WriteableBitmap src,int value) [算法说明]   图像颜色聚类的方法有很多,但是对于视频监控而言,现有方法很难满足实时性的要求,这里介绍一种位屏蔽压缩的方法实现颜色聚类,可以满足实时性的要求。
1012 0
|
C# 计算机视觉
Win8Metro(C#)数字图像处理--2.8图像线性变换
原文:Win8Metro(C#)数字图像处理--2.8图像线性变换  2.8图像线性变换 [函数名称] 图像线性变换函数LinearTransformProcess(WriteableBitmap sr...
908 0
|
算法 C# 计算机视觉
Win8Metro(C#)数字图像处理--2.7图像伪彩色
原文:Win8Metro(C#)数字图像处理--2.7图像伪彩色  2.7图像伪彩色函数 [函数名称] 图像伪彩色函数PseudoColorProcess(WriteableBitmap src) [算法说明]   伪彩色是为改善视觉效果,利用计算机图像增强技术对图像的灰度赋予的不同假色彩,即,将一张灰度图转化为彩色图。
1074 0
|
C# 计算机视觉
Win8Metro(C#)数字图像处理--2.6图像对比度调整
原文:Win8Metro(C#)数字图像处理--2.6图像对比度调整  2.6图像对比度调整函数 [函数名称] 图像对比度调整函数ContrastAdjustProcess(WriteableBitma...
1065 0
|
C# 计算机视觉
Win8Metro(C#)数字图像处理--2.5图像亮度调整
原文:Win8Metro(C#)数字图像处理--2.5图像亮度调整  2.5图像亮度调整函数 [函数名称]   图像亮度调整函数BrightnessAdjustProcess(Wr...
1141 0
|
C# 计算机视觉
Win8Metro(C#)数字图像处理--2.10图像中值滤波
原文:Win8Metro(C#)数字图像处理--2.10图像中值滤波  [函数名称] 图像中值滤波函数MedianFilterProcess(WriteableBitmap src) [函数代码]        ///        /// Median filter process.
1229 0
|
C# 计算机视觉
Win8Metro(C#)数字图像处理--2.9图像均值滤波
原文:Win8Metro(C#)数字图像处理--2.9图像均值滤波  [函数名称] 图像均值滤波函数MeanFilterProcess(WriteableBitmap src) [函数代码]        ///        /// Mean filter process.
1250 0