2015-04-29 12:45:37 Trent1985 阅读数 1748
• ###### MATLAB图像处理

MATLAB图像处理课程

4588 人正在学习 去看看 李立宗
﻿﻿

```       /// <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;
}
}```

2019-02-11 10:24:46 limiyudianzi 阅读数 805
• ###### MATLAB图像处理

MATLAB图像处理课程

4588 人正在学习 去看看 李立宗

[‘rgb’, ‘hsv’, ‘rgb cie’, ‘xyz’, ‘yuv’, ‘yiq’, ‘ypbpr’, ‘ycbcr’, ‘ydbdr’]

``````# 转换色彩空间通用的方法
# arr是要转换的图片，fromspace是arr图片的色彩空间，
# tospace是要转换成为的色彩空间。
skimage.color.convert_colorspace(arr, fromspace, tospace)

#除此之外还有很多简短的方便的函数比如：
Skimage.color.rgb2gray(rgb)
Skimage.color.gray2rgb(gray)
Skimage.color.hsv2rgb(hsv)
Skimage.color.rgb2hsv(rgb)
``````

``````import skimage
img = skimage.data.astronaut() #读取图片
skimage.io.imshow(img)
skimage.io.show()

img_gray = skimage.color.rgb2gray(img) #灰度图
skimage.io.imshow(img_gray)
skimage.io.show()

img_hsv = skimage.color.rgb2hsv(img) #hsv空间
skimage.io.imshow(img_hsv)
skimage.io.show()
``````

2018-02-02 14:50:32 u014030821 阅读数 2519
• ###### MATLAB图像处理

MATLAB图像处理课程

4588 人正在学习 去看看 李立宗

# 第六章 彩色图像处理

## 一：颜色模型

### 1.2 CMY和CMYK彩色模型

RGB模型为光的三基色，CMY描述的是颜料的三原色；一般应用于彩色打印机和复印机等。可由RGB转换得到(已经归一化)：

### 1.3 HSI彩色模型

RGB模型、CMY模型和其他类似的彩色模型都无法很好地适应人类实际上解释的颜色。因此，使用 色调、饱和度和亮度(HSI) 来描述物体，可以很好地符合人类视觉。

RGB->HSI:

HSI->RGB:
1. 0<=H<120:

2. 120<=H<240:

3. 240<=H<360:

## 二：彩色图像处理基础

### 2.2 全彩色图像处理

c的分量仅是一幅彩色图像在一点处的RGB分量，可以认为彩色分量是坐标(x,y)的函数：

## 三：彩色图像处理

1. 补色；
2. 彩色分层；
3. 色调和彩色矫正；
4. 直方图处理；
5. 平滑和锐化；
6. 基于彩色的图像分割。

### 3.3 基于彩色的图像分割

1. HSI彩色空间分割；
2. RGB向量空间分割；
3. 彩色边缘检测。

2017-03-20 14:59:37 dominating_ 阅读数 1363
• ###### MATLAB图像处理

MATLAB图像处理课程

4588 人正在学习 去看看 李立宗

# 原理介绍：

## RGB（红绿蓝）

RGB是依据人眼识别的颜色定义出的空间，可表示大部分颜色。是图像处理中最基本、最常用、面向硬件的颜色空间，是一种光混合的体系。

RGB颜色空间最常用的用途就是显示器系统，彩色阴极射线管,彩色光栅图形的显示器都使用R、G、B数值来驱动R、G、B 电子枪发射电子，并分别激发荧光屏上的R、G、B三种颜色的荧光粉发出不同亮度的光线，并通过相加混合产生各种颜色。扫描仪也是通过吸收原稿经反射或透射而发送来的光线中的R、G、B成分，并用它来表示原稿的颜色。

## HSI

HSI色彩空间是从人的视觉系统出发，用色调(Hue)、饱和度(Saturation或Chroma)和亮度 (Intensity或Brightness)来描述色彩。

H——表示颜色的相位角。红、绿、蓝分别相隔120度；互补色分别相差180度，即颜色的类别。
S——表示成所选颜色的纯度和该颜色最大的纯度之间的比率，范围：[0,  1]，即颜色的深浅程度。
I——表示色彩的明亮程度，围：[0, 1]，人眼对亮度很敏感！

## CMYK

CMYK是一种依靠反光的色彩模式，我们是怎样阅读报纸的内容呢？是由阳光或灯光照射到报纸上，再反射到我们的眼中，才看到内容。它需要有外界光源，如果你在黑暗房间内是无法阅读报纸的。只要在屏幕上显示的图像，就是RGB模式表现的。只要是在印刷品上看到的图像，就是CMYK模式表现的。大多数在纸上沉积彩色颜料的设备，如彩色打印机和复印机，要求输入CMY数据，在内部进行RGB到CMY的转换。

## YUV

YUV 颜色空间在 PAL，NTSC和 SECAM复合颜色视频标准中使用。采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。黑白电视系统只使用亮度信号（Y）；彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题，色度信号（U，V）以一种特殊的方式加入亮度信号，这样，黑白电视接收机能够显示正常的黑白图像，而彩色电视接收机能够对对附加的色度信号进行解码从而显示彩色图像。

# 源码

1. //================================================================================
2. /// @brief HLS <====> RGB
3. ///
4. /// [1]H是色相，代表了6种颜色，分成0～6区域，用一个模型来表述就是一个双(六)棱椎，其中的L是HSL立方体的主对角线。
5. //     RGB立方体的顶点：红、黄、绿、青、蓝和品红就成为HSL六角形的顶点,0-360度的范围内有6种颜色,但是它不是平均分布的,如绿色最多.
6. ///    H是0-360，L和S是0.00%-100.00%
7. //================================================================================
8. //HLS ---> RGB
9. void RGBtoHLS (int rgb, double& H, double& L, double& S)
10. {
11.     Color color(rgb);
12.     RGBtoHLS(color.R, color.G, color.B, H, L, S);
13. }
14.
15. //HLS ---> RGB
16. void RGBtoHLS (int r, int g, int b, double& H, double& L, double& S)
17. {
18.     int   n_cmax = max(r, max(g, b));
19.     int   n_cmin = min(r, min(g, b));
20.
21.     double Delta = 0;
22.     double Max = 0, Min = 0;
23.     double Redf = 0, Greenf = 0, Bluef = 0;
24.
25.     Redf    = (r / 255.0f);
26.     Greenf  = (g / 255.0f);
27.     Bluef   = (b / 255.0f);
28.
29.     Max     = max(max(Redf, Greenf), Bluef);
30.     Min     = min(min(Redf, Greenf), Bluef);
31.
32.     H = 0;
33.     L = (Max + Min) / 2.0f;
34.     S = 0;
35.
36.     if (Max == Min)
37.     {
38.         return;
39.     }
40.
41.     Delta = (Max - Min);
42.     if (L < 0.5)
43.         S = Delta / (Max + Min);
44.     else
45.         S = Delta / (2.0 - Max - Min);
46.
47.     if (Redf == Max)
48.     {
49.         if (Greenf >= Bluef)
50.         {
51.             H = (Greenf - Bluef) / Delta;
52.         }
53.         else
54.         {
55.             H = 6.0 + (Greenf - Bluef) / Delta;
56.         }
57.     }
58.     else if (Greenf == Max)
59.         H = 2.0 + (Bluef - Redf) / Delta;
60.     else
61.         H = 4.0 + (Redf - Greenf) / Delta;
62.
63.     H /= 6.0; //除以6，表示在那个部分。
64.
65.     if (H < 0.0)
66.         H += 1.0;
67.     if (H > 1)
68.         H -= 1;
69.
70.     H = (int)(H * 360); //转成[0, 360]
71. }
72.
73. void Color_HueToRgb(double p, double q, double Ht, double *Channel)
74. {
75.     if (Ht < 0.0)
76.         Ht += 1.0;
77.     else if (Ht > 1.0)
78.         Ht -= 1.0;
79.
80.     if ((6.0 * Ht) < 1.0)
81.         *Channel = (p + (q - p) * Ht * 6.0);
82.     else if ((2.0 * Ht) < 1.0)
83.         *Channel = (q);
84.     else if ((3.0 * Ht) < 2.0)
85.         *Channel = (p + (q - p) * ((2.0F / 3.0F) - Ht) * 6.0);
86.     else
87.         *Channel = (p);
88. }
89.
90. //RGB ---> HLS
91. void HLStoRGB (double H, double L, double S, BYTE &r, BYTE &g, BYTE &b)
92. {
93.     double M1 = 0, M2 = 0;
94.     double Redf = 0, Greenf = 0, Bluef = 0;
95.
96.     double hue = H / 360;
97.
98.     if (S == 0)//灰色
99.     {
100.         Redf    = L;
101.         Greenf  = L;
102.         Bluef   = L;
103.     }
104.     else
105.     {
106.         if (L <= 0.5)
107.             M2 = L * (1.0 + S);
108.         else
109.             M2 = L + S - L * S;
110.
111.         M1 = (2.0 * L - M2);
112.
113.         Color_HueToRgb(M1, M2, hue + (1.0F / 3.0F), &Redf);
114.         Color_HueToRgb(M1, M2, hue, &Greenf);
115.         Color_HueToRgb(M1, M2, hue - (1.0F / 3.0F), &Bluef);
116.     }
117.
118.     r = (BYTE)(Redf * 255);
119.     g = (BYTE)(Bluef * 255);
120.     b = (BYTE)(Greenf * 255);
121. }

2017-02-23 22:04:40 Mac_lzq 阅读数 6263
• ###### MATLAB图像处理

MATLAB图像处理课程

4588 人正在学习 去看看 李立宗

RGB颜色空间
RGB(red,green,blue)颜色空间最常用的用途就是显示器系统，彩色阴极射线管,彩色光栅图形的显示器 都使用R、G、B数值来驱动R、G、B 电子枪发射电子，并分别激发荧光屏上的R、G、B三种颜色的荧光粉发出不同亮度的光线，并通过相加混合产生各种颜色；扫描仪也是通过吸收原稿经反射或透射而发送来 的光线中的R、G、B成分，并用它来表示原稿的颜色。RGB色彩空间称为与设备相关的色彩空间,因为不同 的扫描仪扫描同一幅图像，会得到不同色彩的图像数据；不同型号的显示器显示同一幅图像，也会有不同 的色彩显示结果。显示器和扫描仪使用的RGB空间与CIE 1931 RGB真实三原色表色系统空间是不同的，后者 是与设备无关的颜色空间。btw：Photoshop的色彩选取器(Color Picker)。可以显示HSB、RGB、LAB和CMYK 色彩空间的每一种颜色的色彩值。

2 人视网膜中三种不同视锥细胞的光谱相对敏感性

RGB对应到显示器的三个刺激值，组成三维正交坐标系统，该系统中任何颜色都落入RGB彩色立方体内，在RGB颜色模型中，黑色在原点处，白色位于离原点最远的角上，灰度级沿着这两点的连线分布，每一个分量图像都是其原色图像。

RGB颜色空间最大的优点就是适合于显示系统，直观且容易理解。但是对彩色描述上的应用还有以下不足：

(1) RGB颜色空间利用三个颜色分量的线性组合来表示颜色，因此不同的色彩难以用精确的数值来表示，定量分析困难。

(2) 在RGB颜色系统中，三个颜色分量之间是高度相关的，即只要亮度改变，三个分量都会相应的改变，如果一个颜色的某一个分量发生了一定程度的改变，那么这颜色很可能也要发生改变。

(3) RGB颜色空间是一种均匀性较差的颜色空间，人眼对于三个颜色分量的敏感程度是不一样的，如果颜色的相似性直接用欧氏距离来度量，其结果与人眼视觉会有较大的偏差。

HSV颜色空间
HIS(Hue-Intensity-Saturation)颜色空间是图像处理中另外一个常用的颜色空间，它从人的视觉系统出发，用色调（Hue）、饱和度（Saturation或Chroma）和亮度（Intensity或Brightness）来描述颜色。HIS颜色空间可以用图3的圆锥空间模型来描述。其中，色调H由角度表示，其取值范围是 ，其中表示红色，表示黄色，表示绿色，表示蓝色，表示品红色。饱和度S是HIS彩色空间中轴线到彩色点的半径长度，彩色点离轴线的距离越近，表示颜色的白光越多。强度I用轴线方向上的高度表示，圆锥体的轴线描述了灰度级，强度最小值时为黑色，强度最大值时为白色。每个和轴线正交的切面上的点，其强度值都是相等的。

HSV(hue,saturation,value)颜色空间的模型对应于圆柱坐标系中的一个圆锥形子集，圆锥的顶面对应于V=1. 它包含RGB模型中的R=1，G=1，B=1 三个面，所代表的颜色较亮。色彩H由绕V轴的旋转角给定。红色对应于 角度0° ，绿色对应于角度120°，蓝色对应于角度240°。在HSV颜色模型中，每一种颜色和它的补色相差180° 。 饱和度S取值从0到1，所以圆锥顶面的半径为１。HSV颜色模型所代表的颜色域是CIE色度图的一个子集，这个 模型中饱和度为百分之百的颜色，其纯度一般小于百分之百。在圆锥的顶点(即原点)处，V=0,H和S无定义， 代表黑色。圆锥的顶面中心处S=0，V=1,H无定义，代表白色。从该点到原点代表亮度渐暗的灰色，即具有不同 灰度的灰色。对于这些点，S=0,H的值无定义。可以说，HSV模型中的V轴对应于RGB颜色空间中的主对角线。 在圆锥顶面的圆周上的颜色，V=1，S=1,这种颜色是纯色。HSV模型对应于画家配色的方法。画家用改变色浓和 色深的方法从某种纯色获得不同色调的颜色，在一种纯色中加入白色以改变色浓，加入黑色以改变色深，同时 加入不同比例的白色，黑色即可获得各种不同的色调。前面这一大段我相信看起来也比较费劲，虽然已经尽力准确的去解释了，但我还是建议具体使用请着重数学公式，结合图示理解 ,效果更佳。

图4 HIS/HSV彩色空间（二

(1)   H和S分量与人感受彩色的方式相似，彩色图像中的每一个均匀性彩色区域都对应一个相一致的色度和饱和度，色度和饱和度能够被用来进行独立于亮度的彩色区域分割。

(2)   I分量与颜色信息无关。

Lab 颜色空间
Lab颜色空间是由CIE（国际照明委员会）制定的一种色彩模式。自然界中任何一点色都可以在Lab空间中表达出来，它的色彩空间比RGB空间还要大。另 外，这种模式是以数字化方式来描述人的视觉感应， 与设备无关，所以它弥补了RGB和CMYK模式必须依赖于设备色彩特性的不足。 由于Lab的色彩空间要比RGB模式和CMYK模式的色彩空间大。这就意味着，RGB、CMYK所能描述的色彩信息，在Lab颜色空间中都能得以影身寸。
Lab颜色空间取坐标Lab，其中L亮度；a的正数代表红色，负端代表绿色；b的正数代表黄色， 负端代表兰色（a,b）有L＝116f（y）-16, a＝500[f（x／0.982）-f（y）], b＝200[f（y）-f（z／1.183 ）]；其中： f（x）＝7.787x+0.138, x〈0.008856; f（x）＝（x）1／3,x〉0.008856

CIE-lab/luv色彩空间

CIE(Commission International del’Eclairage)国际标准照明委员会于1931年建立了一系列表示可见光谱的颜色空间标准。它有三个基本量，用X、Y、Z表示，通过X、Y、Z能够表示任何一种颜色，X、Y、Z的值能够利用R、G、B线性表示出来，相对于RGB颜色空间，XYZ颜色空间几乎能包含人类能够感觉到的所有颜色，但XYZ颜色空间仍然是一种不均匀的颜色空间。因此在CIE-XYZ颜色空间的基础上又有了CIE-Lab，CIE-Luv等颜色空间。

YUV颜色空间

YUV、YCbCr:

RGB三颜色分量转换为YUV422之后，图像的数据量便减少了1/3,如果是YUV420，则数据量便减少了一半。常用这种转换后的数据进行图像压缩编码。

CMYK颜色空间
CMYK(cyan,magenta,yellow)颜色空间应用于印刷工业,印刷业通过青(C)、品(M)、黄(Y)三原色油墨的不同 网点面积率的叠印来表现丰富多彩的颜色和阶调，这便是三原色的CMY颜色空间。实际印刷中，一般采用青 (C)、品(M)、黄(Y)、黑(BK)四色印刷，在印刷的中间调至暗调增加黑版。当红绿蓝三原色被混合时，会产生 白色，但是当混合蓝绿色、紫红色和黄色三原色时会产生黑色。既然实际用的墨水并不会产生纯正的颜色， 黑色是包括在分开的颜色，而这模型称之为CMYK。CMYK颜色空间是和设备或者是印刷过程相关的，则工艺方法、 油墨的特性、纸张的特性等，不同的条件有不同的印刷结果。所以CMYK颜色空间称为与设备有关的表色空间。 而且，CMYK具有多值性，也就是说对同一种具有相同绝对色度的颜色，在相同的印刷过程前提下，可以用分种 CMYK数字组合来表示和印刷出来。这种特性给颜色管理带来了很多麻烦，同样也给控制带来了很多的灵活性。 在印刷过程中，必然要经过一个分色的过程，所谓分色就是将计算机中使 用的RGB颜色转换成印刷使用的CMYK 颜色。在转换过程中存在着两个复杂的问题，其一是这两个颜色空间在表现颜色的范围上不完全一样，RGB的 色域较大而CMYK则较小，因此就要进行色域压缩；其二是这两个颜色都是和具体的设备相关的，颜色本身没有 绝对性。因此就需要通过一个与设备无关的颜色空间来进行转换，即可以通过以上介绍的XYZ或LAB色空间来 进行转换。

CMY颜色空间
CMY是一种颜料混合配色体系

RGB是一种光混合配色体系

C - Cyan 〈互补色〉 R - Red
M - Magenta 品红 〈互补色〉 G - Green 绿
Y - Yellow 〈互补色〉 B - Blue

·C和R相反，M和G相反，Y和B相反

HSL颜色空间
HSL(hue,saturation,lightness)颜色空间，这个颜色空间都是用户台式机图形程序的颜色表示， 用六角形锥体表示自己的颜色模型。

HSB颜色空间
HSB(hue,saturation,brightness)颜色空间，这个颜色空间都是用户台式机图形程序的颜色表示， 用六角形锥体表示自己的颜色模型。

Ycc颜色空间

XYZ颜色空间