共享一个实现数字图像处理中各种颜色空间互相转换的类,有图有真相!HIS,HSV,YUV,YIQ,CMYK......

Trent1985
博客专家认证
2012-11-07 05:30:43
今天写了一个不同颜色空间相互转换的类,觉得还可以,跟大家分享一下,喜欢数字图像处理的朋友们可以看下,这个类可以实现HIS,HSV,YUV,XYZ,YIQ,CMYK颜色空间与RGB颜色空间的相互转换,本人在这里只给出HIS的图像实例,这里只对H分量进行了调整,下面先看结果:




免费下载地址:
http://download.csdn.net/detail/trent1985/4743052
给出部分代码,由于CSDN上传代码内容不超过10000个字符,没办法呵呵。。。。。。
csharp
private Bitmap srcBitmap = null;
public TImageColorspace(Bitmap tempBitmap)
{
srcBitmap = tempBitmap;
}
public byte[]RGBValue()
{
try
{
int w = srcBitmap.Width;
int h = srcBitmap.Height;
byte[] imageData = new byte[w * h * 3];
Bitmap dstBitmap = new Bitmap(srcBitmap.Width, srcBitmap.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
System.Drawing.Imaging.BitmapData srcData = srcBitmap.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
unsafe
{
byte* pIn = (byte*)srcData.Scan0.ToPointer();
byte* p;
int stride = srcData.Stride;
int r, g, b;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
p = pIn;
r = p[2];
g = p[1];
b = p[0];
imageData[x * 3 + y * w * 3] = (byte)b;
imageData[x * 3 + 1 + y * w * 3] = (byte)g;
imageData[x * 3 + 2 + y * w * 3] = (byte)r;
pIn += 3;
}
pIn += srcData.Stride - w * 3;
}
srcBitmap.UnlockBits(srcData);
return imageData;
}
}
catch (Exception e)
{
MessageBox.Show(e.Message.ToString());
return null;
}
}

public double[] HISValue()
{
try
{
int w = srcBitmap.Width;
int h = srcBitmap.Height;
double[] imageData = new double[w * h * 3];
Bitmap dstBitmap = new Bitmap(srcBitmap.Width, srcBitmap.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
System.Drawing.Imaging.BitmapData srcData = srcBitmap.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
unsafe
{
byte* pIn = (byte*)srcData.Scan0.ToPointer();
byte* p;
int stride = srcData.Stride;
double r, g, b;
double hV = 0, degree = 0, iV = 0, sV = 0;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
p = pIn;
r = (double)p[2] / 255.0;
g = (double)p[1] / 255.0;
b = (double)p[0] / 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);
imageData[x * 3 + y * w * 3] = hV;
imageData[x * 3 + 1 + y * w * 3] = iV;
imageData[x * 3 + 2 + y * w * 3] = sV;
pIn += 3;
}
pIn += srcData.Stride - w * 3;
}
srcBitmap.UnlockBits(srcData);
return imageData;
}
}
catch (Exception e)
{
MessageBox.Show(e.Message.ToString());
return null;
}
}
public static double[] RGBtoHIS(byte[] rgbValue, int w, int h)
{
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 = rgbValue[x * 3 + y * w * 3] / 255.0;
g = rgbValue[x * 3 + 1 + y * w * 3] / 255.0;
r = 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;
}
public static byte[] HIStoRGB(double[] hisValue, int w, int h)
{
byte[] rgbValue = new byte[w * h * 3];
double hV = 0, iV = 0, sV = 0;
double r = 0, g = 0, b = 0;
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
hV = hisValue[i * 3 + j * w * 3];
iV = hisValue[i * 3 + 1 + j * w * 3];
sV = hisValue[i * 3 + 2 + j * 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[i * 3 + j * w * 3] = (byte)(Math .Min(255,b * 255.0));
rgbValue[i * 3 + 1 + j * w * 3] = (byte)(Math .Min(255,g * 255.0));
rgbValue[i * 3 + 2 + j * w * 3] = (byte)(Math .Min(255,r * 255.0));
}
}
return rgbValue;
}
...全文
631 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
houshannanhai 2014-05-29
  • 打赏
  • 举报
回复
这个 是 RGB转化为HIS的公式
houshannanhai 2014-05-29
  • 打赏
  • 举报
回复
我看了 你程序的RGB转his的部分。有一个问题,你所用的转化公式是RGB转HSV的,并不是RGB转HIS 我不知道你在这里是认为HIS就是HSV或者近似两者相等还是别的原因? 因为从定义上来看 两者确实很接近,但毕竟还是两种不同的模型。
Trent1985 2012-11-08
  • 打赏
  • 举报
回复
引用 3 楼 laviewpbt 的回复:
用C#做图像的人估计不多,我看你还算常回答图像方面的问题的。 其实C#的unsafe 模式下的处理速度和VC6在质上基本没有任何区别,有可能还会快些(编译器的优化能力可能更强),不晓得为什么研究的人这么少。 最近在研究C#的图像处理功能,以前一直在用VB6做图像,同样算法C#可以比VB6做到快50%,有同样的兴趣的朋友 加个QQ 聊聊。 QQ:……
呵呵,志同道合阿,我一直在做C#数字图像处理的,可惜了解的不深入,记下你QQ了,回头聊!
laviewpbt 2012-11-07
  • 打赏
  • 举报
回复
用C#做图像的人估计不多,我看你还算常回答图像方面的问题的。 其实C#的unsafe 模式下的处理速度和VC6在质上基本没有任何区别,有可能还会快些(编译器的优化能力可能更强),不晓得为什么研究的人这么少。 最近在研究C#的图像处理功能,以前一直在用VB6做图像,同样算法C#可以比VB6做到快50%,有同样的兴趣的朋友 加个QQ 聊聊。 QQ:33184777
Trent1985 2012-11-07
  • 打赏
  • 举报
回复
引用 1 楼 laviewpbt 的回复:
速度 需要继续优化。
是滴。。。
laviewpbt 2012-11-07
  • 打赏
  • 举报
回复
速度 需要继续优化。

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧