Matlab 根据 shp 裁剪矩阵/图像 函数

关于这个函数,我最近(2020.11.1)又修改了一下,之前的版本第二步通用性不强,这波应该可以通用了。现将几个版本命个名:
2020-8-24 V1.0 有内切圆外切圆,第二步不通用
2020-11-1 V2.0 有内切圆外切圆,第二步通用
2020-11-1 V2.1 无内切圆外切圆,第二步通用

1、全代码

1.1 V1.0

function varargout=tailorsheng(varargin)
%% 此函数用于根据 shp 裁剪矩阵/图像
% 输入:
%       P2file shpfile
%       TDMSPfile tiffile,可以不是tif
%       str  要裁剪谁
%       mode 10国家
% 输出:
%       sheng shp
%       photo mat图像
%       ex    经纬度极值
% 调用:
%       TDMSPfile='D:\复习资料\自学\7_科研\夜光遥感\data\DMSP\F121999.v4\F121999.v4b_web.stable_lights.avg_vis.tif';
%       P2file='D:\下载\Useful\shp\国家基础地理数据\bou2_4m\bou2_4p.shp';%省界多边形
%       str='北京市';
%       mode=1;
%       [sheng,photo,ex]=tailorsheng(P2file,TDMSPfile,str);
%       [sheng,photo,ex]=tailorsheng(P2file,TDMSPfile,str,mode);
%-------------------------------------------------------------------
    %%%%    Authors:   Bill O'Hanlon
    %%%%    EMAIL:     ohanlon@qq.com
    %%%%    DATE:      24-08-2020
%% 输入
disp('-------function tailorsheng------');
tic %开始计时
mode=1;
if nargin==3
    P2file=varargin{1}; %注意,这里是{, (会是元胞
    TDMSPfile=varargin{2};
    str=varargin{3};
elseif nargin==4
    P2file=varargin{1}; %注意,这里是{, (会是元胞
    TDMSPfile=varargin{2};
    str=varargin{3};
    mode=varargin{4};%这里不做变换的话会是元胞
else
    disp('参数不合要求!');
    return;
end
%% 第一步,提取目标省份的 shp,注意看其范围
[henan,ex]=drawsheng(P2file,str,mode);
disp('shp文件搞定!');
%% 第二步,把图像大致范围剪出来,这步根据图像种类不同,代码也不一样,Attention!!
TDMSP=imread(TDMSPfile); %DMSP范围 180°W-180°E,65°S-75°N
Xmax=ex(1);              %X是经度,Y是纬度
Ymax=ex(2);              %这些已经取整了。
Xmin=ex(3);
Ymin=ex(4);
Xmax1=Xmax+180;          %这是裁剪时用的
Ymax1=75-Ymax;
Xmin1=Xmin+180;
Ymin1=75-Ymin;
Henan=TDMSP(Ymax1*120:Ymin1*120,Xmin1*120:Xmax1*120);%根据自己需要裁减
disp('粗裁剪完成!');
%% 第三步,计算不规则边界的内切圆和外接圆
Y=Ymin:0.0083333333:Ymax; %分辨率0.0083333333°  1°=120
X=Xmin:0.0083333333:Xmax; %求逻辑矩阵用到
[a,b]=size(Henan);
Y2=repmat(Y',1,b);
X2=repmat(X,a,1);
Y2=flipud(Y2);                     %这个纬度得上下翻转一下。
xv=henan.X;yv=henan.Y;             %提取边界
xv = xv(1:end-1); yv = yv(1:end-1);%把最后一个NaN去掉
disp('需要计算逻辑的区域为 Figure 2 红色区域');
bianjie=[xv;yv];
[zhongxin1,zhongxin2,smallR,bigR]=getZhongxin(bianjie,X2,Y2);
%% 第四步,根据内切圆和外接圆+边界进行裁剪
disp('开始计算逻辑矩阵..');
photo=zeros(a,b);
photo(:)=nan;
for i=1:a
    for j=1:b
        if mod(i*b+j,10000)==0
            disp([int2str(i*b+j),' / ',int2str(a*b), ' OK!']);
        end
        x=X2(i,j);
        y=Y2(i,j);
        if norm(zhongxin1-[x;y])<=smallR
            photo(i,j)=Henan(i,j);%内接圆里面的都在
            continue;
        elseif norm(zhongxin2-[x;y])>=bigR
            continue;%外接圆外面的都不在
        elseif inpolygon(x,y,xv,yv)
            photo(i,j)=Henan(i,j);
        end
    end
end
disp('细裁剪完成!');
%% 第五步,画图,裁剪后的
[x,x1,y,y1] = getxy(X,Y);
x=(x-Xmin).*120; 
y=(y-Ymin).*120;
photo=flipud(photo);%contourf 上下翻转一下,才变成imshow
figure;
contourf(photo,'LineStyle','none');
colormap(gray);colorbar %jet
set(gca,'XTick',x,'XTicklabel',x1);   %设置x,y轴
set(gca,'YTick',y,'YTicklabel',y1);
title([str,'夜光遥感影像']);
%% 输出
if nargout==3
    varargout{1}=henan; 
    varargout{2}=photo;
    varargout{3}=ex;
elseif nargout==2
    varargout{1}=henan; 
    varargout{2}=photo;
elseif nargout==1
    varargout{1}=henan; 
elseif nargout==0
    return;
else
    disp('参数不合要求!');
    return;
end
disp('--------Finished!--------');
toc  %展示运行时间
end

1.2 V2.0

function varargout=tailorsheng(varargin)
%% 此函数用于根据 shp 裁剪矩阵/图像
% 输入:
%       P2file shpfile
%       TDMSPfile tiffile,可以不是tif
%       str  要裁剪谁
%       mode 1省0国家
% 输出:
%       sheng shp
%       photo mat图像
%       ex    经纬度极值
% 调用:
%       TDMSPfile='D:\复习资料\自学\7_科研\夜光遥感\data\DMSP\F121999.v4\F121999.v4b_web.stable_lights.avg_vis.tif';
%       P2file='D:\下载\Useful\shp\国家基础地理数据\bou2_4m\bou2_4p.shp';%省界多边形
%       str='北京市';
%       mode=1;
%       [sheng,photo,ex]=tailorsheng(P2file,TDMSPfile,str);
%       [sheng,photo,ex]=tailorsheng(P2file,TDMSPfile,str,mode);
%-------------------------------------------------------------------
    %%%%    Authors:   Bill O'Hanlon
    %%%%    EMAIL:     ohanlon@qq.com
    %%%%    DATE:      01-11-2020
%% 输入
disp('-------function tailorsheng------');
tic %开始计时
mode=1;
if nargin==3
    P2file=varargin{1}; %注意,这里是{, (会是元胞
    TDMSPfile=varargin{2};
    str=varargin{3};
elseif nargin==4
    P2file=varargin{1}; %注意,这里是{, (会是元胞
    TDMSPfile=varargin{2};
    str=varargin{3};
    mode=varargin{4};%这里不做变换的话会是元胞
else
    disp('参数不合要求!');
    return;
end
%% 第一步,提取目标省份的 shp,注意看其范围
[henan,ex]=drawsheng(P2file,str,mode);
disp('shp文件搞定!');
%% 第二步,把图像大致范围剪出来,这步根据图像种类不同,代码也不一样,Attention!!
TDMSP=imread(TDMSPfile); %DMSP范围 73.49781527°E-135.0894573°E,3.83544513°N-53.56042524°N
Xmax=ex(1);              %X是经度,Y是纬度
Ymax=ex(2);              %这些已经取整了。
Xmin=ex(3);
Ymin=ex(4);
Info=geotiffinfo(TDMSPfile); %读取图像信息,比如经纬度,分辨率
global PixelScale; %定义了几个全局变量,
global Pixel_;
global XBound;
global YBound;
PixelScale=Info.PixelScale(1,1);
Pixel_=1/PixelScale;
XBound=Info.BoundingBox(1,1);
YBound=Info.BoundingBox(2,2);
[a,b]=size(TDMSP);
if(Xmax>Info.BoundingBox(2,1)) Xmax=Info.BoundingBox(2,1); end
if(Xmin<Info.BoundingBox(1,1)) Xmin=Info.BoundingBox(1,1); end
if(Ymax>Info.BoundingBox(2,2)) Ymax=Info.BoundingBox(2,2); end
if(Ymin<Info.BoundingBox(1,2)) Ymin=Info.BoundingBox(1,2); end
Xmax1=Xmax-XBound;          %这是裁剪时用的
Ymax1=YBound-Ymax;
Xmin1=Xmin-XBound;
Ymin1=YBound-Ymin;
hangs=round(Ymax1*Pixel_); %上界
hangx=round(Ymin1*Pixel_); %下界
liez=round(Xmin1*Pixel_);  %左界
liey=round(Xmax1*Pixel_);  %右
if(hangs<1) hangs=1; end
if(hangx>a) hangx=b;end
if(liez<1) liez=1; end
if(liey>b) liey=b; end

Henan=TDMSP(hangs:hangx,...
    liez:liey);%根据自己需要裁减
sprintf('粗裁剪完成! %d,%d,%d,%d',hangs,hangx,liez,liey);
%% 第三步,计算不规则边界的内切圆和外接圆
Y=Ymin:PixelScale:Ymax; %分辨率0.0083333333°  1°=120
X=Xmin:PixelScale:Xmax; %求逻辑矩阵用到
%[a,b]=size(Henan);
a=size(Y,2);
b=size(X,2);
Y2=repmat(Y',1,b);
X2=repmat(X,a,1);
Y2=flipud(Y2);                     %这个纬度得上下翻转一下。
xv=henan.X;yv=henan.Y;             %提取边界
xv = xv(1:end-1); yv = yv(1:end-1);%把最后一个NaN去掉
disp('需要计算逻辑的区域为 Figure 2 红色区域');
bianjie=[xv;yv];
[zhongxin1,zhongxin2,smallR,bigR]=getZhongxin(bianjie,X2,Y2);
%% 第四步,根据内切圆和外接圆+边界进行裁剪
disp('开始计算逻辑矩阵..');
photo=zeros(a,b);
photo(:)=nan;
for i=1:a
    for j=1:b
        if mod(i*b+j,10000)==0
            disp([int2str(i*b+j),' / ',int2str(a*b), ' OK!']);
        end
        x=X2(i,j);
        y=Y2(i,j);
        if norm(zhongxin1-[x;y])<=smallR
            photo(i,j)=Henan(i,j);%内接圆里面的都在
            continue;
        elseif norm(zhongxin2-[x;y])>=bigR
            continue;%外接圆外面的都不在
        elseif inpolygon(x,y,xv,yv)
            photo(i,j)=Henan(i,j);
        end
    end
end
disp('细裁剪完成!');
%% 第五步,画图,裁剪后的
[x,x1,y,y1] = getxy(X,Y);
x=(x-Xmin).*Pixel_; 
y=(y-Ymin).*Pixel_;
photo=flipud(photo);%contourf 上下翻转一下,才变成imshow
figure;
contourf(photo,'LineStyle','none');
colormap(gray);colorbar %jet
set(gca,'XTick',x,'XTicklabel',x1);   %设置x,y轴
set(gca,'YTick',y,'YTicklabel',y1);
title([str,'夜光遥感影像']);
%% 输出
photo(photo>=0)=1;
if nargout==3
    varargout{1}=henan; 
    varargout{2}=photo;
    varargout{3}=ex;
elseif nargout==2
    varargout{1}=henan; 
    varargout{2}=photo;
elseif nargout==1
    varargout{1}=henan; 
elseif nargout==0
    return;
else
    disp('参数不合要求!');
    return;
end
disp('--------Finished!--------');
toc  %展示运行时间
end

1.3 V2.1

function varargout=tailorsheng(varargin)
%% 此函数用于根据 shp 裁剪矩阵/图像
% 输入:
%       P2file shpfile
%       TDMSPfile tiffile,可以不是tif
%       str  要裁剪谁
%       mode 1省0国家
% 输出:
%       sheng shp
%       photo mat图像
%       ex    经纬度极值
% 调用:
%       TDMSPfile='D:\复习资料\自学\7_科研\夜光遥感\data\DMSP\F121999.v4\F121999.v4b_web.stable_lights.avg_vis.tif';
%       P2file='D:\下载\Useful\shp\国家基础地理数据\bou2_4m\bou2_4p.shp';%省界多边形
%       str='北京市';
%       mode=1;
%       [sheng,photo,ex]=tailorsheng(P2file,TDMSPfile,str);
%       [sheng,photo,ex]=tailorsheng(P2file,TDMSPfile,str,mode);
%-------------------------------------------------------------------
    %%%%    Authors:   Bill O'Hanlon
    %%%%    EMAIL:     ohanlon@qq.com
    %%%%    DATE:      24-08-2020
%% 输入
disp('-------function tailorsheng------');
tic %开始计时
mode=1;
if nargin==3
    P2file=varargin{1}; %注意,这里是{, (会是元胞
    TDMSPfile=varargin{2};
    str=varargin{3};
elseif nargin==4
    P2file=varargin{1}; %注意,这里是{, (会是元胞
    TDMSPfile=varargin{2};
    str=varargin{3};
    mode=varargin{4};%这里不做变换的话会是元胞
else
    disp('参数不合要求!');
    return;
end
%% 第一步,提取目标省份的 shp,注意看其范围
[henan,ex]=drawsheng(P2file,str,mode);
disp('shp文件搞定!');
%% 第二步,把图像大致范围剪出来,这步根据图像种类不同,代码也不一样,Attention!!
TDMSP=imread(TDMSPfile); %DMSP范围 73.49781527°E-135.0894573°E,3.83544513°N-53.56042524°N
Xmax=ex(1);              %X是经度,Y是纬度
Ymax=ex(2);              %这些已经取整了。
Xmin=ex(3);
Ymin=ex(4);
Info=geotiffinfo(TDMSPfile); %读取图像信息,比如经纬度,分辨率
global PixelScale; %定义了几个全局变量,
global Pixel_;
global XBound;
global YBound;
PixelScale=Info.PixelScale(1,1);
Pixel_=1/PixelScale;
XBound=Info.BoundingBox(1,1);
YBound=Info.BoundingBox(2,2);
[a,b]=size(TDMSP);
if(Xmax>Info.BoundingBox(2,1)) Xmax=Info.BoundingBox(2,1); end
if(Xmin<Info.BoundingBox(1,1)) Xmin=Info.BoundingBox(1,1); end
if(Ymax>Info.BoundingBox(2,2)) Ymax=Info.BoundingBox(2,2); end
if(Ymin<Info.BoundingBox(1,2)) Ymin=Info.BoundingBox(1,2); end
Xmax1=Xmax-XBound;          %这是裁剪时用的
Ymax1=YBound-Ymax;
Xmin1=Xmin-XBound;
Ymin1=YBound-Ymin;
hangs=round(Ymax1*Pixel_); %上界
hangx=round(Ymin1*Pixel_); %下界
liez=round(Xmin1*Pixel_);  %左界
liey=round(Xmax1*Pixel_);  %右
if(hangs<1) hangs=1; end
if(hangx>a) hangx=b;end
if(liez<1) liez=1; end
if(liey>b) liey=b; end

Henan=TDMSP(hangs:hangx,...
    liez:liey);%根据自己需要裁减
sprintf('粗裁剪完成! %d,%d,%d,%d',hangs,hangx,liez,liey);
%% 第三步,计算不规则边界的内切圆和外接圆
Y=Ymin:PixelScale:Ymax; %分辨率0.0083333333°  1°=120
X=Xmin:PixelScale:Xmax; %求逻辑矩阵用到
%[a,b]=size(Henan);
a=size(Y,2);
b=size(X,2);
Y2=repmat(Y',1,b);
X2=repmat(X,a,1);
Y2=flipud(Y2);                     %这个纬度得上下翻转一下。
xv=henan.X;yv=henan.Y;             %提取边界
xv = xv(1:end-1); yv = yv(1:end-1);%把最后一个NaN去掉
disp('需要计算逻辑的区域为 Figure 2 红色区域');
bianjie=[xv;yv];
%[zhongxin1,zhongxin2,smallR,bigR]=getZhongxin(bianjie,X2,Y2);
%% 第四步,根据内切圆和外接圆+边界进行裁剪
disp('开始计算逻辑矩阵..');
photo=zeros(a,b);
photo(:)=nan;
for i=1:a
    for j=1:b
        if mod(i*b+j,10000)==0
            disp([int2str(i*b+j),' / ',int2str(a*b), ' OK!']);
        end
        x=X2(i,j);
        y=Y2(i,j);
        if inpolygon(x,y,xv,yv)
            photo(i,j)=Henan(i,j);
        end
    end
end
disp('细裁剪完成!');
%% 第五步,画图,裁剪后的
[x,x1,y,y1] = getxy(X,Y);
x=(x-Xmin).*Pixel_; 
y=(y-Ymin).*Pixel_;
photo=flipud(photo);%contourf 上下翻转一下,才变成imshow
figure;
contourf(photo,'LineStyle','none');
colormap(gray);colorbar %jet
set(gca,'XTick',x,'XTicklabel',x1);   %设置x,y轴
set(gca,'YTick',y,'YTicklabel',y1);
title([str,'夜光遥感影像']);
%% 输出
photo(photo>=0)=1;
if nargout==3
    varargout{1}=henan; 
    varargout{2}=photo;
    varargout{3}=ex;
elseif nargout==2
    varargout{1}=henan; 
    varargout{2}=photo;
elseif nargout==1
    varargout{1}=henan; 
elseif nargout==0
    return;
else
    disp('参数不合要求!');
    return;
end
disp('--------Finished!--------');
toc  %展示运行时间
end

依赖:

内切圆和外接圆 :https://blog.csdn.net/Gou_Hailong/article/details/108206335
扣shp:https://blog.csdn.net/Gou_Hailong/article/details/108209395
缩放矩阵或图像:https://blog.csdn.net/Gou_Hailong/article/details/108206521
画地图注释:https://blog.csdn.net/Gou_Hailong/article/details/108208442

注:这个函数裁剪小点的边界还好,如果边界太大或者图像太大,运行时间会超级长的,这酸爽被我记录在了下面博客中:

https://blog.csdn.net/Gou_Hailong/article/details/108147268

2、调用

调用代码:

clc
clear
TDMSPfile='D:\复习资料\自学\7_科研\夜光遥感\data\DMSP\F121999.v4\F121999.v4b_web.stable_lights.avg_vis.tif';
P2file='D:\下载\Useful\shp\国家基础地理数据\bou2_4m\bou2_4p.shp';%省界多边形
str='北京市';
mode=1;
[sheng,photo,ex]=tailorsheng(P2file,TDMSPfile,str,mode);

结果:

在这里插入图片描述

CSDN 脑子秀逗了,说图片违规,dd,
博客园链接:https://www.cnblogs.com/Gou-Hailong/p/13559163.html

  • 0
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: MATLAB是一种强大的计算机软件,用于数据可视化、数值计算、绘图和编程等多种功能。其中,MATLAB也支持使用SHP(Shapefile)文件来裁剪图像。 首先,我们需要将所需的SHP文件导入MATLAB的工作环境中。这可以通过使用shapefile函数来实现,该函数需要传递SHP文件的完整路径作为参数。 接下来,我们需要加载要裁剪的原始图像。这可以通过使用imread函数来实现,该函数需要传递原始图像的完整路径或者二进制图像数据作为参数。 一旦加载了SHP文件和原始图像,我们可以使用mapshow函数来将其显示在屏幕上。然后,我们可以使用imcrop函数根据SHP文件的边界框来裁剪图像。 具体来说,我们可以使用poly2mask函数SHP文件中的多边形边界转换为二进制掩模。然后,我们可以将掩模传递给imcrop函数裁剪原始图像裁剪后的图像可以使用imshow函数来展示。 最后,我们需要将裁剪后的图像保存为新文件。这可以使用imwrite函数来实现,该函数需要传递裁剪后的图像数据和文件路径作为参数。 总之,通过使用MATLAB中的SHP图像处理函数,我们可以轻松地裁剪图像。这在地理信息系统(GIS)和遥感领域中非常有用。 ### 回答2: 在MATLAB中,我们可以使用shapefile来裁剪图像。shapefile是一种常见的GIS数据格式,用于存储空间数据。要使用shapefile进行裁剪,需要采取以下步骤: 1. 使用shapefile函数读取要用于裁剪的多边形区域的shp文件,并存储在一个变量中。 2. 使用imread函数读取要进行裁剪图像,并存储在另一个变量中。 3. 使用imref2d函数获取标准空间参考对象,其代表图像的空间参考,并存储在一个变量中。 4. 使用mapshow函数将多边形区域进行绘制并显示在图像上,以便确定要裁剪哪个区域。 5. 使用roipoly函数选择裁剪区域并存储在一个变量中。 6. 使用imcrop函数图像进行裁剪并保存。裁剪后的图像是只包含原图像中被选中区域的图像。 这是使用MATLAB进行shp裁剪的基本步骤。使用shapefile进行裁剪可以更精确地剪裁图像,从而提高图像分析的准确性和精度。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪猪头拯救地球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值