从昨天折腾到今天。再折腾下去我都要上主楼了 

大致和灰度图均衡是一样的,主要是不能像平滑什么的直接对R,G,B三个分量进行。这样出来的图像时没法看的。因此我们要对亮度进行均衡。而HSI彩色空间中的分量I代表图像的亮度,和图像的彩色信息无关,所以它是我们perfect的折腾对象。

一、首先,就是把图像从RGB空间转换到HSI空间。原理我就很懒的截图了:

(引自《数字图像处理第三版》(中文版)P280)
实现代码如下:
 1 void RGBtoHSI(float r,float g,float b,float *h,float *s,float *i)
2 {
3 float pi = 3.1415926;
4 float temp = sqrt((r-g)*(r-g)+(r-b)*(g-b));
5 temp = temp > 0?temp:0.01;
6 if(b<=g)
7 *h = acos(((r-g+r-b)/2.0)/temp);
8 else
9 *h = 2*pi - acos(((r-g+r-b)/2.0)/temp);
10 temp = r+g+b>0?r+g+b:0.01;
11 *s = 1.0-(3.0/temp)*min(r,g,b);
12 *i = (r+g+b)/3.0;
13 }

二、当然在进行直方图均衡以后我们还要把HSI转换回RGB,要不然我不知道怎么把它画出来。原理还是截图如下:

代码如下:

 1 void HSItoRGB(float h,float s,float i,float *r,float *g,float *b)
2 {
3 float pi = 3.1415926;
4 float otz =2*pi / 3;
5 if(h >=0 && h < otz)
6 {
7 *b = i*(1.0-s);
8 *r = i*(1.0+(s*cos(h))/(cos(pi/3.0-h)));
9 *g = 3.0*i-(*b+*r);
10 }
11 else if(h >= otz && h < 2 * otz)
12 {
13 *r = i*(1-s);
14 *g = i*(1+(s*cos(h-otz))/(cos(pi -h)));
15 *b = 3*i-(*g+*r);
16 }
17 else
18 {
19 *g = i*(1-s);
20 *b = i*(1+(s*cos(h-otz*2))/(cos(5*pi/6-h)));
21 *r = 3*i-(*g+*b);
22 }
23 }

第四行定义的otz这个变量就代表2pi/3,即120度,其实有了变量pi完全可以把它省略掉的。

最主要的注意就是除法中除数不能为零,所以第5行和第10行对于即将作为除数的temp都有个判断,其他的照着公式打就可了。头文件里要包含#include "cmath"。

三、最后对分量I进行直方图均衡,基本和对灰度图像进行直方图均衡时一样的步骤,然后再调用上面的HSItoRGB()函数把图像转回到RGB空间画出来就好了。最最最最最最最重要的一天(这个bug我调了很久)就是从HSI转回到RGB空间的时候分量R,G,B的值有可能超过255,一定要修改成255,见下面代码的73~75行!要不出来的图像会吓死你。

代码如下:

 1 void MainWindow::on_action_color_zhifang_triggered()
2 {
3 width = image_png.width();
4 height = image_png.height();
5 grayImg = QImage(width,height,QImage::Format_ARGB32);
6
7 //存放HSI空间分量的结构体
8 typedef struct HSI{
9 float h;
10 float s;
11 float i;
12 }hsi;
13
14 //申请一个二维结构体数组,存放每个像素转换到HSI空间后三分量的值
15 hsi **p = new hsi*[height];
16 for(int i = 0;i < height;i++)
17 p[i] = new hsi[height];
18
19 //遍历图像,调用函数RGBtoHSI()转换到HSI空间
20 float max = 0;
21 for(int i = 0;i < width;i++)
22 {
23 for(int j = 0;j < height;j ++)
24 {
25 QRgb rgb = image_png.pixel(i,j);
26 RGBtoHSI(qRed(rgb),qGreen(rgb),qBlue(rgb),&p[i][j].h,&p[i][j].s,&p[i][j].i);
27 max = max > p[i][j].i?max:p[i][j].i;
28 }
29 }
30 //qDebug()<<max;
31
32 int n = (int)(max+0.5);
33 //对分量I进行直方图均衡
34 int *II = new int[n+1];
35 float *IIPro = new float[n+1];
36 float *IITemp = new float[n+1];
37 float *IIJun = new float[n+1];
38
39 for(int i = 0;i <= n;i++)
40 II[i] = 0;
41
42 //计算频率,即nk
43 for(int i = 0;i < width;i++)
44 {
45 for(int j = 0;j < height;j ++)
46 {
47 II[(int)(p[i][j].i+0.5)]++;
48 }
49 }
50
51 //计算每个数量级出现的概率
52 for(int i = 0;i <= n;i++)
53 {
54 IIPro[i] = (II[i]*1.0)/(width*height);
55 }
56
57 //概率累加并计算均值
58 IITemp[0] = IIPro[0];
59 for(int i = 1;i <= n;i++)
60 {
61 IITemp[i] = IITemp[i-1]+IIPro[i];
62
63 IIJun[i]= n*IITemp[i];
64 }
65 for(int i=0;i<width;i++)
66 {
67
68 for(int j=0;j<height;j++)
69 {
70 p[i][j].i = IIJun[(int)(p[i][j].i+0.5)];
71 float r,g,b;
72 HSItoRGB(p[i][j].h,p[i][j].s,p[i][j].i,&r,&g,&b);
73 r = r > 255?255:(int)(r+0.5);
74 g = g > 255?255:(int)(g+0.5);
75 b = b > 255?255:(int)(b+0.5);
76 grayImg.setPixel(i,j,qRgb(r,g,b));
77 }
78 }
79
80 update();
81 }

实现的效果如下图所示,左边是原图,右边是亮度均衡后的图像:

http://www.cnblogs.com/DemonEdge/p/3422381.html

http://www.cnblogs.com/jianxinzhou/p/4086806.html 网络神经

http://www.cnblogs.com/easymind223/p/3462195.html hsv 拉升

http://baike.baidu.com/view/2969062.htm?from_id=852&type=syn&fromtitle=HDR&fr=aladdin hdr alg

图像处理之图像格式变换和色彩增强---rgb2hsi2hsv 色彩增强的更多相关文章

  1. Win8 Metro(C#)数字图像处理--2.38Hough变换直线检测

    原文:Win8 Metro(C#)数字图像处理--2.38Hough变换直线检测  [函数名称] Hough 变换直线检测         HoughLineDetect(WriteableBit ...

  2. 【数字图像处理】gamma变换

    论文:gamma校正的快速算法及其c语言实现 gamma变换实现过程 假设图像中有一个像素,值是 200 ,那么对这个像素进行校正必须执行如下步骤: 1. 归一化 :将像素值转换为  0 - 1  之 ...

  3. opencv图像处理之gamma变换

    import cv2 import numpy as np img=cv2.imread('4.jpg') def adjust_gamma(image, gamma=1.0): invGamma = ...

  4. PIE SDK彩色空间变换

    1. 算法功能简介 使用彩色空间变换工具可以将三波段红.绿.蓝图像变换到一个特定的彩色空间,并且能从所选彩色空间变换回 RGB.两次变换之间,通过对比度拉伸,可以生成一个色彩增强的彩色合成图像.此外, ...

  5. iOS中的图像处理(一)——基础滤镜

    最近在稍微做一些整理,翻起这部分的代码,发现是两个多月前的了. 这里讨论的是基于RGBA模型下的图像处理,即将变换作用在每个像素上. 代码是以UIImage的category形式存在的: typede ...

  6. PIE SDK最小噪声变换

    1.算法功能简介 最小噪声分离变换是用于判定图像数据内在的维数(即波段数),分离数据中的噪声,减少随后处理中的计算需求量. MNF 本质上是两次层叠的主成分变换.第一次变换(基于估计的噪声协方差矩阵) ...

  7. PIE SDK主成分变换

    1.算法功能简介   主成分变换(Principal Component Analysis,PCA)又称K-L(Karhunen-Loeve)变换或霍特林(Hotelling)变换,是基于变量之间的相 ...

  8. CxImage新手教程,图文并茂

    作为一个游戏client程序猿,须要对图像处理有一定的知识. CxImage是C++实现的功能强大的.能处理多种文件格式的图像管理类.它可以简单高速的实现图像的导入.保存.显示和变换. 同一时候又具有 ...

  9. Saliency Detection: A Spectral Residual Approach

    Saliency Detection: A Spectral Residual Approach 题目:Saliency Detection: A Spectral Residual Approach ...

随机推荐

  1. hdu2024

    这题目感觉不是很严谨,如果是关键字的话也是不能作为合法标识符的,但是这个不用检测,就算要检测也会很费劲,还得用字符串匹配,而且还得知道一共都有哪些关键字,太麻烦了,所以出题人原意就是检查大小写字母数字 ...

  2. 【软考2】Java语言的基本知识汇总

    导读:现在对于java这一模块,还没有相应的项目经验,只是通过各种类型的资料,对java有一个面上的了解.现在,对此做一个罗列总结,在以后的学习过程中,逐步完善! 一.语言的发展 1.1,机器语言 在 ...

  3. HDU——2112HDU Today(SPFA+简单Hash或map+前向星)

    HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. NOI2015 荷马史诗 【k-哈夫曼树】

    题目 追逐影子的人,自己就是影子 --荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛> ...

  5. tyvj 1061 Mobile Service

    线性DP 本题的阶段很明显,就是完成了几个请求,但是信息不足以转移,我们还需要存储三个服务员的位置,但是三个人都存的话会T,我们发现在阶段 i 处,一定有一个服务员在 p[i] 处,所以我们可以只存另 ...

  6. 【BZOJ1500】维修数列(splay)

    题意: 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的 ...

  7. cout与cerr

    cout对应于标准输出流,默认情况下是显示器.这是一个被缓冲的输出,可以被重定向. cerr对应标准错误流,用于显示错误消息.默认情况下被关联到标准输出流,但它不被缓冲,也就说错误消息可以直接发送到显 ...

  8. vba功能语句

    VBA语句集(第1辑) 定制模块行为(1) Option Explicit '强制对模块内所有变量进行声明Option Private Module '标记模块为私有,仅对同一工程中其它模块有用,在宏 ...

  9. (1)Swing创建窗体

    本系列使用Intellij IDEA 2017.3.4版本 一.运行窗体 1. 2. 3. 4. 5. 6. 给JPanel起个名字 -如From 7. 8. 9. 生成 import javax.s ...

  10. STM32调试问题

    1.JLINK V8 error:flash download failed - could not load file: Options for Target 'Targer 1'下的菜单下Outp ...