写在前面:
1.这次实验在代码规范和类封装上下了一些功夫,花了很多时间。
2.这个星期突然有很多事情要忙,实在是有点顾不上课程留下的作业,所以略微拖了一点时间。
3.用c++去实现真的挺有成就感的,虽然我对图像处理不是特别感兴趣,但是在其中解决问题的过程,调试通过的那一时刻,确实能带给我很多快乐。
4.以后要忙的事情突然多了许多,不定期拖更或许是常态hhh。
5.anyway,enjoy your life
文章结构:
- 回顾前文
- 实验结果
- 关键实验代码(类的封装)
- 总结感想
回顾前文
上一篇文章
1.首先小声说个对不起,因为,上一篇文章分享出去的gihub链接一开始忘记推送了,所以一开始有的人会发现它是个半成品hhh。
2. 上一篇文章在结尾处修正了两个小错误。
实验结果
- 线性变换
- 非线性变换
- 分段线性变换
- 直方图均衡
-
低通滤波
-
高通滤波
- 中值滤波
- 最大值滤波
- 最小值滤波
10.伪彩色增强
关键实验代码(类的封装)
线性变换和非线性变换就不多说了,就是简单的函数映射。
下面是各种滤波,我封装进了我的类,大家可以通过include 我的类 直接实现相关功能。
USER_FILTER.h 滤波类
#pragma once
/*
**********************************************************************
* 模块名称: USER_FILTER
* 摘 要: 滤波类
* 当前版本: 1.0
* 作 者: guangjie2333
* 完成日期: 2021-10-22
* 内 容:
* 注 意: 整个模块基于RGB三通道bmp图
*********************************************************************/
/*
**********************************************************************
* 包含头文件
**********************************************************************
*/
#include "USER_DEFINE.h"
/*
**********************************************************************
* 用户字定义类
**********************************************************************
*/
class USER_FILTER
{
//variable
public:
BYTE* pixelArray;
int ArraySize;
int high;
int width;
BYTE* R_array; //RGB三个分量分别做滤波
BYTE* G_array;
BYTE* B_array;
protected:
private:
//低通滤波模板
int lowFilterTemplate[9] = {1 ,1 , 1 ,
1 , 1 , 1 ,
1 , 1 , 1 };
//高通滤波模板
int HighFilterTemplate[9] = { 0, -1, 0,
-1, 5, -1,
0, -1, 0 };
//function
public:
USER_FILTER(BYTE* array, int h, int w);
~USER_FILTER();
void LowFilter();
void HighFilter();
void MidFilter();
void MaxFilter();
void MinFilter();
protected:
void SeparateRGB();
void UnionRGB();
private:
void Convolution(int flag);//图像模板卷积
void DealLowConvolution(BYTE** matrix);
void DealHighConvolution(BYTE** matrix);
void DealMidConvolution(BYTE** matrix);
void DealMaxConvolution(BYTE** matrix);
void DealMinConvolution(BYTE** matrix);
};
USER_FILTER.cpp 滤波类
#include "pch.h"
#include "USER_FILTER.h"
/*
********************************************************************************
********************************************************************************
* 构造&析构函数
********************************************************************************
********************************************************************************
*/
/*
******************************************************************************
* 函数名称: USER_FILTER
* 函数功能: 构造(初始化)函数
* 输入参数: array :bmp图像的RGB三通道数据, h :图像高 w:图像宽
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
USER_FILTER::USER_FILTER(BYTE* array, int h, int w)
{
pixelArray = array;
high = h;
width = w;
ArraySize = high * width * 3;
R_array = (BYTE*)new char[ArraySize / 3 + 1];
G_array = (BYTE*)new char[ArraySize / 3 + 1];
B_array = (BYTE*)new char[ArraySize / 3 + 1];
}
/*
******************************************************************************
* 函数名称: ~USER_HIS_EQU
* 函数功能: 析构函数,将动态开辟的空间清除
* 输入参数: none
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
USER_FILTER::~USER_FILTER()
{
delete[] R_array;
delete[] G_array;
delete[] B_array;
}
/*
********************************************************************************
********************************************************************************
* 接口函数
********************************************************************************
********************************************************************************
*/
/*
******************************************************************************
* 函数名称: LowFilter
* 函数功能: 实现一幅图像的低通滤波
* 输入参数: none
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::LowFilter()
{
SeparateRGB();//分离RGB分别做滤波
Convolution(0);//0代表低通滤波卷积
UnionRGB();
}
/*
******************************************************************************
* 函数名称: HighFilter
* 函数功能: 实现一幅图像的高通滤波
* 输入参数: none
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::HighFilter()
{
SeparateRGB();//分离RGB分别做滤波
Convolution(1);//1代表低通滤波卷积
UnionRGB();
}
/*
******************************************************************************
* 函数名称: MidFilter
* 函数功能: 实现一幅图像的中值滤波
* 输入参数: none
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::MidFilter()
{
SeparateRGB();//分离RGB分别做滤波
Convolution(2);//2代表中值滤波卷积
UnionRGB();
}
/*
******************************************************************************
* 函数名称: MaxFilter
* 函数功能: 实现一幅图像的最大值滤波
* 输入参数: none
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::MaxFilter()
{
SeparateRGB();//分离RGB分别做滤波
Convolution(3);//3代表最大值滤波卷积
UnionRGB();
}
/*
******************************************************************************
* 函数名称: MinFilter
* 函数功能: 实现一幅图像的最小值滤波
* 输入参数: none
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::MinFilter()
{
SeparateRGB();//分离RGB分别做滤波
Convolution(4);//4代表最小值滤波卷积
UnionRGB();
}
/*
********************************************************************************
********************************************************************************
* 功能函数
********************************************************************************
********************************************************************************
*/
/*
******************************************************************************
* 函数名称: SeparateRGB
* 函数功能: 分离RGB分量
* 输入参数: array :bmp图像的RGB三通道数据, ArraySize:array数据大小
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::SeparateRGB()
{
int j = 0;
for (int i = 0; i < ArraySize; i = i + 3)
{
R_array[j] = pixelArray[i + 2];
G_array[j] = pixelArray[i + 1];
B_array[j] = pixelArray[i + 0];
j++;
}
}
/*
******************************************************************************
* 函数名称: UnionRGB
* 函数功能: RGB均衡化后的分量整合
* 输入参数: array : 图像数据 ArraySize:数据大小
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::UnionRGB()
{
int j = 0;
for (int i = 0; i < ArraySize; i = i + 3)
{
pixelArray[i + 2] = R_array[j];
pixelArray[i + 1] = G_array[j];
pixelArray[i + 0] = B_array[j];
j++;
}
}
/*
******************************************************************************
* 函数名称: Convolution
* 函数功能: RGB 实现图像卷积
* 输入参数: flag : 0 低通滤波模板卷积
* 1 高通滤波模板卷积
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:中值,max,min的本质在于排序算法
尽管数据量不大,但是我认为排序算法的选取很重要,优秀的工程师拒绝冒泡
我新建了一个类叫算法类,里面有我大三时候写的快速排序的算法(现在具体实现忘记了hhh)
*******************************************************************************
*/
void USER_FILTER::Convolution(int flag)
{
//动态建立二维数组
BYTE** matrixR;
BYTE** matrixG;
BYTE** matrixB;
matrixR = new BYTE * [high];
matrixG = new BYTE * [high];
matrixB = new BYTE * [high];
for (int j = 0; j < high; j++)
{
matrixR[j] = new BYTE[width];
matrixG[j] = new BYTE[width];
matrixB[j] = new BYTE[width];
}
//初始化
int k = 0;
for (int i = 0; i < high; i++)
{
for (int j = 0; j < width; j++)
{
matrixR[i][j] = R_array[k];
matrixG[i][j] = G_array[k];
matrixB[i][j] = B_array[k];
k++;
}
}
//模板卷积 &MAX &MIN &MID滤波
switch (flag)
{
case 0 :
DealLowConvolution(matrixR); //其实用一个函数实现也可以,但是我想保留函数的纯粹性
DealLowConvolution(matrixG);
DealLowConvolution(matrixB);
break;
case 1 :
DealHighConvolution(matrixR);
DealHighConvolution(matrixG);
DealHighConvolution(matrixB);
break;
case 2:
DealMidConvolution(matrixR);
DealMidConvolution(matrixG);
DealMidConvolution(matrixB);
break;
case 3:
DealMaxConvolution(matrixR);
DealMaxConvolution(matrixG);
DealMaxConvolution(matrixB);
break;
case 4:
DealMinConvolution(matrixR);
DealMinConvolution(matrixG);
DealMinConvolution(matrixB);
break;
default:
break;
}
//卷积结果回传
k = 0;
for (int i = 0; i < high; i++)
{
for (int j = 0; j < width; j++)
{
R_array[k] = matrixR[i][j];
G_array[k] = matrixG[i][j];
B_array[k] = matrixB[i][j];
k++;
}
}
//释放
for (int j = 0; j < high; j++)
{
delete[] matrixR[j];
delete[] matrixG[j];
delete[] matrixB[j];
}
delete[] matrixR;
delete[] matrixG;
delete[] matrixB;
}
/*
******************************************************************************
* 函数名称: DealLowConvolution
* 函数功能: 处理低通滤波
* 输入参数: matrix:二维矩阵
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER :: DealLowConvolution(BYTE** matrix)
{
//动态建立二维数组
BYTE** matrixNew;
matrixNew = new BYTE * [high];
for (int j = 0; j < high; j++)
{
matrixNew[j] = new BYTE[width];
}
//初始化
for (int i = 0; i < high; i++)
{
for (int j = 0; j < width; j++)
{
matrixNew[i][j] = matrix[i][j];
}
}
//卷积
for (int i = 1; i < high - 1 ; i++)
{
for (int j = 1; j < width - 1; j++)
{
matrix[i][j] = matrixNew[i - 1][j - 1] * lowFilterTemplate[0] +
matrixNew[i - 1][j - 0] * lowFilterTemplate[1] +
matrixNew[i - 1][j + 1] * lowFilterTemplate[2] +
matrixNew[i - 0][j - 1] * lowFilterTemplate[3] +
matrixNew[i - 0][j - 0] * lowFilterTemplate[4] +
matrixNew[i - 0][j + 1] * lowFilterTemplate[5] +
matrixNew[i + 1][j - 1] * lowFilterTemplate[6] +
matrixNew[i + 1][j - 0] * lowFilterTemplate[7] +
matrixNew[i + 1][j + 1] * lowFilterTemplate[8] ;
matrix[i][j] /= 9;
matrix[i][j] = matrix[i][j] < 0 ? 0 : matrix[i][j];
matrix[i][j] = matrix[i][j] > 255 ? 255 : matrix[i][j];
}
}
//释放
for (int j = 0; j < high; j++)
{
delete[] matrixNew[j];
}
delete[] matrixNew;
}
/*
******************************************************************************
* 函数名称: DealHighConvolution
* 函数功能: 处理高通滤波
* 输入参数: matrix:二维矩阵
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::DealHighConvolution(BYTE** matrix)
{
//动态建立二维数组
BYTE** matrixNew;
matrixNew = new BYTE * [high];
for (int j = 0; j < high; j++)
{
matrixNew[j] = new BYTE[width];
}
//初始化
for (int i = 0; i < high; i++)
{
for (int j = 0; j < width; j++)
{
matrixNew[i][j] = matrix[i][j];
}
}
//卷积
for (int i = 1; i < high - 1; i++)
{
for (int j = 1; j < width - 1; j++)
{
matrix[i][j] = matrixNew[i - 1][j - 1] * HighFilterTemplate[0] +
matrixNew[i - 1][j - 0] * HighFilterTemplate[1] +
matrixNew[i - 1][j + 1] * HighFilterTemplate[2] +
matrixNew[i - 0][j - 1] * HighFilterTemplate[3] +
matrixNew[i - 0][j - 0] * HighFilterTemplate[4] +
matrixNew[i - 0][j + 1] * HighFilterTemplate[5] +
matrixNew[i + 1][j - 1] * HighFilterTemplate[6] +
matrixNew[i + 1][j - 0] * HighFilterTemplate[7] +
matrixNew[i + 1][j + 1] * HighFilterTemplate[8] ;
matrix[i][j] = matrix[i][j] < 0 ? 0 : matrix[i][j];
matrix[i][j] = matrix[i][j] > 255 ? 255 : matrix[i][j];
}
}
//释放
for (int j = 0; j < high; j++)
{
delete[] matrixNew[j];
}
delete[] matrixNew;
}
/*
******************************************************************************
* 函数名称: DealMidConvolution
* 函数功能: 处理中值滤波
* 输入参数: matrix:二维矩阵
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::DealMidConvolution(BYTE** matrix)
{
//动态建立二维数组
BYTE** matrixNew;
matrixNew = new BYTE * [high];
for (int j = 0; j < high; j++)
{
matrixNew[j] = new BYTE[width];
}
//初始化
for (int i = 0; i < high; i++)
{
for (int j = 0; j < width; j++)
{
matrixNew[i][j] = matrix[i][j];
}
}
//卷积
for (int i = 1; i < high - 1; i++)
{
for (int j = 1; j < width - 1; j++)
{
int TmpArray[9] = {
matrixNew[i - 1][j - 1],
matrixNew[i - 1][j - 0],
matrixNew[i - 1][j + 1],
matrixNew[i - 0][j - 1],
matrixNew[i - 0][j - 0],
matrixNew[i - 0][j + 1],
matrixNew[i + 1][j - 1],
matrixNew[i + 1][j - 0],
matrixNew[i + 1][j + 1]
};
//排序
USER_ALG user_alg;
user_alg.QuickSort(TmpArray,9);
//中位数
matrix[i][j] = TmpArray[(int)9/2];
}
}
//释放
for (int j = 0; j < high; j++)
{
delete[] matrixNew[j];
}
delete[] matrixNew;
}
/*
******************************************************************************
* 函数名称: DealMaxConvolution
* 函数功能: 处理最大值滤波
* 输入参数: matrix:二维矩阵
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::DealMaxConvolution(BYTE** matrix)
{
//动态建立二维数组
BYTE** matrixNew;
matrixNew = new BYTE * [high];
for (int j = 0; j < high; j++)
{
matrixNew[j] = new BYTE[width];
}
//初始化
for (int i = 0; i < high; i++)
{
for (int j = 0; j < width; j++)
{
matrixNew[i][j] = matrix[i][j];
}
}
//卷积
for (int i = 1; i < high - 1; i++)
{
for (int j = 1; j < width - 1; j++)
{
int TmpArray[9] = {
matrixNew[i - 1][j - 1],
matrixNew[i - 1][j - 0],
matrixNew[i - 1][j + 1],
matrixNew[i - 0][j - 1],
matrixNew[i - 0][j - 0],
matrixNew[i - 0][j + 1],
matrixNew[i + 1][j - 1],
matrixNew[i + 1][j - 0],
matrixNew[i + 1][j + 1]
};
//排序
USER_ALG user_alg;
user_alg.QuickSort(TmpArray, 9);
//最大值
matrix[i][j] = TmpArray[8];
}
}
//释放
for (int j = 0; j < high; j++)
{
delete[] matrixNew[j];
}
delete[] matrixNew;
}
/*
******************************************************************************
* 函数名称: DealMinConvolution
* 函数功能: 处理最小值滤波
* 输入参数: matrix:二维矩阵
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-22日
* 注 意:
*******************************************************************************
*/
void USER_FILTER::DealMinConvolution(BYTE** matrix)
{
//动态建立二维数组
BYTE** matrixNew;
matrixNew = new BYTE * [high];
for (int j = 0; j < high; j++)
{
matrixNew[j] = new BYTE[width];
}
//初始化
for (int i = 0; i < high; i++)
{
for (int j = 0; j < width; j++)
{
matrixNew[i][j] = matrix[i][j];
}
}
//卷积
for (int i = 1; i < high - 1; i++)
{
for (int j = 1; j < width - 1; j++)
{
int TmpArray[9] = {
matrixNew[i - 1][j - 1],
matrixNew[i - 1][j - 0],
matrixNew[i - 1][j + 1],
matrixNew[i - 0][j - 1],
matrixNew[i - 0][j - 0],
matrixNew[i - 0][j + 1],
matrixNew[i + 1][j - 1],
matrixNew[i + 1][j - 0],
matrixNew[i + 1][j + 1]
};
//排序
USER_ALG user_alg;
user_alg.QuickSort(TmpArray, 9);
//最小值
matrix[i][j] = TmpArray[0];
}
}
//释放
for (int j = 0; j < high; j++)
{
delete[] matrixNew[j];
}
delete[] matrixNew;
}
USER_HIS_EQU.h 直方图均衡类
#pragma once
/*
**********************************************************************
* 模块名称: USER_HIS_EQU
* 摘 要: 直方图均衡化类
* 当前版本: 1.0
* 作 者: guangjie2333
* 完成日期: 2021-10-19
* 内 容:
* 注 意: none
*********************************************************************/
/*
**********************************************************************
* 包含头文件
**********************************************************************
*/
#include "USER_DEFINE.h"
/*
**********************************************************************
* 用户字定义类
**********************************************************************
*/
class USER_HIS_EQU
{
//variable
private:
BYTE* R_array; //RGB三个分量分别做均衡化
BYTE* G_array;
BYTE* B_array;
BYTE* array;
int ArraySize;
//function
public:
USER_HIS_EQU(BYTE* ARRAY, int ARRAYSIZE);
~USER_HIS_EQU();
void HistogramEqualization();//直方图均衡化的接口函数
protected:
void SeparateRGB(BYTE* array, int ArraySize);
void UnionRGB(BYTE* array, int ArraySize);
float Array_N_Sum(float* array, int N);//求数组前N项和
private:
void OneColorHistogramEqualization(BYTE* array, int ArraySize);
void Classify(int OneColorVal, float* Grade); //输入一个0-255值,以32长度为一组,输出组数
void Normalization(float* Grade, int ArraySize); //输入均衡化的分组数组,每个元素除以单通道颜色总数
void CreatNewGrade(float* Grade);
void UpdateArray(BYTE* array, float* Grade, int ArraySize);//将图像数据根据均衡化的结果做更新
};
USER_HIS_EQU.cpp 直方图均衡类
#include "pch.h"
#include "USER_HIS_EQU.h"
/*
********************************************************************************
********************************************************************************
* 构造&析构函数
********************************************************************************
********************************************************************************
*/
/*
******************************************************************************
* 函数名称: USER_HIS_EQU
* 函数功能: 构造(初始化)函数
* 输入参数: ARRAY :bmp图像的RGB三通道数据, ARRAYSIZE :array的长度
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
USER_HIS_EQU::USER_HIS_EQU(BYTE* ARRAY, int ARRAYSIZE)
{
array = ARRAY;
ArraySize = ARRAYSIZE;
R_array = (BYTE*)new char[ArraySize / 3 + 1];
G_array = (BYTE*)new char[ArraySize / 3 + 1];
B_array = (BYTE*)new char[ArraySize / 3 + 1];
}
/*
******************************************************************************
* 函数名称: ~USER_HIS_EQU
* 函数功能: 析构函数,将动态开辟的空间清除
* 输入参数: none
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
USER_HIS_EQU::~USER_HIS_EQU()
{
delete[] R_array;
delete[] G_array;
delete[] B_array;
}
/*
********************************************************************************
********************************************************************************
* 接口函数
********************************************************************************
********************************************************************************
*/
/*
******************************************************************************
* 函数名称: HistogramEqualization
* 函数功能: 直方图均衡化的接口函数
* 输入参数: void
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_HIS_EQU::HistogramEqualization()
{
//分离RGB
SeparateRGB(array, ArraySize);
//RGB分别直方图均衡化
OneColorHistogramEqualization(R_array, ArraySize / 3);
OneColorHistogramEqualization(G_array, ArraySize / 3);
OneColorHistogramEqualization(B_array, ArraySize / 3);
//更新图像数据
UnionRGB(array, ArraySize);
}
/*
********************************************************************************
********************************************************************************
* 功能函数
********************************************************************************
********************************************************************************
*/
/*
******************************************************************************
* 函数名称: SeparateRGB
* 函数功能: 分离RGB分量
* 输入参数: array :bmp图像的RGB三通道数据, ArraySize :array的长度
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_HIS_EQU :: SeparateRGB(BYTE* array, int ArraySize)
{
int j = 0;
for (int i = 0; i < ArraySize; i = i + 3)
{
R_array[j] = array[i + 2];
G_array[j] = array[i + 1];
B_array[j] = array[i + 0];
j++;
}
}
/*
******************************************************************************
* 函数名称: OneColorHistogramEqualization
* 函数功能: 单通道直方图均衡化
* 输入参数: array :bmp图像的单通道数据, ArraySize :array的长度
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_HIS_EQU::OneColorHistogramEqualization(BYTE* array, int ArraySize)
{
float Grade[8] = {0}; //均衡化的分组计数数组
//分级
for (int i = 0; i < ArraySize; i++)
{
Classify(array[i], Grade);
}
//归一化
Normalization(Grade,ArraySize);
//新的分级
CreatNewGrade(Grade);
//更新灰度值
UpdateArray(array, Grade, ArraySize);
}
/*
******************************************************************************
* 函数名称: Classify
* 函数功能: 将0-255的图像分成8个等级
* 输入参数: OneColorVal:0-255的 R/G/B值 * Grade:均衡化的分组计数数组
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_HIS_EQU :: Classify(int OneColorVal, float* Grade)
{
for (int i = 0; i < 8; i++)
{
if ((OneColorVal >= 32 * i) && (OneColorVal < 32*i + 32))
{
Grade[i]++;
}
}
}
/*
******************************************************************************
* 函数名称: Normalization
* 函数功能: 归一化
* 输入参数: 分级数组Grade
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_HIS_EQU :: Normalization(float* Grade,int ArraySize)
{
for (int i = 0; i < 8; i++)
{
Grade[i] /= ArraySize;
}
}
/*
******************************************************************************
* 函数名称: CreatNewGrade
* 函数功能: 将Grade数组的内容变成灰度值
* 输入参数: 分级数组Grade
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意: 创建新的分级,i代表 分级数组的下标,j代表0-8的分级,经过两个循环,Grade的内容就变成了灰度值
这个函数可能脑洞比较大
*******************************************************************************
*/
void USER_HIS_EQU::CreatNewGrade(float* Grade)
{
float newGrade[8] = { 0 };
//均衡化
for (int i = 0; i < 8; i++)
{
newGrade[i] = Array_N_Sum(Grade,i) * 7;
}
//变换成灰度值
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (newGrade[i] >= j && newGrade[i] <= j + 1)
{
int tmp = round(newGrade[i]);
Grade[i] = (32 * tmp + 32*(tmp + 1))/2;
break;
}
}
}
}
/*
******************************************************************************
* 函数名称: UpdateArray
* 函数功能: 将图像数据根据均衡化的结果做更新
* 输入参数: 分级数组Grade
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_HIS_EQU::UpdateArray(BYTE* array, float* Grade, int ArraySize)
{
for (int i = 0; i < ArraySize; i++)
{
for (int j = 0; j < 8; j++)
{
if ((array[i] >= 32 * j) && (array[i] < 32 * j + 32))
{
array[i] = (int)Grade[j];
break;
}
}
}
}
/*
******************************************************************************
* 函数名称: UnionRGB
* 函数功能: RGB均衡化后的分量整合
* 输入参数: array : 图像数据 ArraySize:数据大小
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
void USER_HIS_EQU ::UnionRGB(BYTE* array, int ArraySize)
{
int j = 0;
for (int i = 0; i < ArraySize; i = i + 3)
{
array[i + 2] = R_array[j];
array[i + 1] = G_array[j];
array[i + 0] = B_array[j];
j++;
}
}
/*
******************************************************************************
* 函数名称: Array_N_Sum
* 函数功能: 求数组前N项和
* 输入参数: 数组 , N
* 输出参数: none
* 返 回 值: void
* 创建日期: 2021年-10月-19日
* 注 意:
*******************************************************************************
*/
float USER_HIS_EQU::Array_N_Sum(float* array, int N)
{
float res = 0;
for (int i = 0; i <= N; i++)
{
res += array[i];
}
return res;
}
关于伪彩色增强
pixelArray 是 256 的灰度图片数据
newPixelArray 是RGB 24位 的伪彩色图像数据
//拷贝原数据
DWORD dataBytes = bmpdata.bmpHeader.bfSize - bmpdata.bmpHeader.bfOffBits;//图像数据大小,单位为字节
BYTE* pixelArray = (BYTE*)new char[dataBytes];
memcpy(pixelArray, bmpdata.pBmpData, dataBytes);
BYTE* newPixelArray = (BYTE*)new char[dataBytes * 3];;
for (int i = 0; i < dataBytes ; i++)
{
//不好意思,用了这么恶心的else if
if ((pixelArray[i] >= 0) && (pixelArray[i] < 63))
{
newPixelArray[i * 3 + 0] = 255;//B
newPixelArray[i * 3 + 1] = 254 - 4 * pixelArray[i];//G
newPixelArray[i * 3 + 2] = 0;//R
}
else if ((pixelArray[i] >= 64) && (pixelArray[i] < 127))
{
newPixelArray[i * 3 + 0] = 510 - 4 * pixelArray[i];//B
newPixelArray[i * 3 + 1] = 4 * pixelArray[i] - 254;//G
newPixelArray[i * 3 + 2] = 0;//R
}
else if ((pixelArray[i] >= 128) && (pixelArray[i] < 191))
{
newPixelArray[i * 3 + 0] = 0;//B
newPixelArray[i * 3 + 1] = 255 ;//G
newPixelArray[i * 3 + 2] = 4 * pixelArray[i] - 510;//R
}
else if ((pixelArray[i] >= 192) && (pixelArray[i] < 255))
{
newPixelArray[i * 3 + 0] = 0;//B
newPixelArray[i * 3 + 1] = 1022 - 4 * pixelArray[i];//G
newPixelArray[i * 3 + 2] = 255;//R
}
}
总结感想
敲代码整个过程让人全心投入,经常不知不觉一个下午一个晚上就没了。
以前敲代码也是在调别人的库,现在过一下自己帮别人写库的瘾,我觉得这是一件很cool的事情。
这次的工程我更加注重代码的规范性,就如雷军所说“代码要写的像诗一样”。
同时我花了许多时间在工程框架的构建上,从滤波类USER_FILTER可以看出函数的分层特别明确,代码可读性非常强。
虽然在卷积时寻找最大值和最小值只有9个数,但是我还是决定引入快速排序算法。
那些什么类似“提高了解决困难的能力”的话我就不想扯了,其中肯定会有一些bug,等后面遇到了再回来改吧。
实验的工程链接如下。