小言_互联网的博客

提取图像直方图(图像处理)

379人阅读  评论(0)

直方图规定化后的研究

由于直方图规定化是根据两张图片的累计直方图进行图像的处理。对于这个处理过程,我尝试了很图像进行替换色系,但是没有找到一个相对合适案例,来体现直方图规定化这个算法的精妙之处。在多次尝试中,我发现一个灰度图像(原图)和一个彩色图像(规定化图)进行直方图规定化处理后,就会得到一个彩色的图像。

我的发现

我们都知道,灰度图像转换为彩色图形,一般情况下都是假彩色。如何将一个灰度图像进行还原成原本的彩色图像,那就是我们需要获得彩色图像的直方图。

创新之处

我利用彩色图像,生成一个色条,该色条与宽度无关。也就是说,我用 1 个像素宽,n 个像素长的有颜色的色条,就可以储存该图像的直方图。通过该色条与一张灰度图像,使用直方图规定化算法就可以将彩色图像还原出来。

具体的用处

  1. 一种新的图像储存方式,使得图像的存储空间更小。

  2. 作为直方图规定化的后续研究提供另一种思路。

  3. 解决一些需要由灰度图像转换为彩色图像的便捷方式。

图像说明

使用程序可以将图像的直方图提取出来,显示到图片下面,如图所示。

 源码:


  
  1. ///
  2. // 程序名称:图像处理——提取直方图
  3. // 编译环境:Mictosoft Visual Studio 2013, EasyX_20200315(beta)
  4. //
  5. #include<graphics.h>
  6. #include<conio.h>
  7. #include<math.h>
  8. // 计算每一种 DN 值在整个像片中所占的比例
  9. void Hist(IMAGE *pimg, double num[][256])
  10. {
  11. DWORD *p = GetImageBuffer(pimg);
  12. for ( int j = 0; j < 256; j++)
  13. {
  14. double sumr = 0.0;
  15. double sumg = 0.0;
  16. double sumb = 0.0;
  17. for ( int i = pimg-> getwidth() * pimg-> getheight() - 1; i >= 0; i--)
  18. {
  19. if (j == GetRValue(p[i]))
  20. {
  21. sumr++;
  22. }
  23. if (j == GetGValue(p[i]))
  24. {
  25. sumg++;
  26. }
  27. if (j == GetBValue(p[i]))
  28. {
  29. sumb++;
  30. }
  31. }
  32. num[ 0][j] = sumr / (pimg-> getwidth() * pimg-> getheight());
  33. num[ 1][j] = sumg / (pimg-> getwidth() * pimg-> getheight());
  34. num[ 2][j] = sumb / (pimg-> getwidth() * pimg-> getheight());
  35. }
  36. }
  37. // 累计直方图
  38. void HistTOsum(double Hist[][256], int Sum[][256])
  39. {
  40. for ( int j = 0; j < 3; j++)
  41. {
  42. double mysum = 0;
  43. for ( int i = 0; i < 256; i++)
  44. {
  45. mysum += Hist[j][i];
  46. Sum[j][i] = ( int)mysum;
  47. }
  48. }
  49. }
  50. int main()
  51. {
  52. int width = 0;
  53. int height = 0;
  54. IMAGE imgpolt, imgTM;
  55. loadimage(&imgpolt, _T( "bingbing.jpeg")); // 加载原图
  56. width = imgpolt. getwidth();
  57. height = imgpolt. getheight();
  58. initgraph(width, height + 30);
  59. setbkcolor(WHITE);
  60. cleardevice();
  61. putimage( 0, 0, &imgpolt);
  62. double HistPO[ 3][ 256]; // 原图像的频率
  63. int HistPOsum[ 3][ 256]; // 原累计直方图
  64. Hist(&imgpolt, HistPO); // 计算原图的直方图
  65. for ( int i = 0; i < 256; i++)
  66. {
  67. HistPO[ 0][i] = HistPO[ 0][i] * width;
  68. HistPO[ 1][i] = HistPO[ 1][i] * width;
  69. HistPO[ 2][i] = HistPO[ 2][i] * width;
  70. }
  71. HistTOsum(HistPO, HistPOsum); // 计算原图的累计直方图
  72. for ( int x = 0; x < width; x++)
  73. {
  74. int r = 0, g = 0, b = 0;
  75. bool Isr = true;
  76. bool Isg = true;
  77. bool Isb = true;
  78. for ( int j = 0; j < 256; j++)
  79. {
  80. if (x <= HistPOsum[ 0][j] && Isr)
  81. {
  82. r = j;
  83. Isr = false;
  84. }
  85. if (x <= HistPOsum[ 1][j] && Isg)
  86. {
  87. g = j;
  88. Isg = false;
  89. }
  90. if (x <= HistPOsum[ 2][j] && Isb)
  91. {
  92. b = j;
  93. Isb = false;
  94. }
  95. if (Isr == false && Isg == false && Isb == false)
  96. {
  97. // 颜色在内存中的表示形式为:0xbbggrr (bb=蓝,gg=绿,rr=红),但是显存中的颜色表现形式为 0xrrggbb。
  98. // 所要特别注意这里两者的红色和蓝色是相反的。
  99. setlinecolor( RGB(b, g, r));
  100. line(x, height, x, height + 30);
  101. break;
  102. }
  103. }
  104. }
  105. setfillcolor(RED);
  106. bar( 0, height - 20, 140, height);
  107. setlinestyle(PS_SOLID | PS_ENDCAP_SQUARE, 4);
  108. setlinecolor(RED);
  109. settextcolor(WHITE);
  110. settextstyle( 25, 0, L"微软雅黑", 0, 0, 0, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH);
  111. line( 0, height, width, height);
  112. line( 0, height + 28, width, height + 28);
  113. setbkmode(TRANSPARENT);
  114. outtextxy( 0, height - 20, _T( "颜色直方图色条"));
  115. _getch();
  116. return 0;
  117. }

点击链接加入群聊【C语言/C++编程学习基】:的个人空间_哔哩哔哩_Bilibili,的主页、动态、视频、专栏、频道、收藏、订阅等。哔哩哔哩Bilibili,你感兴趣的视频都在B站。https://space.bilibili.com/1827181878?spm_id_from=333.1007.0.0


转载:https://blog.csdn.net/yx5666/article/details/127909850
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场