65.9K
CodeProject 正在变化。 阅读更多。
Home

图像转换:灰度到彩色

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.19/5 (19投票s)

2008年11月21日

CPOL

1分钟阅读

viewsIcon

125570

downloadIcon

5231

简易转换图像的算法

介绍  

这是一个简单的图像转换算法,将灰度图像转换为彩色图像。它远非理想,但非常简单。

背景

通常,我们计算灰度颜色如下:

Gray  = Green * 0.59 + Blue * 0.30 + Red * 0.11;

每个颜色结构为 [Gray, Gray, Gray] 都有一个颜色集合

G = [Gray, Gray, Gray]
G -> P = {C},对于P中的每个C:Green * 0.59 + Blue * 0.30 + Red * 0.11 = Gray。

首先,我们创建一个控制点集合。控制点等同于“灰度”颜色和“完全”颜色。当我们设置了控制点后,可以将任何“灰度”颜色近似为“完全”颜色。如果“灰度”颜色位于两个控制点 C1 和 C2 之间,则颜色近似为:

K = (Gray - C1Gray)/(C2Gray - C1Gray)
Red = C1Red + K*(C2Red - C1Red)
Green = C1Green + K*(C2Green - C1Green)
Blue = C1Blue + K*(C2Blue - C1Blue)

现在我们为每个“灰度”颜色都获得了“完全颜色”的等效值。

scheme_2.jpg

图 1. 转换示意图。

使用方法  

ControlPoint 是一个用于存储控制点数据的结构体。

public struct ControlPoint
{
    private int level;
     public int Level
    {
        get { return level; }
        set { level = value; }
    }
    private Color color;
     public Color Color
    {
        get { return color; }
        set { color = value; }
    }
     public ControlPoint(int level, Color color)
    {
        this.color = color;
        this.level = level;
    }
     public override string ToString()
    {
        return "Level: " + level.ToString() + "; Color: " + color.ToString();
    }
} 

PointsComparer 是一个用于比较两个控制点的类。

public class PointsComparer: IComparer<ControlPoint>
{
    #region IComparer<ControlPoint> Members
     public int Compare(ControlPoint x, ControlPoint y)
    {
        if (x.Level > y.Level)
        {
            return 1;
        }
        if (x.Level < y.Level)
        {
            return -1;
        }
        return 0;
    }
     #endregion
} 

ColorBuilder 是一个用于构建颜色图表的类。它返回一个包含 256 种颜色的数组 - 我们的图表。

public static Color[] GetColorDiagram(List<ControlPoint> points)
{
    Color[] colors = new Color[256];
    points.Sort(new PointsComparer());
     for (int i = 0; i < 256; i++)
    {
        ControlPoint leftColor = new ControlPoint
				(0, GetNearestLeftColor(points[0].Color)); 
        ControlPoint rightColor = new ControlPoint
			(255, GetNearestRigthColor(points[points.Count - 1].Color));
        if (i < points[0].Level)
        {
            rightColor = points[0];
        }
        if (i > points[points.Count - 1].Level)
        {
            leftColor = points[points.Count - 1];
        }
        else
        {
            for (int j = 0; j < points.Count - 1; j++)
            {
                if ((points[j].Level <= i) & (points[j + 1].Level > i))
                {
                    leftColor = points[j];
                    rightColor = points[j + 1];
                }
            }
        }
        if ((rightColor.Level - leftColor.Level) != 0)
        {
            double koef = (double)(i - leftColor.Level) / 
			(double)(rightColor.Level - leftColor.Level);
            int r = leftColor.Color.R + (int)(koef * 
			(rightColor.Color.R - leftColor.Color.R));
            int g = leftColor.Color.G + (int)(koef * 
			(rightColor.Color.G - leftColor.Color.G));
            int b = leftColor.Color.B + (int)(koef * 
			(rightColor.Color.B - leftColor.Color.B));
            colors[i] = Color.FromArgb(r, g, b);
        }
        else
        {
            colors[i] = leftColor.Color;
        }
     }
     return colors;
} 

现在我们可以获得彩色图像了

colorBitmap = new Bitmap(sourceBitmap);
for (int i = 0; i < sourceBitmap.Width; i++)
{
    for (int j = 0; j < sourceBitmap.Height; j++)
    {
        int level = sourceBitmap.GetPixel(i, j).B;
        colorBitmap.SetPixel(i, j, colors[level]);
    }
}
pbxColorImage.Image = colorBitmap;

ColorDialog.JPG

图 2. 简单的颜色对话框。

GrayColor.JPG

图 3. 灰度图像、彩色图像和颜色图表。

值得关注的点  

该算法非常简单,并且存在许多缺陷。但对于图像处理初学者来说,这是一个很好的例子。

更新信息

  1. 新的灰度级别计算公式
  2. 移除了空列表的错误
© . All rights reserved.