因为我们的无人机主要搭载的是多光谱相机(我们是大疆300+多光谱/高光谱),所以我们的学习主要集中在多光谱的数据分析上。当然也可以搭载近红外,高光谱,叶绿素荧光成像等。
====== 多光谱无人机传感器 =======
多光谱无人机传感器可捕获电磁波谱可见光和近红外部分的高分辨率影像,从而可以计算植被指数。
电磁波谱是波长范围很广的,每个波长都携带信息。其中只有一小部分是人眼可见的。当我们观察任何东西时,我们可以看到的是红色,绿色和蓝色(RGB)的反射色谱,我们将其解释为基于波长的彩虹颜色的任意组合。普通的RGB相机过滤波长,以获得我们可以看到的信息。多光谱相机配备了镜头和滤光片,可以拾取超出可见光谱的波长 - 在红外波长的方向上。
为什么这对分析作物和土壤很重要?因为植物和土壤根据其内容物吸收和反射来自阳光的波长。例如,当植物健康并进行光合作用时,它会吸收大量的红光和蓝光,并反射绿色和更多的红外光。
当你观察富含叶绿素(绿色)的植物时,你会看到植物反射的光的波长,而不是它吸收的波长(蓝色和红色)。叶子中叶绿素的产生导致大量的红外光反射率,但我们看不到这一点。多光谱传感器可以记录这一点。这是有用的,因为减少的红外反射率信号在我们用肉眼看到叶绿素之前就降低了叶绿素的产生,所以我们可以通过多光谱无人机传感器主动跟踪植物的健康状况,这也使得利用无人机来获取和检测植物一些重要的表型指数提供了可能。
例如:植物叶面在可见光红光波段有很强的吸收特性,在近红外波段有很强的反射特性,这是植被遥感监测的物理基础。通过这两个波段测值组合得到的NDVI指数,对土壤背景变化敏感,能较好地识别植被和水体。在植被处于中、低覆盖度时,该指数随覆盖度的增加而迅速增大,当达到一定覆盖度后增长缓慢,所以适用于植被早、中期生长阶段的动态监测。
NDVI = (ρNIR-ρR)/(ρNIR+ρR)式中:ρNIR是近红外波段的反射率,ρR是红光波段的反射率。可见光红光波段(058-068μm)位于叶绿素吸收带,近红外波段(075-110μm)位于绿色植物光谱高反射区。
NDVI取值范围:-1~1,NDVI值近似为0表示无植被的裸土区;NDVI正值表示有植被覆盖,且随覆盖度增大而增大,大于07表明该区域植被密度较高;而地面覆盖水雪区域NDVI是负值。NDVI是植物空间密度和植物生长状态的zui好指示因子,与植被覆盖的分布密度呈线性相关关系,一般应用于检测植被生长状态、植被覆盖等领域。
下图是一个小麦试验田,拼接获得的RGB合成正射影像图,以及各个波段的反射地图和指数图。
根据不同需要可以将波段进行组合计算得到植被指数,这边计算的是NDVI指数图。结合图表可以看出:红色区域表示有水区域,接近0值部分是道路和裸土,左边绿色较密集区域植被覆盖较好,右边部分由于冬小麦正处于出苗期,叶面积小,NDVI值较小呈现土**。
=== 无人机多光谱影像拼接 ====
无人机的图像拼接主要包含:图像的几何校正、图像预处理、图像配准、图像融合。
图像的几何校正:就是要校正成像过程中所造成的各种畸变,产生一幅符合某种地图投影或图形表达要求的新图像。图像预处理就是将变形的图像纠正并且统一到建立的坐标系中, 以便可测量地物的坐标信息。
图像的配准:是指对图像间的匹配信息进行提取,在提取出的信息中寻找最佳的匹配,完成图像间的对齐。图像拼接的成功与否主要是看图像的配准。
图像的融合:是指在配准以后对图像进行缝合并平滑边界,让图像过渡自然。
图像的拼接主要主要集中在频率域和空间域。频率域一般是利用Fourier变换的相位相关性。优点是使用了快速傅里叶变换 (Fast Fourier Transform, FFT) , 但是对于尺寸缩放比较敏感。空间域分为基于灰度的配准算法和基于特征的配准算法。空间域的优点是对图像变形具有较好的鲁棒性, 但是在图像之间寻找匹配的特征区域运算量比较大。
获取图像之后,就是图像的分割和特征的获取了。
分割是从预处理的图像中提取目标信息重要步骤,它通过分离一组像素(图像中感兴趣)来实现作物特定对应的区域的自动识别和量化。分割方法选择没有确定的标准,图像特点,复杂度以及分割效果等选择分割方法的依据。
而特征提取是建立一组非冗余的、能充分表示图像信息的步骤。由于基于图谱信息分析植物很大程度上取决于所提取特征的质量,例如常见的植被指数(光谱指数)、颜色特征等。然后利用这些特征指数,我们可以对作物状态进行定性分析,如发育阶段、病虫害诊断等; 对作物定量分析,如氮含量、水含量、产量等反演。根据解译所采用的特征:基于光谱的解译方法、基于图像信息的解译以及基于混合特征(图谱融合)的解译。通俗的说就是把特征指数翻译成为可以理解的表型特征。
因为我们不是研究图像这个领域的,所以就不深入去研究其中的算法了,主要采取成熟的软件和算法进行无人机影像的拼接。当然, 可处理和选择的软件很多,目前作物领域比较常用的有ENVI和Pix4Dmapper等。 我们这里主要用Pix4Dmapper。
Pix4Dmapper是专业的摄影测量软件,可将从无人机航摄影像处理得到二维地图、三维和点云模型。Pix4Dmapper支持RGB、多光谱、热红外等数据,采用全自动工作流, *** 作直观、简单,学习成本极低。整个 *** 作流程如下:
第一步:新建一个项目
第二步:填写项目名称和路径。注:好像名称不能有中文。
第三步:导入无人机影像数据。
第四步:选择数据类型和相应的指数参数设置,有航线地图的载入航线地图。
第五步:点击开始和等待。
第六步:最后获得拼接的图像。例如,下面就是获得的2个不同田块的拼接图像。然后点击指数计算器,可以计算相应的指数信息。
如果一块田种了的是很多不同的品种材料,在规划的时候,我们应该进行明显的划分,这样就可以分割图像,计算相应区域的参数,然后与基因型进行关联分析了。例如下面的测试例子,我们可以依据模型预测每个田块的发病等级。
直接在spring中配置编译的classes的路径就好,将bean的管理交给spring,不要扫描Java包,你的mybatise只要负责写sql语句就好你如果使用junit测试,parameterClass="com类"resultClass="com类"mybatis 配置mapperLocations 不能扫描java包 只能扫描resources目录下的xml文件 求解
MybatisPlus特性
快速开始
初始化测试数据表:
父工程依赖
该工程用于依赖管理,pom如下:
创建MyBaitsPlus工程
依赖如下:
properties配置
在这里配置数据库连接,以及数据连接池与mybatisplus的配置等
常规增删改查实现
创建实体类:
该lombok插件省去getset方法。
创建UserMapper接口,并且实现BaseMapper<User>这里我们指定实体类为user可直接使用接口中的方法。
UserMapperxml,如下:
执行SQL:
在SpringBoot中使用MybatisPlus分页需要注入Bean,并且在启动类上使用@MapperScan("comsimplespringbootmapper")扫描mapper文件路径如下:
使用MyBatisPlus可以为我们减少很多很多的代码,不过需要编写实体类,有失必有得。
配置动态数据源
dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。
优势
网上关于动态数据源的切换的文档有很多,核心只有两种。
如果你的数据源较少,场景不复杂,选择以上任意一种都可以。如果你需要更多特性,请尝试本动态数据源。
劣势
不能使用多数据源事务(同一个数据源下能使用事务),网上其他方案也都不能提供。
如果你需要使用到分布式事务,那么你的架构应该到了微服务化的时候了。
如果呼声强烈,项目达到800 star,作者考虑集成分布式事务。
PS: 如果您只是几个数据库但是有强烈的需求分布式事务,建议还是使用传统方式自己构建多套环境集成atomic这类,网上百度很多。
约定
建议
强烈建议在 主从模式 下遵循普遍的规则,以便他人能更轻易理解你的代码。
主数据库 建议 只执行 INSERT UPDATE DELETE *** 作。
从数据库 建议 只执行 SELECT *** 作。
快速开始
加入依赖:
注释掉原来的数据库配置,加入:
使用 @DS 切换数据源。
@DS 可以注解在方法上和类上, 同时存在方法注解优先于类上注解 。
注解在service实现或mapper接口方法上,但强烈不建议同时在service和mapper注解。 (可能会有问题)
如果不加入主键则使用默认数据源。
DruidDataSourceAutoConfigure会注入一个DataSourceWrapper,其会在原生的springdatasource下找url,username,password等。而我们动态数据源的配置路径是变化的,所以需要排除:
或者在类上排除:
然后更换properties配置信息:
本篇代码案例地址:
>
引入了以下包
其中自动装配的包就是mybatis-spring-boot-autoconfigure。
META-INF下有一个springfactories文件
导入了这个类MybatisAutoConfiguration
注册MapperScannerConfigurer的Bean定义到Spring容器中,并设置扫描包的路径
MapperScannerConfigurer 实现BeanDefinitionRegistryPostProcessor接口,实例化的时候会调到postProcessBeanDefinitionRegistry方法,这个方法里会创建一个ClassPathMapperScanner对象,然后去扫描
扫描到之后修改BeanDefinition
@MapperScan注解,会import进来MapperScannerRegistrar这个类
MapperScannerRegistrar类实现ImportBeanDefinitionRegistrar接口,实例化的时候会调用registerBeanDefinitions方法
和@Mapper一样,同样会创建MapperScannerConfigurer的BeanDefition,用于后续实例化
只不过要扫描的包路径变了,不再是默认的,而是@MapperScan配置的包路径
后面的话则和@Mapper扫描到之后的工作原理是一样的,扫描到之后,更改BeanDefinition,一毛一样的。
==可以看出@MapperScan最主要的工作原理除了提供BasePackage的值之外,就是用@Import注解导入MapperScannerRegistrar所以这个注解打在任何可以被spring扫描到的类上都可以,并不一定要打在启动类上(大多数为了只是为了看起来方便,把全局性的配置注解打在启动类上而已)==
前面提到,注册扫描@Mapper接口的MapperScannerConfigurer实例的类是AutoConfiguredMapperScannerRegistrar,那么这个类是如何被导入进来的呢
MybatisAutoConfiguration还有一个静态内部类,@Import了AutoConfiguredMapperScannerRegistrar类,但是有@ConditionalOnMissingBean,即spring容器中不存在MapperFactoryBean,MapperScannerConfigurer的实例。
如果@MapperScan注解生效,并且扫描到任意一个Mapper接口(前面被改造成MapperFactoryBean类型的了),那么就不满足注册这个类MapperScannerRegistrarNotFoundConfiguration的实例的条件,继而不会导入AutoConfiguredMapperScannerRegistrar类。
前面提到,所有的Mapper接口被扫描到,封装成BeanDefinition,还经历了一次改造,
最主要的就是将mapper接口BeanDefination的beanClass改成了orgmybatisspringmapperMapperFactoryBeanclass
并且将mapper接口BeanDefination的名称作为构造函数的入参传入进去
并讲BeanDefinition的autowireMode属性改成 AUTOWIRE_BY_TYPE ,后面实例化该bean的时候会调用属性的描述器,用write的方式注入属性值,最重要的那个属性那就是SqlSessionTemplate 会通过这种方式将前面MybatisAutoConfiguration中@Bean出来的SqlSessionTemplate注入到其中。
类图:
这里他实现了FactoryBean,
FactoryBean有以下方法
这里是spring的一个拓展点,实现了FactoryBean接口的类,将可以实现getObject() 和getObjectType来实例化额外的一个bean并装到spring容器中
好吧,其实Mapper代理对象的创建就是在MapperFactoryBean的getObject方法中返回的
这里就是熟悉的原生Mybatis创建Mapper接口的味道了。
附上调用的类时序图,回过头来看一下调用的整体流程。
1Child类根据前面输入的三个参数,即tasktracher的地址、端口、taskid。通过TaskUmbilicalProtocol协议,从TaskTracker获得需要执行的Task,在Child的main函数中调用执行。
2 在Chilld中,执行Task的run方法。Task 的run方法。是真正执行用户定义的map或者reduce任务的入口,通过TaskUmbilicalProtocol向tasktracker上报执行进度。
3 在MapTask的run中执行runMapper方法来调用mapper定义的方法。
4 在runNewMapper方法中构造mapper实例和mapper执行的配置信息。并执行mapperrun方法来调用到用户定义的mapper的方法。
5 mapper的run方法中,从输入数据中逐一取出调用map方法来处理每一条数据
6 mapper的map方法是真正用户定义的处理数据的类。也是用户唯一需要定义的方法。
说明:日常mybatis研发,需要在每个interface配置@Mapper,为了开发简便使用@MapperScan可以指定要扫描的Mapper类的包的路径
优势:避免每个interface增加注解,提升开发效率
场景:仅需加载application启动main即可
@MapperScan注解多个包
@MapperScan({"comkfitdemo","comkfituser”})
参考资料:
>
MyBatis-plus是完全基于MyBatis开发的一个增强工具,是在MyBatis的基础上做增强的框架,为简化开发、提高效率而生。
它在MyBatis原本的框架上增加了很多实用性功能,比如乐观锁插件、字段自动填充功能、分页插件、条件构造器、sql 注入器等等。使用 MyBatis-plus 可以完全不写任何 XML 文件,直接使用继承了BaseMapper 接口的类对象完成对数据库的映射 *** 作
基于映射的原理,MyBatis-plus 必然要实现 Mapper中的方法与 SQL 语句的对应转化,以下即为 MyBatis-plus 重要流程图例
1在 MyBatis-plus 中, MybatisPlusAutoConfiguration 自动配置类的 sqlSessionFactory() 方法为 Spring提供创建 sqlSession 的工厂类对象,对 sqlSessionFactory 进行定义的定义类变为了 MybatisSqlSessionFactoryBean 。
在 sqlSessionFactory() 方法中,除了注入 MyBatis本身的组件,还会注入MyBatis-plus 的 主键生成器、SQL 注入器等组件,最后通过 MybatisSqlSessionFactoryBean#getObject() 方法获取到 sqlSessionFactory 对象
2 MybatisSqlSessionFactoryBean#getObject() 执行懒加载策略,最后通过 buildSqlSessionFactory() 方法创建 SqlSessionFactory 工厂类对象。这个方法的流程很长,不过大致可以分为两个步骤:
3 MybatisXMLConfigBuilder#parse() 会去解析配置文件,最后会调用到其内部方法 mapperElement() 。这个方法完成解析 Mapper工作,并将其添加到配置类 MybatisConfiguration 中
4 MybatisConfiguration#addMapper() 方法其实是去调用 MybatisMapperRegistry#addMapper() 方法,其核心是 MybatisMapperAnnotationBuilder#parse()
5 MybatisMapperAnnotationBuilder#parse() 方法真正开始完成 Mapper 接口中的方法与 SQL 语句的映射,其中 parseStatement() 方法是解析 @Select/@Update 等注解写入的 SQL语句,而代码 GlobalConfigUtilsgetSqlInjector(configuration)inspectInject(assistant, type ) 通过 MaBatis-plus的 SQL 注入器完成 Mapper 方法与 SQL 语句的转化
6 AbstractSqlInjector#inspectInject() 会完成 BaseMapper 接口中提供的通用方法对应的 SQL 语句准备,这部分主要通过 AbstractMethod#inject() 方法完成
7 AbstractMethod#inject() 方法并没有什么特别的 *** 作,只是调用其子类实现 injectMappedStatement() 方法。以 SelectOne#injectMappedStatement() 为例,其 SQL 语句的核心在于 SqlMethod 类,这个枚举类中缓存了可以动态拼接的 SQL 语句脚本,只需要填上参数 format 就可以得到 SQL 语句的执行脚本。
以上过程结束,只需要将所有信息通过 addInsertMappedStatement() 方法封装成 MappedStatement 对象并将其加入到容器中,这样 Mapper接口方法调用时,就可以通过 动态代理 的方式找到其对应执行的 SQL 脚本,至此 SQL 语句准备及配置解析就完成了。
最后拼接的 SQL 语句 脚本形式如下示例,实际执行数据库 *** 作时会解析这个脚本完成变量替换,从而得到可执行的 SQL 语句
8 SqlSessionFactory 对象的创建需要回到 MybatisSqlSessionFactoryBean#buildSqlSessionFactory() 方法中,很容易追踪到 MybatisSqlSessionFactoryBuilder#build() 方法,最后其实是通过 SqlSessionFactoryBuilder#build() 方法创建了一个 DefaultSqlSessionFactory 对象返回
1 @MapperScan 注解通过 @Import(MapperScannerRegistrarclass) 引入扫描注册的类 MapperScannerRegistrar ,该类实现了 ImportBeanDefinitionRegistrar 接口并重写 registerBeanDefinitions() 方法,在该方法中注册了 MapperScannerConfigurer 类
2 MapperScannerConfigurer 是 Mapper接口的扫描配置类,实现了 BeanDefinitionRegistryPostProcessor 接口,其 postProcessBeanDefinitionRegistry() 方法会在容器启动过程中被回调,通过 ClassPathMapperScanner#scan() 方法完成 Mapper 的扫描注册
3 ClassPathMapperScanner#processBeanDefinitions() 将扫描到的 Mapper接口生成的对应 BeanDefinition 的 beanClass 属性替换为 MapperFactoryBean ,这样每次获取 Mapper 实例实际是通过 MapperFactoryBean 的实例去获取
此处体现了 FactoryBean 的定位,即用于获取同一类 bean 的工厂 bean。
4 @Autowired 自动注入 Mapper 触发容器获取 bean 的方法,调用到 MapperFactoryBean#getObject() 方法,最终调用到 sqlSessionTemplate#getMapper() 方法
5MyBatis-plus 使用的配置类是 MybatisConfiguration ,最终调用到 MybatisMapperRegistry#getMapper() 方法,这里就进入了动态代理获取 MapperProxy 实例的流程
6 MybatisMapperProxyFactory#newInstance() 方法给自动注入返回一个 MybatisMapperProxy 代理对象
7调用 Mapper 接口的方法触发代理对象的 MybatisMapperProxy#invoke() ,此时根据 Mapper 对象被调用的方法生成 MybatisMapperMethod 对象,通过 MybatisMapperMethod#execute() 去真正地执行 SQL 语句,从而完成数据库 *** 作。
以上就是关于【光谱数据分析】Pix4Dmapper(一)全部的内容,包括:【光谱数据分析】Pix4Dmapper(一)、mybatis 配置mapperLocations 不能扫描java包 只能扫描resources目录下的xml文件 求解、SpringBoot整合MyBatisPlus配置动态数据源等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)