近期遇到部分影像整体颜色比较暗,但是在ArcGis中显示的确实非常清晰。进过多方查找资料发现其实,就是对图像做了线性拉伸所致。
线性的拉伸原理: 某个影像的颜色值分布在某一特定小比例区域,如果是8位图像,形象的比喻就是,全图影响较多分布为某一区域,需要将区域扩大到整个8位的颜色域内。如:颜色范围为4-50 的一幅图看起来就是黑黢黢的,如果所有颜色全部映射到0-255,那么颜色就会显得很靓丽,首先放一个效果图:
拉伸前:
拉伸后:
拉伸前后的直方图对比:
线性拉伸方程为简单的二元一次方程,展开式如下:
y = x*(dmax -dmin)/(smax - smin)+(smax*dmin-smin*dmax)/(smax - smin);
直接上代码,下面函数实现将一行影像数据线性拉伸,:
/// \brief 标准差拉伸
/// \param pInter const T * poSrcData, 原始数据
/// \param T * poDstData, 目标数据块
/// \param int nSizex 数据长度
/// \param T smin, T smax 原始像素值域
/// \param T dmin, T dmax 目标像素值域
template<typename T>
inline int CImageCorrectionDlg::LinearTension(const T * poSrcData, T * poDstData, int nSizex, T smin, T smax, T dmin, T dmax)
{
double k = (double)(dmax - dmin) / (smax - smin);
double b = (double)(smax*dmin - smin*dmax) / (smax - smin);
for (int i = 0; i < nSizex; i++)
{
int tmp = k*poSrcData[i] + b;
if (tmp <= 0)
{
if(poSrcData[i] == 0)
poDstData[i] = 0;
else
poDstData[i] = 1;//原来不是0的如果直接拉伸0将变为nodata
}
else if (tmp >= 255)
poDstData[i] = 255;
else
poDstData[i] = (T)tmp;
}
return 0;
}
另外影像的读取和写入使用了GDAL库,直方图统计用到了GetHistogram, 和ComputeStatistics。GDAL使用网上一大堆这里不做描述,最后上传一个自己用mfc写好的程序,此程序目前只能线性拉伸,另外的百分比截断拉伸还未完成,后续完成将更新,此程序依赖GDAL库,需自行编译。资源地址:https://download.csdn.net/download/chijingjing/10348659
2018/0527
以下地址代码包含最值, 百分比,标准差拉升的实现.https://download.csdn.net/download/chijingjing/10441503