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

一. MATLAB实现ENVI线性拉伸

1.参考链接,程序主体来源于:

https://blog.csdn.net/u014090429/article/details/106403645

2.程序修改适用于RGB影像

(1)修改内容介绍:

修改1:适用于影像不完全覆盖矩形区域,即存在大量无效值区域的影像。
修改2:ENVI对影像进行线型拉伸,是针对每一波段的影像进行线性拉伸的。(即分别对R,G,B波段进行拉伸)。原程序适用于单波段处理,修改后程序适用于RGB影像。
在这里插入图片描述

(2)程序介绍:

程序包含3个函数:
(1)calc_lr_val.m(计算影像的灰度直方图)
(2)img_map.m(将原影像按照2%线性拉伸投射到uint8的影像)
(3)img_strech.m(线性拉伸应用到RGB影像上)
(4)程序使用例子

% ------------------------------------
% 计算直方图左右裁剪的灰度值
% 2015/07/01
%
% Input histcount --> 直方图
% tt --> 图像像素个数
% per --> 左右裁剪的百分比
% 
% Output l_val --> 左值
% r_val --> 右值
% ------------------------------------
 
function [l_val, r_val] = calc_lr_val(histcount, tt, per)
 
    fprintf(' ... ... ... ... ... ... ... ... ...\n');
    fprintf(' ... CALC LEFT AND RIGHT VALUE \n');
 
    per_tt = tt*per;  % 按百分比裁剪的像素个数 
 
    % 计算左值
    tmp = 0;
    for i = 1:length(histcount)
        tmp = tmp + histcount(i);
        if tmp >= per_tt
            l_val = i;
            break;
        end
    end
    % 计算右值
    tmp = 0;
    for i = 1:length(histcount)
        tmp = tmp + histcount(length(histcount)-i+1);
        if tmp >= per_tt
            r_val = length(histcount)-i+1;
            break;
        end
    end
 
    fprintf(' ... Stretch Percentage is %d%%\n', per*100);
    fprintf(' ... Left Val is %d \n', l_val);
    fprintf(' ... Right Val is %d \n', r_val);
    fprintf(' ... ... ... ... ... ... ... ... ...\n\n');
 
return
% ------------------------------------
% 将图像映射至 [0, 255] 区间
% 2015/07/01
%
% Input img_16bit --> 16位原图像
% l_val --> 映射左值
% r_val --> 映射右值
% 
% Output img_8bit --> 输出8位拉伸后图像
% ------------------------------------
 
function [img_8bit] = img_map(img_16bit, l_val, r_val)
 
    [xlen, ylen, c] = size(img_16bit);
    img_8bit = zeros(xlen, ylen);
 
    fprintf(' ... ... ... ... ... ... ... ... ...\n');
    fprintf(' ... IMG MAPPING FROM 16BIT TO 8BIT \n');    
    fprintf(' ... Img mapping begin ... ... \n');
 
    % 按照左右值映射
    img_8bit = (img_16bit - l_val).*(255/(r_val-l_val));
    img_8bit = uint8(round(img_8bit));
 
 
    fprintf(' ... Img mapping finshied !!! !!! \n\n');
 
return
function img_matrx_new= img_strech(img_file_name)
    img_matrix = imread(img_file_name);



    for i=1:3

        img=img_matrix(:,:,i);
        % 这里默认输入图像为单通道
        [ylen, xlen] = size(img);
    %     fprintf(' ... Img Xlen: %d pixels\n', xlen);
    %     fprintf(' ... Img Ylen: %d pixels\n\n\n', ylen);

        % 线性拉伸
        max_val = max(img(:));

        %img(find(img<=1))=nan;
        min_val = min(img(:));
        % temp_img=img(:);
        % min_val = min(temp_img(find(temp_img~=0)));
        % %b=min(B(find(B~=0)));

    %     fprintf(' ... ... ... ... ... ... ... ... ... ...\n');
    %     fprintf(' ... Min Val is %d \n', min_val);
    %     fprintf(' ... Max Val is %d \n', max_val);
    %     fprintf(' ... ... ... ... ... ... ... ... ... ...\n\n');

        % 统计直方图
        % 输入图像为16位,取值范围为 065535
        bins = 0:65535;
        histcount = histc(img(:)', bins); 
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        histcount(1) =0; %因为自己使用的影像,有很多nodata_value,但是数值为0,所以加这一步骤
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %清除临时变量 
        clear bins max_val min_val; 
        % 直方图裁剪,计算左值和右值 
        [l_val, r_val] = calc_lr_val(histcount, xlen*ylen, 0.02); 
        % 根据左值和右值,将图像由16位映射至8位 
        img_8bit = img_map(img, l_val, r_val); 
        % 保存结果 
        img_matrx_new(:,:,i)=img_8bit;
        %imwrite(img_8bit, 'res_blue.png');

    end

   % return (img_matrx_new);

end
%RGB影像:band 1,2,3 分别是 R,G,B
img_file_name='E:\2022_5_2_GF_pa1_pa2_lens_rect\pa2_021_010\树高查看\layer_stcak_ms.tif';   
img_strech_new= img_strech(img_file_name);
imshow(img_strech_new);

展示结果,目视和envi展示结果一致:
在这里插入图片描述

二.matlab在底图上画剖面线

1.在底图上画剖面线

参考链接:https://blog.csdn.net/Enjolras_fuu/article/details/66530196
想要的结果:底图上有两条线,且坐标都在。
在这里插入图片描述

我的流程:

fclose all
clear all
clc

%RGB影像:band 1,2,3 分别是 R,G,B
img_file_name='E:\2022_5_2_GF_pa1_pa2_lens_rect\pa2_021_010\树高查看\layer_stcak_ms.tif';   
img_strech_new= img_strech(img_file_name);
%imshow(img_strech_new);

chm_name='E:\2022_5_2_GF_pa1_pa2_lens_rect\pa2_021_010\树高查看\layer_stcak_chm.tif';
img_chm=imread(chm_name);
size_img_chm=size(img_chm);
y_axis_limits=[-50,50];
figure();
hold on
imshow(img_strech_new);

hold on
show_y=ones(1,size_img_chm(2))*(ceil(size_img_chm(1)/2))+(-img_chm(ceil(size_img_chm(1)/2),:));
plot(show_y,'r','LineWidth',2);
hold on
plot(ones(1,size_img_chm(2))*(ceil(size_img_chm(1)/2)),'k','LineWidth',1);
%axis xy
hold on
%axis([0 size_img_chm(2) y_axis_limits(1) y_axis_limits(2)]);%限制x轴,y轴的显示范围
axis on
axis([0 size_img_chm(2) 0 size_img_chm(1)]);%限制x轴,y轴的显示范围
hold off

2.底图上的剖面线与底图表示为不同的坐标系

双坐标系参考:https://blog.csdn.net/qq_20481015/article/details/81172140


fig=figure;
%先用imshow画出底图
imshow(img_strech_new);
hold on
%激活左边的坐标系,作为底图,或者是第一个plot的坐标系
yyaxis left
plot(ones(1,size_img_chm(2))*(chm_show_line),'y','LineWidth',1);
hold on
%限制左边坐标系的显示范围
axis([0 size_img_chm(2) 0 size_img_chm(1)]);%限制x轴,y轴的显示范围
axis on

%激活右边的坐标系,作为第二个plot的坐标系
yyaxis right
set(gca,'YDir','normal');        %将y轴方向设置为普通(从下到上递增)%set(gca,'YDir','reverse');        %将x轴方向设置为反向(从上到下递增)。
show_y=(img_chm(chm_show_line,:)+7);
%show_y=ones(1,size_img_chm(2))*(chm_show_line)+(img_chm(chm_show_line,:)+7);
plot(show_y,'r','LineWidth',2);
hold on
%限制右边坐标系的显示范围
axis([0 size_img_chm(2) -(1-chm_show_line/size_img_chm(1))*100 (chm_show_line/size_img_chm(1))*100]);%限制x轴,y轴的显示范围
axis on


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值