数字图像处理学习笔记(1.3)---位图的读写、几何变换、傅里叶变换、直方图均衡
图像的直方图均衡
#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; }