图像的直方图均衡
#include"bmp.h"
#include<cmath>
#include<cstring>
#include<cstdio>
#include<iostream>
int* m_histArray;
void Bitmap::releasedHist()
{
if (m_histArray != NULL)
delete[] m_histArray;
}
//说明:灰度图像统计直方图,m_histArray中存放了当前图像的统计数据
int* Bitmap::computeHistGray()
{
//只处理灰度图像
if (bitCount != 8)
return NULL;
//循环变量
int i, j;
m_histArray = new int[256];
//直方图数组清0
for (i = 0; i<256; i++)
m_histArray[i] = 0;
//每行像素所占字节数
int lineByte = (width_p*bitCount/ 8 + 3) / 4 * 4;
//中间变量
int temp;
//统计灰度直方图
for (i = 0; i<17; i++){
for (j = 0; j<width_p; j++){
temp = *(dataBuf + i*lineByte + j);
m_histArray[temp]++;
}
}
return m_histArray;
}
//说明:彩色图像亮度直方图,m_histArray中存放了当前图像的亮度统计数据
int* Bitmap::computeHistBrightness()
{
m_histArray = new int[256];
//彩色图像有效
if (bitCount != 24)
return NULL;
//循环变量
int i, j;
//直方图数组清0
for (i = 0; i<256; i++)
m_histArray[i] = 0;
//每行像素所占字节数
int lineByte = (width_p*bitCount / 8 + 3) / 4 * 4;
//中间变量
int temp;
//统计亮度直方图
for (i = 0; i<height_p; i++){
for (j = 0; j<width_p; j++){
temp = 0.11**(dataBuf + i*lineByte + j * 3 + 0)
+ 0.59**(dataBuf + i*lineByte + j * 3 + 1)
+ 0.30**(dataBuf + i*lineByte + j * 3 + 2) + 0.5;
m_histArray[temp]++;
}
}
return m_histArray;
}
//说明:彩色图像红色通道直方图,对图像红色分量的统计
int* Bitmap::computeHistRed()
{
m_histArray = new int[256];
//彩色图像有效
if (bitCount != 24)
return NULL;
//循环变量
int i, j;
//直方图数组清0
for (i = 0; i<256; i++)
m_histArray[i] = 0;
//每行像素所占字节数
int lineByte = (width_p*bitCount / 8 + 3) / 4 * 4;
//中间变量
int temp;
//统计红色通道直方图
for (i = 0; i<height_p; i++){
for (j = 0; j<width_p; j++){
temp = *(dataBuf + i*lineByte + j * 3 + 2);
m_histArray[temp]++;
}
}
return m_histArray;
}
//说明:彩色图像绿色通道直方图,对图像绿色分量的统计
int* Bitmap::computeHistGreen()
{
m_histArray = new int[256];
//彩色图像有效
if (bitCount != 24)
return NULL;
//循环变量
int i, j;
//直方图数组清0
for (i = 0; i<256; i++)
m_histArray[i] = 0;
//每行像素所占字节数
int lineByte = (width_p*bitCount / 8 + 3) / 4 * 4;
//中间变量
int temp;
//统计绿色通道直方图
for (i = 0; i<height_p; i++){
for (j = 0; j<width_p; j++){
temp = *(dataBuf + i*lineByte + j * 3 + 1);
m_histArray[temp]++;
}
}
return m_histArray;
}
//说明:彩色图像蓝色通道直方图,对图像蓝色分量的统计
int* Bitmap::computeHistBlue()
{
m_histArray = new int[256];
//彩色图像有效
if (bitCount != 24)
return NULL;
//循环变量
int i, j;
//直方图数组清0
for (i = 0; i<256; i++)
m_histArray[i] = 0;
//每行像素所占字节数
int lineByte = (width_p*bitCount / 8 + 3) / 4 * 4;
//中间变量
int temp;
//统计蓝色通道直方图
for (i = 0; i<height_p; i++){
for (j = 0; j<width_p; j++){
temp = *(dataBuf + i*lineByte + j * 3 + 0);
m_histArray[temp]++;
}
}
return m_histArray;
}
//说明:计算直方图均值,直方图的统计特征
float Bitmap::computeHistAverage()
{
if (bitCount == 8)
m_histArray = computeHistGray();
else if (bitCount == 24)
m_histArray = computeHistBrightness();
else
return 0;
int sum = 0;
for (int i = 0; i<256; i++)
sum += i*m_histArray[i];
float m_average = (float)sum / (width_p*height_p);
delete[] m_histArray;
return m_average;
}
//说明:计算直方图方差,直方图的统计特征
float Bitmap::computeDeviation()
{
if (bitCount == 8)
m_histArray = computeHistGray();
else if (bitCount == 24)
m_histArray = computeHistBrightness();
else
return 0;
float m_average = computeHistAverage();
double deviation = 0;
for (int i = 0; i<256; i++)
deviation += (i - m_average)*(i - m_average)*m_histArray[i];
deviation /= (width_p*height_p);
float m_deviation = sqrt(deviation);
delete[] m_histArray;
return deviation;
}
//说明:直方图均衡,该函数只对灰度图像有效
void Bitmap::histEqualization()
{
// 只处理灰度
if (bitCount != 8)
return;
//输出图像每行像素所占的字节数
int lineByte = (width_p*bitCount / 8 + 3) / 4 * 4;
unsigned char* dataBufOut = new unsigned char[lineByte*height_p];
//循环变量
int i, j;
//映射表
double map[256];
//中间变量
int sum, tmp;
//统计灰度直方图
m_histArray=computeHistGray();
//计算映射表
sum = 0;
for (i = 0; i<256; i++){
sum += m_histArray[i];
map[i] = (double)sum * 255 / (width_p*height_p) + 0.5;
}
//输出数据赋值
for (i = 0; i<height_p; i++)
{
for (j = 0; j<width_p; j++)
{
tmp = *(dataBuf + i*lineByte + j);
*(dataBufOut + i*lineByte + j) = (int)map[tmp];
}
}
delete[] dataBuf;
dataBuf = dataBufOut;
}
测试:
#include"bmp.h"
#include<iostream>
using namespace std;
int main()
{
char* fileName = "qianxun.bmp";
Bitmap* bmp = new Bitmap();
bmp->read(fileName);
bmp->histEqualization(); bmp->releasedHist();
bmp->write("fourier.bmp");
delete bmp;
return 1;
}