图像RGB与HSI相互转换的C语⾔代码直接 PO 代码:
1 #include <stdio.h>
2 #include <math.h>
3 #include "graphics.h"
4
5
6/* 三通道数据,⽤于保存RGB或HSI图像数据 */
7 typedef struct {
8double *channel1;
9double *channel2;
10double *channel3;
11 } ThreeChannels;
12/* 三通道数据的初始化 */
13void InitThreeChannels(ThreeChannels &tc, int w, int h) {
14    tc.channel1 = (double *)malloc(w*h*sizeof(double));
15    tc.channel2 = (double *)malloc(w*h*sizeof(double));
16    tc.channel3 = (double *)malloc(w*h*sizeof(double));
17 }
18/* 三通道数据的释放 */c语言数组最大值最小值
19void FreeThreeChannels(ThreeChannels &tc) {
20free(tc.channel1);
21free(tc.channel2);
22free(tc.channel3);
23 }
24
25/*
26功能: 在整型数组中到最⼩值和最⼤值
27输⼊: 整型数组;数组⼤⼩;接收最⼩值;接收最⼤值
28结果: 得到数组中的最⼩值和最⼤值
29*/
30void GetMinMaxInt(int *arr, int n, int &min, int &max);
31/*
32功能: 在浮点型数组中到最⼩值和最⼤值
33输⼊: 浮点型数组;数组⼤⼩;接收最⼩值;接收最⼤值
34结果: 得到数组中的最⼩值和最⼤值
35*/
36void GetMinMaxDouble(double *arr, int n, double &min, double &max);
37/*
38功能: 打印RGB彩⾊图像
39输⼊: ThreeChannels三通道数据的结构体,宽⾼
40结果: 打印RGB彩⾊图像
41*/
42void PrintRGBImage(ThreeChannels &tc, int w, int h);
43/*
44功能: 根据⽂件名获取RGB彩⾊图像
45输⼊: ⽂件名;ThreeChannels三通道数据的结构体,宽⾼;是否打印图像
46结果: 将获取到的RGB图像保存在ThreeChannels结构体中
47*/
48void GetImageRGB(char *file, ThreeChannels &tc, int w, int h, int mode);
49/*
50功能: RGB转为HSI
51输⼊: RGB三通道结构体,HSI三通道结构体
52结果: 将RGB三通道转为HSI三通道
53*/
54void RGB2HSI(ThreeChannels &rgb, int w, int h, ThreeChannels &hsi);
55/*
56功能: HSI转为RGB
57输⼊: HSI三通道结构体,RGB三通道结构体
58结果: 将HSI三通道转为RGB三通道
59*/
60void HSI2RGB(ThreeChannels &hsi, int w, int h, ThreeChannels &rgb);
61
62
63int main() {
64int w=972, h=607;
65char file_name[] = "kanna.jpg";
66
67    initgraph(w, h, 0);
68    setcaption("RGB与HSI相互转换");
69
70    ThreeChannels imgRGB;
71    InitThreeChannels(imgRGB, w, h);
72
73// 获取RGB彩⾊图像
74    GetImageRGB(file_name, imgRGB, w, h, 0);
75
76// RGB转为HSI
77    ThreeChannels imgHSI;
78    InitThreeChannels(imgHSI, w, h);
79    RGB2HSI(imgRGB, w, h, imgHSI);
80
81//    double min, max;
82//    GetMinMaxDouble(imgHSI.channel1, w*h, min, max);
83//    printf("%lf %lf\n", min, max);
84
85// HSI转为RGB
86    ThreeChannels imgRGBtmp;
87    InitThreeChannels(imgRGBtmp, w, h);
88    HSI2RGB(imgHSI, w, h, imgRGBtmp);
89
90// 打印最终结果
91    PrintRGBImage(imgRGBtmp, w, h);
92
93    getch();
94    FreeThreeChannels(imgRGB);
95    FreeThreeChannels(imgHSI);
96    FreeThreeChannels(imgRGBtmp);
97    closegraph();
98return0;
99 }
100
101
102
103/* 在整型数组中到最⼩值和最⼤值 */
104void GetMinMaxInt(int *arr, int n, int &min, int &max) {
105    min = 0x7fffffff;
106    max = 0x80000000;
107for(int i=0; i<n; i++) {
108if(arr[i] > max) max = arr[i];
109if(arr[i] < min) min = arr[i];
110    }
111 }
112/* 在浮点型数组中到最⼩值和最⼤值 */
113void GetMinMaxDouble(double *arr, int n, double &min, double &max) { 114    min = 1.7976931348623158e+308;
115    max = 2.2250738585072014e-308;
116for(int i=0; i<n; i++) {
117if(arr[i] > max) max = arr[i];
118if(arr[i] < min) min = arr[i];
119    }
120 }
121
122
123/* 打印RGB彩⾊图像 */
124void PrintRGBImage(ThreeChannels &tc, int w, int h) {
125    color_t color;
126int i, j, red, green, blue;
127for(i=0; i<w; i++) {
128for(j=0; j<h; j++) {
129            red = *(tc.channel1+h*i+j) * 255.0;
130            green = *(tc.channel2+h*i+j) * 255.0;
131            blue = *(tc.channel3+h*i+j) * 255.0;
132            color = EGERGB(red, green, blue);
133            putpixel(i, j, color);
134        }
135    }
136 }
137/* 根据⽂件名获取RGB彩⾊图像 */
138void GetImageRGB(char *file, ThreeChannels &tc, int w, int h, int mode) { 139    color_t color;
140int i, j, red, green, blue;
141    PIMAGE pimg = newimage();
142    getimage(pimg, file, w, h);
143
144for(i=0; i<w; i++) {
145for(j=0; j<h; j++) {
146            color = getpixel(i, j, pimg);
147            red = EGEGET_R(color);
148            green = EGEGET_G(color);
149            blue = EGEGET_B(color);
150            *(tc.channel1+h*i+j) = red / 255.0;
151            *(tc.channel2+h*i+j) = green / 255.0;
152            *(tc.channel3+h*i+j) = blue / 255.0;
153        }
154    }
155// 是否打印RGB彩⾊图像
156if(mode) {
157        PrintRGBImage(tc, w, h);
158    }
159    delimage(pimg);
160 }
161/* RGB转为HSI */
162void RGB2HSI(ThreeChannels &rgb, int w, int h, ThreeChannels &hsi) {
163double rr, gg, bb, theta, ii, ss, hh, min_r_g_b;
164int i, j;
165for(i=0; i<w; i++) {
166for(j=0; j<h; j++) {
167            rr = *(rgb.channel1+h*i+j);
168            gg = *(rgb.channel2+h*i+j);
169            bb = *(rgb.channel3+h*i+j);
170
171            min_r_g_b = rr<gg ? rr:gg;
172            min_r_g_b = bb<min_r_g_b ? bb:min_r_g_b;
173
174/*
175这有个⼩细节,且很容易被忽略
176不能通过rr==gg==bb来避免除零的风险,这样仍然是错误的
177⽽是如下这样
178*/
179if(rr==gg && rr==bb) theta=PI/2.0;
180else theta = acos(0.5 * ((rr-gg)+(rr-bb)) / sqrt((rr-gg)*(rr-gg) + (rr-bb)*(gg-bb))); 181            hh = bb>gg ? (2.0*PI-theta):theta;
182            ii = 1.0/3.0 * (rr+gg+bb);
183            ss = 1.0 - min_r_g_b/ii;
184
185            *(hsi.channel1+h*i+j) = hh;
186            *(hsi.channel2+h*i+j) = ss;
187            *(hsi.channel3+h*i+j) = ii;
188        }
189    }
190 }
191/* HSI转为RGB */
192void HSI2RGB(ThreeChannels &hsi, int w, int h, ThreeChannels &rgb) {
193double ii, ss, hh, theta, rr, gg, bb;
194int i, j;
195
196for(i=0; i<w; i++) {
197for(j=0; j<h; j++) {
198            hh = *(hsi.channel1+h*i+j);
199            ss = *(hsi.channel2+h*i+j);
200            ii = *(hsi.channel3+h*i+j);
201
202if(hh>=0.0 && hh<(PI*120.0/180.0)) {
203                bb = ii * (1.0-ss);
204                rr = ii * (1.0 + ss*cos(hh) / cos((PI*60.0/180.0)-hh));
205                gg = 3.0*ii - (rr+bb);
206            } else if(hh>=(PI*120.0/180.0) && hh<(PI*240.0/180.0)) {
207                hh -= PI*120.0/180.0;
208                rr = ii * (1.0-ss);
209                gg = ii * (1.0 + ss*cos(hh) / cos((PI*60.0/180.0)-hh));
210                bb = 3.0*ii - (rr+gg);
211            } else if(hh>=(PI*240.0/180.0) && hh<(PI*360.0/180.0)) {
212                hh -= PI*240.0/180.0;
213                gg = ii * (1.0-ss);
214                bb = ii * (1.0 + ss*cos(hh) / cos((PI*60.0/180.0)-hh));
215                rr = 3.0*ii - (gg+bb);
216            }
217
218            *(rgb.channel1+h*i+j) = rr;
219            *(rgb.channel2+h*i+j) = gg;
220            *(rgb.channel3+h*i+j) = bb;
221        }
222    }
223 }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。