zl程序教程

您现在的位置是:首页 >  其他

当前栏目

各个颜色空间的转换

转换 空间 颜色 各个
2023-09-27 14:27:15 时间
 
  1. // RGB<->YUV

  2. // RGB<->XYZ

  3. // RGB<->LAB

  4. // RGB<->HSV

  5. // RGB<->CMY

  6.  
  7. // XYZ<->LAB

  8. // YUV ->XYZ

  9. // LAB ->HSV

  10. // XYZ ->HSV

  11. // RGB ->CMYK

  12. // CMYK->CMY

  13.  
  14. // http://www.cnblogs.com/phinecos/archive/2009/05/03/1448121.html

  15. // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html

  16. // http://www.programmershare.com/1288015/

  17. // http://blog.sina.com.cn/s/blog_6806030c0101ei9z.html

  18.  
  19. #include <math.h>

  20.  
  21. template <class T>

  22. const T& HYMin(const T& refT1, const T& refT2)

  23. {

  24. return (refT1 < refT2) ? refT1 : refT2;

  25. }

  26.  
  27. template <class T>

  28. const T& HYMax(const T& refT1, const T& refT2)

  29. {

  30. return (refT1 > refT2) ? refT1 : refT2;

  31. }

  32.  
  33. // RGB转换为YUV

  34. void RGB2YUV(double dR, double dG, double dB, double &dY, double &dU, double &dV)

  35. {

  36. dY = 0.257 * dR + 0.504 * dG + 0.098 * dB + 16; // y

  37. dU = -0.148 * dR - 0.291 * dG + 0.439 * dB + 128; // u

  38. dV = 0.439 * dR - 0.368 * dG - 0.071 * dB + 128; // v

  39. }

  40.  
  41. // YUV转换为RGB

  42. void YUV2RGB(double dY, double dU, double dV, double &dR, double &dG, double &dB)

  43. {

  44. dR = 1.0 * dY + 8 + 1.402 * (dV - 128);

  45. dG = 1.0 * dY - 0.34413 * (dU - 128) - 0.71414 * (dV - 128);

  46. dB = 1.0 * dY + 1.772 * (dU - 128) + 0;

  47. }

  48.  
  49. // RGB转换为XYZ

  50. void RGB2XYZ(double dR, double dG, double dB, double &dX, double &dY, double &dZ)

  51. {

  52. double dTempR = (dR / 255.0);

  53. double dTempG = (dG / 255.0);

  54. double dTempB = (dB / 255.0);

  55.  
  56. if(0.04045 < dTempR)

  57. {

  58. dTempR = pow((dTempR + 0.055) / 1.055, 2.4);

  59. }

  60. else

  61. {

  62. dTempR /= 12.92;

  63. }

  64.  
  65. if(0.04045 < dTempG)

  66. {

  67. dTempG = pow((dTempG + 0.055) / 1.055, 2.4);

  68. }

  69. else

  70. {

  71. dTempG /= 12.92;

  72. }

  73.  
  74. if(0.04045 < dTempB)

  75. {

  76. dTempB = pow((dTempB + 0.055) / 1.055, 2.4);

  77. }

  78. else

  79. {

  80. dTempB /= 12.92;

  81. }

  82.  
  83. dTempR *= 100.0;

  84. dTempG *= 100.0;

  85. dTempB *= 100.0;

  86.  
  87. //Observer. = 2°, Illuminant = D65

  88. dX = 0.4124564 * dTempR + 0.3575761 * dTempG + 0.1804375 * dTempB;

  89. dY = 0.2126729 * dTempR + 0.7151522 * dTempG + 0.0721750 * dTempB;

  90. dZ = 0.0193339 * dTempR + 0.1191920 * dTempG + 0.9503041 * dTempB;

  91. }

  92.  
  93. // XYZ转换为LAB

  94. void XYZ2LAB(double dX, double dY, double dZ, double &dL, double &dA ,double &dB)

  95. {

  96. double dTempX = dX / 95.047;

  97. double dTempY = dY / 100.000;

  98. double dTempZ = dZ / 108.883;

  99.  
  100. if(0.008856 < dTempX)

  101. {

  102. dTempX = pow((float)dTempX, 1.0f / 3.0f);

  103. }

  104. else

  105. {

  106. dTempX = ( 7.787 * dTempX ) + (16.0 / 116.0);

  107. }

  108.  
  109. if(0.008856 < dTempY)

  110. {

  111. dTempY = pow((float)dTempY, 1.0f / 3.0f);

  112. }

  113. else

  114. {

  115. dTempY = (7.787 * dTempY) + (16.0 / 116.0);

  116. }

  117.  
  118. if(0.008856 < dTempZ)

  119. {

  120. dTempZ = pow((float)dTempZ, 1.0f / 3.0f);

  121. }

  122. else

  123. {

  124. dTempZ = (7.787 * dTempZ) + (16.0 / 116.0);

  125. }

  126.  
  127. dL = (116 * dTempY) - 16;

  128. dA = 500 * (dTempX - dTempY);

  129. dB = 200 * (dTempY - dTempZ);

  130. }

  131.  
  132. // RGB转换为LAB

  133. void RGB2LAB(double dR, double dG, double dB, double &dLAB_L, double &dLAB_A, double &dLAB_B)

  134. {

  135. double dX, dY, dZ;

  136. RGB2XYZ(dR, dG, dB, dX, dY, dZ);

  137. XYZ2LAB(dX, dY, dZ, dLAB_L, dLAB_A, dLAB_B);

  138. }

  139.  
  140. // LAB转换为XYZ

  141. void LAB2XYZ(double dLAB_L, double dLAB_A, double dLAB_B, double &dX, double &dY, double &dZ)

  142. {

  143. double dTempY = (dLAB_L + 16) / 116;

  144. double dTempX = dLAB_A / 500 + dTempY;

  145. double dTempZ = dTempY - dLAB_B / 200;

  146.  
  147. if(pow((double)dTempY, 3) > 0.008856)

  148. {

  149. dTempY = pow((double)dTempY, 3);

  150. }

  151. else

  152. {

  153. dTempY = (dTempY - 16 / 116) / 7.787;

  154. }

  155.  
  156. if(pow((double)dTempX, 3) > 0.008856)

  157. {

  158. dTempX = pow((double)dTempX, 3);

  159. }

  160. else

  161. {

  162. dTempX = (dTempX - 16 / 116) / 7.787;

  163. }

  164.  
  165. if(pow((double)dTempZ, 3) > 0.008856)

  166. {

  167. dTempZ = pow((double)dTempZ, 3);

  168. }

  169. else

  170. {

  171. dTempZ = (dTempZ - 16.0 / 116.0) / 7.787;

  172. }

  173.  
  174. dX = 95.047 * dTempX;

  175. dY = 100.000 * dTempY;

  176. dZ = 108.883 * dTempZ;

  177. }

  178.  
  179. // XYZ转换为RGB

  180. void XYZ2RGB(double dX, double dY, double dZ, double &dR, double &dG, double &dB)

  181. {

  182. double dTempX = dX / 100.0f; // X from 0 to 95.047 (Observer = 2°, Illuminant = D65)

  183. double dTempY = dY / 100.0f; // Y from 0 to 100.000

  184. double dTempZ = dZ / 100.0f; // Z from 0 to 108.883

  185.  
  186. double dTempR = dTempX * 3.2404542 + dTempY * -1.5371385 + dTempZ * -0.4985314;

  187. double dTempG = dTempX * -0.9692660 + dTempY * 1.8760108 + dTempZ * 0.0415560;

  188. double dTempB = dTempX * 0.0556434 + dTempY * -0.2040259 + dTempZ * 1.0572252;

  189.  
  190. if(0.0031308 < dTempR)

  191. {

  192. dTempR = 1.055 * (pow(dTempR, (1 / 2.4))) - 0.055;

  193. }

  194. else

  195. {

  196. dTempR *= 12.92;

  197. }

  198.  
  199. if(0.0031308 < dTempG)

  200. {

  201. dTempG = 1.055 * (pow(dTempG, (1 / 2.4))) - 0.055;

  202. }

  203. else

  204. {

  205. dTempG *= 12.92;

  206. }

  207.  
  208. if(0.0031308 < dTempB)

  209. {

  210. dTempB = 1.055 * (pow(dTempB, (1 / 2.4))) - 0.055;

  211. }

  212. else

  213. {

  214. dTempB *= 12.92;

  215. }

  216.  
  217. dR = 255.0f * dTempR;

  218. dG = 255.0f * dTempG;

  219. dB = 255.0f * dTempB;

  220. }

  221.  
  222. // LAB转换为RGB

  223. void LAB2RGB(double dLAB_L, double dLAB_A, double dLAB_B, double &dR, double &dG, double &dB)

  224. {

  225. double dX, dY, dZ;

  226. LAB2XYZ(dLAB_L, dLAB_A, dLAB_B, dX, dY, dZ);

  227. XYZ2RGB(dX, dY, dZ, dR, dG, dB);

  228. }

  229.  
  230. // RGB转换为HSV

  231. void RGB2HSV(double dR, double dG, double dB, double &dH, double &dS, double& dV)

  232. {

  233. double dTempR = (dR / 255); // RGB from 0 to 255

  234. double dTempG = (dG / 255);

  235. double dTempB = (dB / 255);

  236.  
  237. double dMin, dMax, dDelMax;

  238. dMin = HYMin(HYMin(dTempR, dTempG), dTempB);

  239. dMax = HYMax(HYMax(dTempR, dTempG), dTempB);

  240. dDelMax = dMax - dMin; // Delta RGB value

  241.  
  242. dV = dMax;

  243.  
  244. if(0 == dMax) // This is a gray, no chroma

  245. {

  246. dH = 0.0; // HSV results from 0 to 1

  247. dS = 0.0;

  248. }

  249. else // Chromatic data

  250. {

  251. dS = dDelMax / dMax;

  252.  
  253. double dDelR = (((dMax - dTempR) / 6) + (dDelMax / 2)) / dDelMax;

  254. double dDelG = (((dMax - dTempG) / 6) + (dDelMax / 2)) / dDelMax;

  255. double dDelB = (((dMax - dTempB) / 6) + (dDelMax / 2)) / dDelMax;

  256.  
  257. if(dTempR == dMax)

  258. {

  259. dH = dDelB - dDelG;

  260. }

  261. else if(dTempG == dMax)

  262. {

  263. dH = (1.0 / 3.0) + dDelR - dDelB;

  264. }

  265. else if(dTempB == dMax)

  266. {

  267. dH = (2.0 / 3.0) + dDelG - dDelR;

  268. }

  269.  
  270. if(0 > dH)

  271. {

  272. dH += 1.0;

  273. }

  274.  
  275. if(1 < dH)

  276. {

  277. dH -= 1.0;

  278. }

  279. }

  280. }

  281.  
  282. // HSV转换为RGB

  283. void HSV2RGB(double dH, double dS, double dV, double &dR, double &dG, double &dB)

  284. {

  285. if(dS == 0) // HSV from 0 to 1

  286. {

  287. dR = 255.0f * dV;

  288. dG = 255.0f * dV;

  289. dB = 255.0f * dV;

  290. }

  291. else

  292. {

  293. // 86912219

  294. double dTempH, dTempI, dTemp1, dTemp2, dTemp3;

  295.  
  296. dTempH = 6.0f * dH;

  297. if(6 == dTempH)

  298. {

  299. dTempH = 0.0; // H must be < 1

  300. }

  301.  
  302. dTempI = int(dTempH); //Or var_i = floor( var_h )

  303. dTemp1 = dV * (1 - dS);

  304. dTemp2 = dV * (1 - dS * (dTempH - dTempI));

  305. dTemp3 = dV * (1 - dS * (1 - (dTempH - dTempI)));

  306.  
  307. double dTempR, dTempG, dTempB;

  308.  
  309. if(0 == dTempI)

  310. {

  311. dTempR = dV;

  312. dTempG = dTemp3 ;

  313. dTempB = dTemp1;

  314. }

  315. else if(1 == dTempI)

  316. {

  317. dTempR = dTemp2 ;

  318. dTempG = dV;

  319. dTempB = dTemp1;

  320. }

  321. else if(2 == dTempI)

  322. {

  323. dTempR = dTemp1;

  324. dTempG = dV;

  325. dTempB = dTemp3;

  326. }

  327. else if (3 == dTempI)

  328. {

  329. dTempR = dTemp1 ;

  330. dTempG = dTemp2 ;

  331. dTempB = dV;

  332. }

  333. else if(4 == dTempI)

  334. {

  335. dTempR = dTemp3;

  336. dTempG = dTemp1;

  337. dTempB = dV;

  338. }

  339. else

  340. {

  341. dTempR = dV;

  342. dTempG = dTemp1;

  343. dTempB = dTemp2;

  344. }

  345.  
  346. dR = 255.0f * dTempR; // RGB results from 0 to 255

  347. dG = 255.0f * dTempR;

  348. dB = 255.0f * dTempR;

  349. }

  350. }

  351.  
  352. // YUV转换为XYZ

  353. void YUV2XYZ(double dL, double dU, double dV, double &dX, double &dY, double &dZ)

  354. {

  355. double dTempY, dRefX, dRefY, dRefZ, dRefU, dRefV, dTempU, dTempV;

  356.  
  357. dTempY = (dL + 16) / 116;

  358. if(pow(dTempY, 3) > 0.008856)

  359. {

  360. dTempY = pow(dTempY, 3);

  361. }

  362. else

  363. {

  364. dTempY = (dTempY - 16.0 / 116.0) / 7.787;

  365. }

  366.  
  367. dRefX = 95.047; //Observer= 2°, Illuminant= D65

  368. dRefY = 100.000;

  369. dRefZ = 108.883;

  370.  
  371. dRefU = (4 * dRefX ) / (dRefX + (15 * dRefY) + (3 * dRefZ));

  372. dRefV = (9 * dRefY ) / (dRefX + (15 * dRefY) + (3 * dRefZ));

  373.  
  374. dTempU = dU / (13 * dL) + dRefU;

  375. dTempV = dV / (13 * dL) + dRefV;

  376.  
  377. dY = dTempY * 100;

  378. dX = -(9 * dY * dTempU) / ((dTempU - 4) * dTempV - dTempU * dTempV);

  379. dZ = (9 * dY - (15 * dTempV * dY) - (dTempV * dX)) / (3 * dTempV);

  380. }

  381.  
  382. // XYZ转换为HSV

  383. void XYZ2HSV(double dX, double dY, double dZ,double &dH, double &dS, double &dV)

  384. {

  385. double dR, dG, dB;

  386. XYZ2RGB(dX, dY, dZ, dR, dG, dB);

  387. RGB2HSV(dR, dG, dB, dH, dS, dV);

  388. }

  389.  
  390. // LAB转换为HSV

  391. void LAB2HSV(double dL, double dA, double dB, double &dH, double &dS, double &dV)

  392. {

  393. double dX, dY, dZ;

  394. LAB2XYZ(dL, dA, dB, dX, dY, dZ);

  395. XYZ2HSV(dX, dY, dZ, dH, dS, dV);

  396. }

  397.  
  398.  
  399. // RGB转换为CMY

  400. void RGB2CMY(double dR, double dG, double dB, double &dC, double &dM, double dY)

  401. {

  402. dC = 1.0 - (dR / 255.0f);

  403. dM = 1.0 - (dG / 255.0f);

  404. dY = 1.0 - (dB / 255.0f);

  405. }

  406.  
  407. //CMY转换为RGB

  408. void CMY2RGB(double dC, double dM, double dY, double &dR, double &dG, double &dB)

  409. {

  410. dR = (1.0f - dC) * 255.0f;

  411. dG = (1.0f - dM) * 255.0f;

  412. dB = (1.0f - dY) * 255.0f;

  413. }

  414.  
  415. //RGB转换为CMYK

  416. void RGB2CMYK(double dR, double dG, double dB, double &dC, double &dM, double dY, double &dK)

  417. {

  418. // RGB2CMY

  419. RGB2CMY(dR, dG, dB, dC, dM, dY);

  420.  
  421. //CMYK and CMY values from 0 to 1

  422. double dTempK = 1.0;

  423.  
  424. if(dC < dTempK)

  425. {

  426. dTempK = dC;

  427. }

  428.  
  429. if(dM < dTempK)

  430. {

  431. dTempK = dM;

  432. }

  433.  
  434. if(dY < dTempK)

  435. {

  436. dTempK = dY;

  437. }

  438.  
  439. if(1 == dTempK)

  440. { //Black

  441. dC = 0;

  442. dM = 0;

  443. dY = 0;

  444. }

  445. else

  446. {

  447. dC = (dC - dTempK) / (1 - dTempK);

  448. dM = (dM - dTempK) / (1 - dTempK);

  449. dY = (dY - dTempK) / (1 - dTempK);

  450. }

  451.  
  452. dK = dTempK;

  453. }

  454.  
  455. // CMYK转换为CMY

  456. void CMYK2CMY(double dC1, double dM1, double dY1, double dK1, double &dC2, double &dM2, double dY2)

  457. {

  458. dC2 = (dC1 * (1 - dK1) + dK1);

  459. dM2 = (dM1 * (1 - dK1) + dK1);

  460. dY2 = (dY1 * (1 - dK1) + dK1);

  461. }

 

// RGB<-->HSL互转描述, 我已验证, 这个就是Windows颜色选择对话框的颜色选择转换算法

http://www.cnblogs.com/daiguagua/p/3311756.html