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

大致和灰度图均衡是一样的,主要是不能像平滑什么的直接对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. Python第三方库之openpyxl(11)

    Python第三方库之openpyxl(11) Stock Charts(股票图) 在工作表上按特定顺序排列的列或行中的数据可以在股票图表中绘制.正如其名称所暗示的,股票图表通常被用来说明股价的波动. ...

  2. 【LeetCode】Grid Illumination(网格照明)

    这道题是LeetCode里的第1001道题. 题目要求: 在 N x N 的网格上,每个单元格 (x, y) 上都有一盏灯,其中 0 <= x < N 且 0 <= y < N ...

  3. Leetcode 363.矩形区域不超过k的最大数值和

    矩形区域不超过k的最大数值和 给定一个非空二维矩阵 matrix 和一个整数 k,找到这个矩阵内部不大于 k 的最大矩形和. 示例: 输入: matrix = [[1,0,1],[0,-2,3]], ...

  4. ASP.NET中一般处理程序报的错误:由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值

    1.把context.Response.End();代码换成 HttpContext.Current.ApplicationInstance.CompleteRequest(); 2.把context ...

  5. web.xml不同的头文件

    <转自:http://blog.csdn.net/qq_16313365/article/details/53783288> 1. Servlet 3.1 Java EE 7 XML sc ...

  6. 雅礼培训4.3 Problem A 【点分治】

    题目简述 一个\(N\)个节点的树,有\(M\)个炸弹分布在一些节点上,有各自的威力,随着其他点距离增大对其他点的伤害呈等差减小,直至为0 问每个点受到的伤害 题解 QAQ考场代码没处理好有些炸弹威力 ...

  7. http 400报错

    http 400报错---springmvc相关: 1.使用了json入参,传递给了对象,如果对象里的属性,如这里的Bonus是int类型,你传入了非int类型,这里就会报400 2.使用了@Requ ...

  8. #1045 - Access denied for user 'root'@'localhost' (using password: NO)的问题

    问题描述:  修改了root的密码,然后在http://localhost/phpmyadmin下无法登录了  报错:#1045 - Access denied for user 'root'@'lo ...

  9. PatentTips - Optimizing Write Combining Performance

    BACKGROUND OF THE INVENTION The use of a cache memory with a processor facilitates the reduction of ...

  10. python操作excel--生成图表

    [问题] 想要折腾Python中的Excel中的图标,Chart,Graph. [解决过程] 1.参考: use python to generate graph in excel 说是可以用pywi ...