ENVI打开图像实现2%线性拉伸的原理是:“遥感图像数据大多为16位,在显示时要将其拉伸到0-255的区间范围,ENVI软件打开图像时默认使用2%的线性拉伸,思路是将直方图累积在2%和98%之间的像元值拉伸,取直方图累积在2%处对应的光谱值为MinValue,98%处对应的光谱值为MaxValue,那么可解释为如果像元值大于MinValue且小于MaxValue,则将其拉伸至0-255;如果像元值小于MinValue,那么将其改为MinValue;如果像元值大于MaxValue,那么将其改为255。”
您在原函数中定义的操作是将灰度值进行线性变化,这是不符合此处“灰度值线性变换”定义的。当然,我这么说是假设您当时实习的要求和我们这次相同,均为“图像点运算:灰度线性变换(%2线性拉伸)”
如果是,那么可以这样改:(我的类叫ProcessFunctions)
头文件中加入public函数:
ProcessFunctions GrayScale(ProcessFunctions img, float ratio);
函数定义:
ProcessFunctions ProcessFunctions::GrayScale(ProcessFunctions img, float ratio) {
cv::Mat mimg = this->matrixCopy.clone();
mimg.convertTo(mimg, CV_32FC1);//像素值转换为单通道的 32 位浮点型数据类型
int rows = this->matrixCopy.rows;
int cols = this->matrixCopy.cols;
int counts = rows * cols;
mimg = mimg.reshape(1, counts);//一行counts列
// 计算需要找到的位置
int totalElements = mimg.cols;
int maxBottomPercent = totalElements * 0.02; // 最小的2%
int minTopPercent = totalElements * 0.98; // 最大的2%
// 初始化最小的前2%中最大的数值和最大的2%中最小的数值
float maxMinBottomPercent = 0;
float minMaxTopPercent = 0;
// 遍历一维数组找到最小的前2%中最大的数值和最大的2%中最小的数值
int PixCounter[256] = { 0 }; // 初始化数组,假设是8位图像,范围为0-255
// 遍历一维Mat数组,更新PixCounter
for (int i = 0; i < mimg.cols-1 ; ++i) {
uchar pixelValue = mimg.at<uchar>(0, i); // 获取当前位置的像素值
// 在PixCounter数组中对应位置加一
PixCounter[pixelValue]++;
}
int charger = 0;
for (int i = 0; i < 255; ++i) {
charger += PixCounter[i];
if (charger >= maxBottomPercent)
minMaxTopPercent = i;
else if (charger <= minTopPercent)
maxMinBottomPercent = i;
}
cout << maxMinBottomPercent << '\t' << minMaxTopPercent;
ProcessFunctions nimg;
Mat* temp = nimg.getMatrix();
*temp = 255.0 * (this->matrixCopy - maxMinBottomPercent) / (minMaxTopPercent - maxMinBottomPercent);
(*temp).convertTo((*temp), CV_8UC1);
return nimg;
}
请学长检查
ENVI打开图像实现2%线性拉伸的原理是:“遥感图像数据大多为16位,在显示时要将其拉伸到0-255的区间范围,ENVI软件打开图像时默认使用2%的线性拉伸,思路是将直方图累积在2%和98%之间的像元值拉伸,取直方图累积在2%处对应的光谱值为MinValue,98%处对应的光谱值为MaxValue,那么可解释为如果像元值大于MinValue且小于MaxValue,则将其拉伸至0-255;如果像元值小于MinValue,那么将其改为MinValue;如果像元值大于MaxValue,那么将其改为255。”
您在原函数中定义的操作是将灰度值进行线性变化,这是不符合此处“灰度值线性变换”定义的。当然,我这么说是假设您当时实习的要求和我们这次相同,均为“图像点运算:灰度线性变换(%2线性拉伸)”
如果是,那么可以这样改:(我的类叫ProcessFunctions)
头文件中加入public函数:
函数定义:
请学长检查