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

大致和灰度图均衡是一样的,主要是不能像平滑什么的直接对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. xtu数据结构 H. City Horizon

    H. City Horizon Time Limit: 2000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java cl ...

  2. Educational Codeforces Round 33 (Rated for Div. 2)

    A. Chess For Three time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  3. [luoguP3668] [USACO17OPEN]Modern Art 2 现代艺术2(栈)

    传送门 还是一个字——栈 然后加一大堆特判 至少我是这么做的 我的代码 #include <cstdio> #include <iostream> #define N 1000 ...

  4. 刷题总结——shortest(ssoi)

    题目: 题目背景 SOURCE:NOIP2015-SHY-3 题目描述 给定一张 n 个点的有向带权完全图,和一个数组 a[] ,请按顺序删除数组中的点,请求出在删除点 a[i] 以前,所有未删除点对 ...

  5. hdu4336 Card Collector(概率DP,状态压缩)

    In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...

  6. 从ip addr add和ifconfig的区别看linux网卡ip地址的结构

    今天一个老外在邮件列表上问了一个问题,就是ip addr add和ifconfig的区别,我给他进行了解答,可能因为英语不好吧,解答的很简单,因此我还是要在这里详细说明一下.其实它们之间没有什么区别, ...

  7. Annual Congress of MUD

    Annual Congress of MUD 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Multiuser dungeon games, also called MUD games ...

  8. Codevs 2989 寻找somebody

    时间限制: 2 s 空间限制: 8000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在一个n*m的方阵中 寻找somebody的位置 有可能k不存在输出“bianta ...

  9. HDU 4771 BFS + 状压

    Stealing Harry Potter's Precious Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 ...

  10. AC日记——小书童——刷题大军 洛谷 P1926

    题目背景 数学是火,点亮物理的灯:物理是灯,照亮化学的路:化学是路,通向生物的坑:生物是坑,埋葬学理的人. 文言是火,点亮历史宫灯:历史是灯,照亮社会之路:社会是路,通向哲学大坑:哲学是坑,埋葬文科生 ...