ENVI%2线性拉伸算法实现

对遥感图像进行2%线性拉伸 参考链接:http://www.voidcn.com/article/p-ethxsjor-du.html 阅读详情

一、在ENVI里面有Linear和Linear2%的线性拉伸的方法,当然还有其它各种各样的拉伸方式,用的最多的就是Linear2%

二、Linear方法较为简单,原理如下所示:我们需要增强的或者说线性拉伸的图像范围一般为[0,255],因此下面公式中的c=0,d=255,得到一般公式为g(x,y)=255/(b-a)*(f(x,y)-a),循环迭代图像每个像元值,然后将小于a的灰度值赋值为0,大于b的灰度值赋值为255,a与b之间的按照公式计算即可。

三、Linear算法实现(本算法是在Qt下编译运行的,C++语言,调用了GDAL库,同时设置了输出文件方便查看效果)

    GDALDataset *dataSet = (GDALDataset*)GDALOpen(pszSrcFile,GA_ReadOnly);//原始图像,路径自己改

    int width = dataSet->GetRasterXSize();
    int height = dataSet->GetRasterYSize();
    GDALDataType dataType = dataSet->GetRasterBand(1)->GetRasterDataType();
    GDALDriver *poDriver = (GDALDriver*)GDALGetDriverByName("GTiff");
    GDALDataset *poDstDS = poDriver->Create(pszDstFile,width,height,3,dataType,NULL);//创建输出路径,路径自己改

    GDALRasterBand *poBand1,*poBand2,*poBand3;
    GDALRasterBand *pDstband1 = poDstDS->GetRasterBand(1);//输出图像R波段
    GDALRasterBand *pDstband2 = poDstDS->GetRasterBand(2);//输出图像G波段
    GDALRasterBand *pDstband3 = poDstDS->GetRasterBand(3);//输出图像B波段

    poBand1 = dataSet->GetRasterBand(1);//读取R波段

    unsigned char *pBuf1 = new unsigned char[width*height];//存储原始图像灰度值
    unsigned char *BufR = new unsigned char[width*height];//存储增强图像灰度值
    poBand1->RasterIO(GF_Read,0,0,width,height,pBuf1,width,height,GDT_Byte,0,0);
    double adfMinMax[2];//获取图像灰度最大最小值
    GDALComputeRasterMinMax((GDALRasterBandH)poBand1,FALSE,adfMinMax);
    int min = adfMinMax[0];
    int max = adfMinMax[1];
    for(int i=0;i<width*height;i++)
    {
        if(pBuf1[i]<min)
            BufR[i] = 0;
        else if(pBuf1[i]>max)
            BufR[i] = 255;
        else
            BufR[i] = 255/(max - min)*(pBuf1[i] - min);
    }
    pDstband1->RasterIO(GF_Write,0,0,width,height,BufR,width,height,GDT_Byte,0,0);//写入R波段

    poBand2 = dataSet->GetRasterBand(2);//读取G波段

    unsigned char *pBuf2 = new unsigned char[width*height];
    unsigned char *BufG = new unsigned char[width*height];
    poBand2->RasterIO(GF_Read,0,0,width,height,pBuf2,width,height,GDT_Byte,0,0);
    double adfMinMax2[2];
    GDALComputeRasterMinMax((GDALRasterBandH)poBand2,FALSE,adfMinMax2);
    int min2 = adfMinMax2[0];
    int max2 = adfMinMax2[1];
    for(int i=0;i<width*height;i++)
    {
        if(pBuf2[i]<min2)
            BufG[i] = 0;
        else if(pBuf2[i]>max2)
            BufG[i] = 255;
        else
            BufG[i] = 255/(max2 - min2)*(pBuf2[i] - min2);
    }
    pDstband2->RasterIO(GF_Write,0,0,width,height,BufG,width,height,GDT_Byte,0,0);//写入G波段


    poBand3 = dataSet->GetRasterBand(3);//读取B波段

    unsigned char *pBuf3 = new unsigned char[width*height];
    unsigned char *BufB = new unsigned char[width*height];
    poBand3->RasterIO(GF_Read,0,0,width,height,pBuf3,width,height,GDT_Byte,0,0);
    double adfMinMax3[2];
    GDALComputeRasterMinMax((GDALRasterBandH)poBand3,FALSE,adfMinMax3);
    int min3 = adfMinMax3[0];
    int max3 = adfMinMax3[1];
    for(int i=0;i<width*height;i++)
    {
        if(pBuf3[i]<min3)
            BufB[i] = 0;
        else if(pBuf3[i]>max3)
            BufB[i] = 255;
        else
            BufB[i] = 255/(max3 - min3)*(pBuf3[i] - min3);
    }
    pDstband3->RasterIO(GF_Write,0,0,width,height,BufB,width,height,GDT_Byte,0,0);//写入B波段
    //关闭数据集,删除内存
    GDALClose((GDALDatasetH)dataSet);
    GDALClose((GDALDatasetH)poDstDS);
    delete [] pBuf1;
    delete [] BufR;
    delete [] pBuf2;
    delete [] BufG;
    delete [] pBuf3;
    delete [] BufB;

四、Linear2%方法复杂一点,原理如下:我们依然假设增强的图像范围为[0,255],读取原始图像后首先进行直方图统计,得到0~255每个灰度值对应的个数(如下面的HistBand1),然后用对应的灰度个数除以图像总的像元数(width*height),将得到的结果进行累计(比如0对应的值是0.001,1对应的值是0.002,那么0的累计值就是0.001,而1的累计值就是0对应的值再加上1对应的值,就是0.003)放入变量HistR、HistG、HistB,这样就得到了累计直方图,然后找到2%对应的灰度值minR和98%对应的灰度值maxR(其他波段类似),将这两个值作为原始图像灰度的最大最小值,运用上述Linear方法即可得到最终给结果。

五、Linear2%算法实现(本算法是在Qt下编译运行的,需要调用GDAL库,同时设置了输出文件方便查看效果)

    GDALDataset *dataSet = (GDALDataset*)GDALOpen(pszSrcFile,GA_ReadOnly);//输入文件路径自己改

    int width = dataSet->GetRasterXSize();
    int height = dataSet->GetRasterYSize();
    GDALDataType dataType = dataSet->GetRasterBand(1)->GetRasterDataType();
    GDALDriver *poDriver = (GDALDriver*)GDALGetDriverByName("GTiff");
    GDALDataset *poDstDS = poDriver->Create(pszDstFile,width,height,3,dataType,NULL);//输出文件路径自己改

    //统计直方图
    unsigned long long HistBand1[256] = {0};
    unsigned long long HistBand2[256] = {0};
    unsigned long long HistBand3[256] = {0};

    //累计直方图
    float HistR[256] = {0};
    float HistG[256] = {0};
    float HistB[256] = {0};

    GDALRasterBand *poBand1,*poBand2,*poBand3;
    GDALRasterBand *pDstband1 = poDstDS->GetRasterBand(1);
    GDALRasterBand *pDstband2 = poDstDS->GetRasterBand(2);
    GDALRasterBand *pDstband3 = poDstDS->GetRasterBand(3);

    //R波段累计直方图
    poBand1 = dataSet->GetRasterBand(1);
    poBand1->GetHistogram(-0.5,255.5,256,HistBand1,TRUE,FALSE,NULL,NULL);
    HistR[0] = (float)HistBand1[0]/(width*height);
    for(int i=1;i<=255;i++)
    {
        HistR[i] = HistR[i-1] + (float)HistBand1[i]/(width*height);
    }

    unsigned char *pBuf1 = new unsigned char[width*height];
    unsigned char *BufR = new unsigned char[width*height];
    poBand1->RasterIO(GF_Read,0,0,width,height,pBuf1,width,height,GDT_Byte,0,0);
    //R波段赋值
    int minR,maxR;//2%处的灰度值和98%处的灰度值
    for(int i=0;i<=255;i++)
    {
        if(HistR[i]<=0.02)
            minR = i;
        if(HistR[i]<=0.98)
            maxR = i;
    }

    for(int i=0;i<width*height;i++)
    {
        if(pBuf1[i]<=minR)
            BufR[i] = 0;
        else if(pBuf1[i]>=maxR)
            BufR[i] = 255;
        else
            BufR[i] = 255/(maxR - minR)*(pBuf1[i] - minR);
    }
    pDstband1->RasterIO(GF_Write,0,0,width,height,BufR,width,height,GDT_Byte,0,0);

    //G波段累计直方图
    poBand2 = dataSet->GetRasterBand(2);
    poBand2->GetHistogram(-0.5,255.5,256,HistBand2,TRUE,FALSE,NULL,NULL);
    HistG[0] = (float)HistBand2[0]/(width*height);
    for(int i=1;i<=255;i++)
    {
        HistG[i] = HistG[i-1] + (float)HistBand2[i]/(width*height);
    }

    unsigned char *pBuf2 = new unsigned char[width*height];
    unsigned char *BufG = new unsigned char[width*height];
    poBand2->RasterIO(GF_Read,0,0,width,height,pBuf2,width,height,GDT_Byte,0,0);
    //G波段赋值
    int minG,maxG;
    for(int i=0;i<=255;i++)
    {
        if(HistG[i]<=0.02)
            minG = i;
        if(HistG[i]<=0.98)
            maxG = i;
    }

    for(int i=0;i<width*height;i++)
    {
        if(pBuf2[i]<=minG)
            BufG[i] = 0;
        else if(pBuf2[i]>=maxG)
            BufG[i] = 255;
        else
            BufG[i] = 255/(maxG - minG)*(pBuf2[i] - minG);
    }
    pDstband2->RasterIO(GF_Write,0,0,width,height,BufG,width,height,GDT_Byte,0,0);

    //B波段累计直方图
    poBand3 = dataSet->GetRasterBand(3);
    poBand3->GetHistogram(-0.5,255.5,256,HistBand3,TRUE,FALSE,NULL,NULL);
    HistB[0] = (float)HistBand3[0]/(width*height);
    for(int i=1;i<=255;i++)
    {
        HistB[i] = HistB[i-1] + (float)HistBand3[i]/(width*height);
    }

    unsigned char *pBuf3 = new unsigned char[width*height];
    unsigned char *BufB = new unsigned char[width*height];
    poBand3->RasterIO(GF_Read,0,0,width,height,pBuf3,width,height,GDT_Byte,0,0);
    //B波段赋值
    int minB,maxB;
    for(int i=0;i<=255;i++)
    {
        if(HistB[i]<=0.02)
            minB = i;
        if(HistB[i]<=0.98)
            maxB = i;
    }

    for(int i=0;i<width*height;i++)
    {
        if(pBuf3[i]<=minB)
            BufB[i] = 0;
        else if(pBuf3[i]>=maxB)
            BufB[i] = 255;
        else
            BufB[i] = 255/(maxB - minB)*(pBuf3[i] - minB);
    }
    pDstband3->RasterIO(GF_Write,0,0,width,height,BufB,width,height,GDT_Byte,0,0);

    GDALClose((GDALDatasetH)dataSet);
    GDALClose((GDALDatasetH)poDstDS);
    delete [] pBuf1;
    delete [] BufR;
    delete [] pBuf2;
    delete [] BufG;
    delete [] pBuf3;
    delete [] BufB;

六、效果对比,和ENVI效果一样,没有ENVI中的红色框框。

原始图像:

Linear图像:

Linear2%图像:

ENVI的几种图像拉伸方式 ENVI的四种图像拉伸方法 阅读详情

相关推荐

图像处理:灰度图片线性截断拉伸

线性拉伸算法对于某些灰度图像,其对比度增强效果良好,但是适应性不强,如果图像中存在坏点或者存在少量像素值散布较大的情况,该方法失效。线性截断拉伸算法是线性拉伸算法的改进,可以克服线性拉伸算法的缺陷,具有剔除异常点的功能,适应性强,能较好地处理各种灰度图像。

qq_28249373的博客 6212

图像处理-线性拉伸

图像领域:拉伸即:灰度图拉伸,与直方图均衡化类似,但是也不同!!!线性拉伸:1)直接线性拉伸;2)裁剪线性拉伸;3)分段式拉伸。1)直接线性拉伸:(直接归一化,然后放缩到指定大小范围)代码:import cv2import numpy as npgray=np.float( cv2.imread(**) )gray_new=( gray-gray.min() ) / ( gray.max()-gr...

LEILEI18A的博客 2万+

深度学习笔记-遥感影像转为tensor前的检查及线性拉伸

深度学习笔记-遥感影像转为tensor前的检查及线性拉伸前言-为什么要做线性拉伸一、transforms.ToTensor二、线性拉伸总结 前言-为什么要做线性拉伸 近期在开展语义分割任务,用到的数据是经过SNAP预处理的Sentinel-1的SAR数据。工作需要将相关的Image和label送入模型,进行目标地物的分割。 这里用到的深度学习框架是pytorch,需要将影像数据转换为tensor后送入model。转换为tensor之前,需要对image和label的存储格式进行检查。为什么呢?这里就需要知

高不胖的学习笔记 1331

(四)图像的%2线性拉伸

图像的百分之二线性拉伸

伯努利 3012

ENVI_IDL: 对风云四号卫星数据波段合成和线性拉伸并分别生成TIFF格式和JPEG格式

这里没什么新的知识点,就是各个地方的数组定义要注意一下啊,有的是无符号数组,有的是字节型数组。最变态的是由于风云四号卫星数据比较大,一个数组占用内存甚至达到300M+,所以不用的内存需要即使处理,否则如果是循环那么很容易出现内存无法分配到数组的错误出现。——————————————————————————————————————————————————————————————————————————————————————我是炒茄子,不用谢。2.对获取的数据进行提取获取三个波段的数据集。...

炒茄子的博客 2192

python2%线性拉伸

核心要点 本方法是针对遥感数据的,因此使用了Gdal,如果你针对的是普通的图片,就直接使用cv2.imread()来读取即可,就不需要gdal了。 np.percentile()函数 np.clip()函数 cv2.split()函数 cv2.merge()函数 gdal的使用 本代码适用于ipython 若在编辑器下使用,需要自行的稍作修改 主体是函数TwoPercentLinear。 import numpy as np import cv2 from matplotlib import pyplot as plt def TwoPercentLinear(image, max_out=

python截断线性拉伸(对应ENVI软件中的Linear2%)

1. 原理简介 在ENVI里面有Linear和Linear2%的线性拉伸的方法,用的最多的就是Linear2%. Linear方法较为简单: g(x,y)=(d - c) / (b - a) * (f(x, y) + c, 其中d和c分别是输出图像的最大值和最小值,b和a分别是原始图像的最大值和最小值,应用上式变换之后将小于c的灰度值赋值为0,大于d的灰度值赋值为255即可。 Linear2%方法复杂一点,原理如下:读取原始图像后首先进行直方图统计,进而计算累计直方图,假定截断值为2,然后找到2

Nick Blog 4403

安卓逆向实战:利用Frida-RPC自动化获取大麦演唱会数据

本文详细介绍了如何利用Frida-RPC技术实现安卓逆向自动化,以获取大麦演唱会数据。通过实战演示,从环境搭建、使用Frida动态分析定位核心签名算法,到封装为可复用的Python脚本,完整解析了自动化数据获取的技术路径与工程化思考。

cheese的博客 974

envi如何进行线性拉伸显示?

有时我们在envi中打开影像时显示影像特别暗,不方便观察和使用,因此这里经常需要进行拉伸操作。而一般我们使用的拉伸方式为线性拉伸2%。 (1)在envi中打开一景影像。 (2)点击选择线性拉伸2%,即可看到拉伸后明显变亮。 ...

YW_remote的博客 1万+

山东大学软件测试实验2——系统功能测试

​ 给出一个被测试的 Web 应用系统(SUT)。http://211.87.232.162:8080/注:友情链接不用延伸测试。针对被测试的 Web 应用系统进行功能测试,发现其存在的缺陷。 ​

m0_74033391的博客 2409

区块链技术在碳足迹数据存证与溯源中的应用深度解析

消费者扫描产品上的二维码,即可通过区块链浏览器查询到该产品的数字碳标签,并追溯其从茶园到货架的每一步碳足迹数据,以及这些数据是如何被智能合约自动计算和认证的,从而建立起强大的品牌信任。如果说哈希链解决了数据的“存”与“证”的问题,那么智能合约则解决了数据“用”与“管”的自动化问题。综上所述,虽然针对“碳足迹数据可追溯性”这一特定应用场景的公开、标准化的性能基准案例尚不丰富,但现有研究和企业级解决方案(特别是联盟链)已经证明,通过合理的技术选型和架构设计,区块链的性能可以满足实际商业需求。

百态·数智思维 | 聚焦大数据、量化与未来AI 1106

图像线性拉伸Python使用公式

数字图像处理,线性拉伸,python,彩色和灰色图像

qq_56809618的博客 4232

本地部署DeepSeek连接MATLAB:打造私有化AI编程助手全攻略

大型语言模型(LLM)通过理解自然语言生成代码、解释技术概念,其核心原理是基于海量数据训练的Transformer架构。这项技术为工程计算和数据分析带来了效率革命,尤其在代码生成、调试辅助和文档自动化等场景价值显著。开源模型如DeepSeek-coder凭借优秀的代码理解能力,结合Ollama提供的本地化部署方案,实现了完全离线、低延迟的私有化部署。通过配置国内镜像加速下载,并利用MATLAB内置的HTTP通信函数构造API请求,工程师可以在熟悉的MATLAB环境中直接调用本地模型,处理数据清洗、算法验证等

weixin_30239339的博客 516

线性拉伸

1、在ENVI中选择数据”test7.img“,打开TM多光谱图像并显示,如图。 2、在显示图像的窗口上选择”增强——交互式拉伸“,弹出窗口。 3、对左图中的白虚线进行调整,到合适位置。也可以点击G、B对其他波段进行调整。 4.调整完后点击Apply,就完成了。 ...

weixin_43887139的博客 3331

上海市大数据中心笔试模拟试卷

为帮助考生熟悉上海市大数据中心笔试的题型、考点及答题逻辑,以下整理了一份的模拟试卷,涵盖大数据专业知识、行政职业能力测试(行测)、公共基础知识(含上海本地政策)三大核心模块,并附详细答案解析。

一叶之秋的博客 1815

【WebRTC】【Unity】Unity Web RTC1-Unity中简单实现远程画面

平台:基本常用平台包括安卓,苹果(max和IOS),Windows64,Linux都行。10. 注意,如果从移动设备浏览器连接服务,信令服务器的SSL证书一定要先设好。想要在Unity中实现实时远程桌面,找到了Render Streaming这个手段,本篇介绍相应的使用方法和实例。8. 打开电脑浏览器,地址栏输入http://127.0.0.1,点击Receiver Sample。新建Unity项目,模板选Third Person,Project Name随意。启动App,控制台出现如下信息表示成功。

每日出拳老爷子的博客 2518

调整图像亮度之 线性拉伸 (1) 基于直方图最值

近期遇到部分影像整体颜色比较暗,但是在ArcGis中显示的确实非常清晰。进过多方查找资料发现其实,就是对图像做了线性拉伸所致。线性的拉伸原理: 某个影像的颜色值分布在某一特定小比例区域,如果是8位图像,形象的比喻就是,全图影响较多分布为某一区域,需要将区域扩大到整个8位的颜色域内。如:颜色范围为4-50 的一幅图看起来就是黑黢黢的,如果所有颜色全部映射到0-255,那么颜色就会显得...

CJJ的专栏 1万+

【AI Agent】Hermes Agent解析

Hermes Agent:一个具备持久化学习能力的开源AI Agent框架 核心特点: 突破传统Agent的"无状态困境",通过记忆系统(SQLite+FTS5全文检索)实现跨会话经验积累 支持200+模型自由切换,11种模型家族和15+平台接入 五层架构设计(入口层、编排层、推理层、工具执行层、存储层)实现平台无关性 47+内置工具和动态技能沉淀机制,支持从任务执行中自动提炼可复用Skill 独特的四层记忆体系(会话/每日/长期/向量索引)和辩证式用户建模 与传统Agent对比: 具备自我进化能力,通过A

sysu_lluozh 924

图像拉伸算法(线性拉伸、百分比拉伸、标准差拉伸)

图像拉伸c++算法

qq_19816973的博客 797

015:机载三维激光扫描技术相关知识

机载三维激光扫描系统(LiDAR)是集激光、GPS、INS等尖端技术于一体的三维航空遥感技术,能高效准确获取地表三维信息。该系统由GPS、INS、激光扫描测距系统、成像装置和工作平台组成,各部件协同工作以获取精确的空间定位、运动状态、地表三维坐标及真实色彩信息。通过制定飞行计划、安置GPS基站、激光扫描测量、惯性测量及获取高清数码影像等步骤,机载LiDAR技术能实时获取大范围高精度三维数据。该技术具有扫描速度快、精度高、全数字特征等优势,广泛应用于测绘、工程、环境监测和城市建设等领域,如城市三维模型重建、灾

qq_31762031的博客 1726

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

遥感数字图像处理实验教程(韦玉春)--部分实验问题回答

图像合成和显示增强、图像变换、图像滤波、图像分割、图像分类、变化监测

伯努利 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++数字图像处理(2)—分段线性拉伸

分段线性拉伸

m0_43425222的博客 1608

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

matlab实现ENVI2%线性拉伸及底图上画双坐标系剖面线

matlab实现ENVI2%线性拉伸及底图上画剖面线

花藻の博客 2259

C++通过类来实现BMP图像的翻转,裁剪,缩放等操作

#实验心得 1.当出现data重载多个时,检查函数是否声明Image引用 2.出现数组越界时问题十分常见,记得通过多输出几次来判断程序在哪个点发生了中断。数组越界要十分明白数组的大小,和输入数组元素的个数,一个一个来判断; 3.循环时,一定要算好循环的次数,不然容易出现数组越界。 总之,一些小细节问题很致命。 #实验要求: > 实验5 类和对象 实验目的 掌握类和对象的创建 掌握构造函数、构造函数的重载,拷贝构造函数、析构函数的设计和使用 掌握成员函数的设计和使用 实验内容 下面的代码已经创建了图

人间理想的博客 2920

ENVI软件测试图像真彩色、假彩色合成的各种方法;阈值分割;拉伸显示

下载一景多光谱遥感影像,用ENVI软件测试图像彩色合成的各种方法,并说明各种合成方法下突出了哪些地物信息;以下载的遥感影像为例,用ENVI软件进行各种图像的拉伸操作,并比较拉伸效果。

weixin_45965977的博客 1万+

ENVI辐射校正(FLAASH)自用

envi大气校正

y1455的博客 5805
上一篇: C++求矩阵最大值和最小值
下一篇: GDAL图像分割算法实现
之乎者也哦
博客等级 码龄8年 7165粉丝 72原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值