[图像处理]直方图均衡化
2020-11-28 ~ 2021-11-16
(0)
直方图均衡化
概念
直方图均衡化(Histogram Equalization) 又称直方图平坦化,实质上是对图像进行非 线性拉伸,重新分配图像象元值,使一定灰度范围内象元值的数量大致相等。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一 个较平的分段直方图:如果输出数据分段值较小的话,会产生粗略分类的视觉效果。 直方图是表示数字图像中每一灰度出现频率的统计关系。直方图能给出图像灰度范围、 每个灰度的频度和灰度的分布、整幅图像的平均明暗和对比度等概貌性描述。灰度直方图是灰度级的函数, 反映的是图像中具有该灰度级像素的个数, 其横坐标是灰度级 r, 纵坐 标是该灰度级出现的频率( 即像素的个数) pr( r) , 整个坐标系描述的是图像灰度级的 分布情况, 由此可以看出图像的灰度分布特性, 即若大部分像素集中在低灰度区域, 图 像呈现暗的特性; 若像素集中在高灰度区域, 图像呈现亮的特性。 由于这个算法只是算了灰度图像,所以加入处理彩色图像,只需要对图像 R G B 每个分量 进行直方图累计后拓展,后找到映射关系。
算法
示例
处理前
处理后
源码
///////////////////////////////////////////////////
// 程序名称:图像处理——直方图均衡化
// 编译环境:Mictosoft Visual Studio 2013, EasyX_20200315(beta)
// 作 者:luoyh <2864292458@qq.com>
// 最后修改:2020-11-27
//
#include<graphics.h>
#include<conio.h>
class Algorithm
{
public:
Algorithm(IMAGE *img, int width, int heigth);
void Histogram(); // 直方图
private:
IMAGE *pimg;
int WIDTH;
int HEIGHT;
};
Algorithm::Algorithm(IMAGE *img, int width, int height)
{
pimg = img;
WIDTH = width;
HEIGHT = height;
};
void Algorithm::Histogram() // 直方图
{
DWORD* p_data = GetImageBuffer(pimg);
int height = HEIGHT;
int wide = WIDTH;
double pr[256], pg[256], pb[256];
int size = HEIGHT * WIDTH;
for (int p = 0; p <= 255; p++)
{
int nr = 0, ng = 0, nb = 0;
for (int j = 0; j < height; j++)
{
for (int i = 0; i < wide; i++)
{
if (p == GetRValue(p_data[j*wide + i]))
{
nr++;
}
if (p == GetGValue(p_data[j*wide + i]))
{
ng++;
}
if (p == GetBValue(p_data[j*wide + i]))
{
nb++;
}
}
}
pr[p] = nr;
pg[p] = ng;
pb[p] = nb;
}
double sr[256] = { 0 }, sg[256] = { 0 }, sb[256] = { 0 };
double aver = 0;
double aveg = 0;
double aveb = 0;
for (int i = 0; i <= 255; i++)
{
aver += pr[i] / size;
sr[i] = aver;
aveg += pg[i] / size;
sg[i] = aveg;
aveb += pb[i] / size;
sb[i] = aveb;
}
double ssr[255] = { 0 }, ssg[255] = { 0 }, ssb[255] = { 0 };
for (int i = 0; i < 255; i++)
{
ssr[i] = (int)(((255 - 1) - 0) * sr[i] + 0.5);
ssg[i] = (int)(((255 - 1) - 0) * sg[i] + 0.5);
ssb[i] = (int)(((255 - 1) - 0) * sb[i] + 0.5);
}
int r = 0, g = 0, b = 0;
double myr = 0, myg = 0, myb = 0;
for (int j = 0; j < height; j++)
{
for (int i = 0; i < wide; i++)
{
while (GetRValue(p_data[j * wide + i]) != r)
{
r++;
if (r == 255)
break;
}
if (GetRValue(p_data[j * wide + i]) == r)
{
myr = ssr[r];
}
r = 0;
while (GetGValue(p_data[j * wide + i]) != g)
{
g++;
if (g == 255)
break;
}
if (GetGValue(p_data[j * wide + i]) == g)
{
myg = ssg[g];
}
g = 0;
while (GetBValue(p_data[j * wide + i]) != b)
{
b++;
if (b == 255)
break;
}
if (GetBValue(p_data[j * wide + i]) == b)
{
myb = ssb[b];
}
b = 0;
p_data[j * wide + i] = RGB(myr, myg, myb);
}
}
};
int main()
{
int width = 0;
int height = 0;
IMAGE g_img;
loadimage(&g_img, _T("src.jpg")); // 加载图片
width = g_img.getwidth();
height = g_img.getheight();
initgraph(width, height);
putimage(0,0,&g_img);
_getch();
Algorithm myA(&g_img, width, height);
myA.Histogram();
putimage(0, 0, &g_img);
_getch();
return 0;
}
作 者:简 单
Q Q: 2864292458
邮 箱:2864292458@qq.com
添加评论
取消回复