图像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小时内删除。
发表评论