继直方图规定化后的研究
由于直方图规定化是根据两张图片的累计直方图进行图像的处理。对于这个处理过程,我尝试了很图像进行替换色系,但是没有找到一个相对合适案例,来体现直方图规定化这个算法的精妙之处。在多次尝试中,我发现一个灰度图像(原图)和一个彩色图像(规定化图)进行直方图规定化处理后,就会得到一个彩色的图像。
我的发现
我们都知道,灰度图像转换为彩色图形,一般情况下都是假彩色。如何将一个灰度图像进行还原成原本的彩色图像,那就是我们需要获得彩色图像的直方图。
创新之处
我利用彩色图像,生成一个色条,该色条与宽度无关。也就是说,我用 1 个像素宽,n 个像素长的有颜色的色条,就可以储存该图像的直方图。通过该色条与一张灰度图像,使用直方图规定化算法就可以将彩色图像还原出来。
具体的用处
-
一种新的图像储存方式,使得图像的存储空间更小。
-
作为直方图规定化的后续研究提供另一种思路。
-
解决一些需要由灰度图像转换为彩色图像的便捷方式。
图像说明
使用程序可以将图像的直方图提取出来,显示到图片下面,如图所示。
源码:
-
-
///
-
// 程序名称:图像处理——提取直方图
-
// 编译环境:Mictosoft Visual Studio 2013, EasyX_20200315(beta)
-
//
-
-
#include<graphics.h>
-
#include<conio.h>
-
#include<math.h>
-
-
// 计算每一种 DN 值在整个像片中所占的比例
-
void Hist(IMAGE *pimg, double num[][256])
-
{
-
DWORD *p =
GetImageBuffer(pimg);
-
for (
int j =
0; j <
256; j++)
-
{
-
double sumr =
0.0;
-
double sumg =
0.0;
-
double sumb =
0.0;
-
for (
int i = pimg->
getwidth() * pimg->
getheight() -
1; i >=
0; i--)
-
{
-
if (j ==
GetRValue(p[i]))
-
{
-
sumr++;
-
}
-
if (j ==
GetGValue(p[i]))
-
{
-
sumg++;
-
}
-
if (j ==
GetBValue(p[i]))
-
{
-
sumb++;
-
}
-
}
-
num[
0][j] = sumr / (pimg->
getwidth() * pimg->
getheight());
-
num[
1][j] = sumg / (pimg->
getwidth() * pimg->
getheight());
-
num[
2][j] = sumb / (pimg->
getwidth() * pimg->
getheight());
-
}
-
}
-
-
// 累计直方图
-
void HistTOsum(double Hist[][256], int Sum[][256])
-
{
-
for (
int j =
0; j <
3; j++)
-
{
-
double mysum =
0;
-
for (
int i =
0; i <
256; i++)
-
{
-
mysum += Hist[j][i];
-
Sum[j][i] = (
int)mysum;
-
}
-
}
-
}
-
-
int main()
-
{
-
int width =
0;
-
int height =
0;
-
IMAGE imgpolt, imgTM;
-
loadimage(&imgpolt, _T(
"bingbing.jpeg"));
// 加载原图
-
width = imgpolt.
getwidth();
-
height = imgpolt.
getheight();
-
initgraph(width, height +
30);
-
setbkcolor(WHITE);
-
cleardevice();
-
putimage(
0,
0, &imgpolt);
-
-
double HistPO[
3][
256];
// 原图像的频率
-
int HistPOsum[
3][
256];
// 原累计直方图
-
-
Hist(&imgpolt, HistPO);
// 计算原图的直方图
-
-
for (
int i =
0; i <
256; i++)
-
{
-
HistPO[
0][i] = HistPO[
0][i] * width;
-
HistPO[
1][i] = HistPO[
1][i] * width;
-
HistPO[
2][i] = HistPO[
2][i] * width;
-
}
-
-
HistTOsum(HistPO, HistPOsum);
// 计算原图的累计直方图
-
-
for (
int x =
0; x < width; x++)
-
{
-
int r =
0, g =
0, b =
0;
-
bool Isr =
true;
-
bool Isg =
true;
-
bool Isb =
true;
-
for (
int j =
0; j <
256; j++)
-
{
-
if (x <= HistPOsum[
0][j] && Isr)
-
{
-
r = j;
-
Isr =
false;
-
}
-
if (x <= HistPOsum[
1][j] && Isg)
-
{
-
g = j;
-
Isg =
false;
-
}
-
if (x <= HistPOsum[
2][j] && Isb)
-
{
-
b = j;
-
Isb =
false;
-
}
-
if (Isr ==
false && Isg ==
false && Isb ==
false)
-
{
-
// 颜色在内存中的表示形式为:0xbbggrr (bb=蓝,gg=绿,rr=红),但是显存中的颜色表现形式为 0xrrggbb。
-
// 所要特别注意这里两者的红色和蓝色是相反的。
-
setlinecolor(
RGB(b, g, r));
-
line(x, height, x, height +
30);
-
break;
-
}
-
}
-
}
-
setfillcolor(RED);
-
bar(
0, height -
20,
140, height);
-
setlinestyle(PS_SOLID | PS_ENDCAP_SQUARE,
4);
-
setlinecolor(RED);
-
settextcolor(WHITE);
-
settextstyle(
25,
0,
L"微软雅黑",
0,
0,
0,
false,
false,
false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH);
-
line(
0, height, width, height);
-
line(
0, height +
28, width, height +
28);
-
setbkmode(TRANSPARENT);
-
outtextxy(
0, height -
20, _T(
"颜色直方图色条"));
-
_getch();
-
return
0;
-
}
点击链接加入群聊【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
查看评论