本季目标为:
1.完善Qt软件(可直接进行实验)
2.基本了解主被动遥感分类与深度学习的流程,了解基准模型
3.读完10篇论文(至少五篇英文)
第一天4.24 星期一 层次聚类算法、ArcGIS中设置将结果显示出来
1.层次聚类算法
用于聚类树干(类似单木分割)
步骤:
1)找到空间中某点p10,有kdTree找到离他最近的n个点,判断这n个点到p的距离。将距离小于阈值r的点p12,p13,p14...放在类Q里
2)在Q去除p10的区间里找到一点p12,重复1
3)在Q去除p10,p12找到一点,重复1,找到p22,p23,p24...全部放进Q里
4)当Q再也不能有新点加入了,则完成搜索了
#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>
#include<pcl/visualization/pcl_visualizer.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
//定义一个表示颜色的三维矢量结构体
struct vecrgb
{
double r;
double g;
double b;
};
int main(int argc, char** argv)
{
// 读取点云数据
pcl::PCDReader reader;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
reader.read("重叠点云2_cut1.pcd", *cloud);
// KdTree的搜索方式
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud(cloud);
//聚类点集的索引
//存储单个独立的聚类
std::vector<pcl::PointIndices> cluster_indices;
// 欧几里德聚类提取及参数设计
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
ec.setClusterTolerance(0.4); // 设置空间聚类的距离0.5米 距离在0.4米以内的点将被聚类在一起。当两个点之间的距离大于0.4米时,它们将被视为不同的聚类。
ec.setMinClusterSize(35); // 设置有效聚类包含的最小的个数
ec.setMaxClusterSize(200); // 设置有效聚类包含的最大的个数
ec.setSearchMethod(tree); // 设置搜索方法
ec.setInputCloud(cloud); //设置输入点云
ec.extract(cluster_indices); // 获取切割之后的聚类索引保存到cluster_indices
// 获取每个聚类的索引个数
int j = 0;
int r, g, b = 0;
for (int it = 0; it < cluster_indices.size(); it++)
{
//逐个点集赋色
/* srand(time(NULL));*/ //这句话也不能加,加了颜色就都一样了
r = rand() % 255;
g = rand() % 255;
b = rand() % 255;
//使用ptr定义一个智能指针,方便内存管理
//智能指针确保为点云对象分配的内存得到适当的管理,当最后一个引用被删除时,该对象会被自动删除。
//"new "操作符被用来为点云对象分配内存,并且该对象的构造函数被调用,没有参数,创建一个没有点的空点云。
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZRGB>);
for (int pit = 0; pit < cluster_indices[it].indices.size(); pit++)
{
pcl::PointXYZRGB point;
//存储每个聚类之后的点的坐标和颜色
point.x = cloud->points[cluster_indices[it].indices[pit]].x;
point.y = cloud->points[cluster_indices[it].indices[pit]].y;
point.z = cloud->points[cluster_indices[it].indices[pit]].z;
point.r = r;
point.g = g;
point.b = b;
cloud_cluster->points.push_back(point);
}
//这三句话是必须写的,否则点云输出时pcl::io::savePCDFileASCII(ss.str(), *cloud_cluster);会报错
cloud_cluster->width = cloud_cluster->points.size();
//cloud_cluster->width被设置为当前簇中的点的数量,这是用pcl::PointCloud对象的point成员的size()方法得到的。
cloud_cluster->height = 1;
//cloud_cluster->height被设置为1,表示该点云代表单行的点。
cloud_cluster->is_dense = true;
//cloud_cluster->is_dense被设置为true,这意味着该点云不包含无效或NaN(非数字)值。
// 当点云被写入磁盘或用于下游处理步骤时,这些属性很重要。通过设置宽度和高度属性,点云可以被其他软件工具正确解释。
// 而通过设置is_dense为true,可以清楚地看到点云中没有丢失或无效的值。
cout << "PointCloud representing the Cluster: " << cloud_cluster->points.size() << " data points." << endl;
//点云多次输出
std::stringstream ss;
//std::stringstream ss创建一个名为ss的新字符串流对象。
ss << "聚类结果_" << j << ".pcd"; //改写成自己的点云写出路径
pcl::io::savePCDFileASCII(ss.str(), *cloud_cluster);
j++;
}
std::system("pause");//防止控制台窗口一闪而过
return (0);
}
2.关于对聚类的一些理解
1)只根据距离聚类,且对聚类起始点无要求,通常称聚类
2)根据距离聚类,且对聚类起始点有一定要求的,通常称区域生长
3)根据多种条件约束聚类,且对聚类起始点有一定要求的,通常称多特征约束生长tips:论文中对于多特征约束生长使用较多,通过改变起始点的选择方法和生长时的约束条件作为创新,在图像处理邻域该聚类方法又叫做连通性分析,不过图像opencvQ中使用的是像素之间的二维水平距离,点云pcl库使用的是点与点之间的三维空间距离。
ArcGIS中设置将结果显示出来
第二天4.25 星期二 QAxObject库的报错解决 << 与 >>
一、#include<QAxObject>报错就换成#include<ActiveQt/QAxObject>
二、报错含有QAxObject库的代码可能会报错
1)无法打开源文件QAxObject
解决:添加模块
2)无法解析的外部符号:
解决:1.在项目->属性->链接器->输入->附加依赖项
release:Qt5AxContainer.lib;Qt5AxBase.lib
debug:Qt5AxContainerd.lib;Qt5AxBased.lib
2.在连接器 -> 常规 -> 附加库
$(QTDIR)\LIB
若还不行:3.在项目->属性->链接器->输入->附加依赖项 中添加qtmain.lib
三、>>是输入 <<是输出
第三天4.26 星期三 外部类放入自己的程序中
外部类如何放入自己的程序中:
例子:针对excelengine类,源自:GitHub - TheThreeDog/ExcelEngine: 一个基于Qt的Excel操作引擎,封装了操作Excel文件的部分接口,相比直接使用QAxObject更加方便,代码可读性也更好。
1.关注.h文件中的获取单例模式的对象的代码
2.在你的主窗口代码的头文件中加入该对象
3.cpp文件中也要加入
4.之后便可以正常使用了
第四天4.27 星期四 导航栏(treeWidget)设计
1.导航栏中设置图标与子节点
imageItem1->setIcon(0, QIcon(":/img/1.png"));
QTreeWidgetItem* imageItem1_1 = new QTreeWidgetItem(imageItem1, QStringList(QString("Band1"))); //子节点1
imageItem1_1->setIcon(0, QIcon(":/img/1.png"));
imageItem1->addChild(imageItem1_1); //添加子节点
2.定义父子节点的导航栏
ui->treeWidget->expandAll(); //结点全部展开
QStringList l;
l << QStringLiteral("点位1");
//第一个参数指向自己,第二个参数必须重载QStringList
QTreeWidgetItem* pf = new QTreeWidgetItem(ui->treeWidget, l);
l.clear();
l << QStringLiteral("东方向位移");
QTreeWidgetItem* p1 = new QTreeWidgetItem(pf, l);
//此处必须为pf否则将不会显示父子关系
l.clear();
l << QStringLiteral("北方向位移");
QTreeWidgetItem* p2 = new QTreeWidgetItem(pf, l);
l.clear();
l << QStringLiteral("纵向位移");
QTreeWidgetItem* p3 = new QTreeWidgetItem(pf, l);
ui->treeWidget->addTopLevelItem(pf);
pf->addChild(p1);
pf->addChild(p2);
pf->addChild(p3);
3.写C++代码的顺序:先写头文件中的函数定义,成员变量;再写函数定义
4.经典函数分析:数据库的修改函数往往是增加函数重写,核心在意设置一个setType函数
//设置类型,判断是增加还是修改
void Dlg_AddStu::setType(bool isAdd,stuInfo info) //如果调用时参数是true,则不用传入info,如果是false,则需要
{
m_isAdd = isAdd; //是添加
m_info = info; //将形参info转为成员变量m_info,以便该类的其他函数使用
//把六个属性拿到,写入输入栏中
ui->le_name->setText(info.name);
ui->sp_age->setValue(info.age);
ui->le_class->setText(QString::number(info.uiclass));
ui->le_grade->setText(QString::number(info.grade));
ui->le_phone->setText(info.phone);
ui->le_wechat->setText(info.Wechat);
}
5.QSqlQuery sql(m_db) 语句解释
使用了Qt中的QSqlQuery类,它表示一个SQL查询操作,并使用一个QSqlDatabase对象作为其构造函数的参数。这个QSqlDatabase对象(在这个例子中命名为"m_db")是一个已经打开的数据库连接,它被用于执行SQL查询操作。
在这段代码中,QSqlQuery对象被初始化为一个名称为"sql"的变量,它将使用"m_db"作为其执行SQL查询操作的目标数据库。这个QSqlQuery对象可以执行各种类型的SQL查询语句,例如SELECT、INSERT、UPDATE和DELETE语句,以及执行存储过程和函数。
一旦QSqlQuery对象被创建,就可以使用它来执行SQL查询语句,例如:
sql.exec("SELECT * FROM customers WHERE name LIKE 'John%'");
这个示例演示了如何使用QSqlQuery对象执行一个简单的SELECT查询操作,以查找名字以"John"开头的客户记录。在这个示例中,QSqlQuery对象的exec()函数被用于执行SQL查询语句,并返回一个QSqlQuery对象,该对象可以用于访问查询结果。
第五天4.28 星期五 数据表的优化 结构体设计 获取当前时间
1.sqlite不支持truncate来清空数据,可以使用delete from 表名
2.结构体的创建在数据库处理方面至关重要,因为可以用该结构体当做一种数据类型
struct dataInfo
{
QString GPST;
QString eb;
QString nb;
QString ub;
QString Q;
QString ns;
QString sde;
QString sdn;
QString sdu;
QString sden;
QString sdnu;
QString sdue;
QString age;
QString ratio;
};
dataInfo info
QList<dataInfo>
QList<dataInfo> getPagedata(quint32 page, quint32 uiCnt);
3.如果你的数据库id列不是自增的,而且还是null,那就将其设置为主键
4.报错问题解决
可能1:数据表里的数据不匹配,修改数据库即可
可能2:绘图函数在数据函数前执行,没有数据表就没法根据数据画图
5. 获取当前时间,并加入到timeValues列表中
QVector<QDateTime> timeValues;
timeValues.append(now.addSecs(i * 60));
第六天4.29 星期六 visio/office安装 ceil函数
1.ceil函数:用于向上取整
2.visio的安装:
1)先装visio再装office
2)visio和office版本要相同,如都是2016,且不能一个是c2r(即点即用),一个是MSI(Windows installer)
3)visio和office的位数要相同,如都是64位
3.office可使用学校的正版软件管理与服务平台
第七天4.30 星期日 IDM使用
1.IDM代理服务器的使用
1)下载-选项-代理服务器-点“使用系统中的设置”按钮
2)查本机的代理服务器地址和端口即可
cmd-输入ipconfig或使用软件
第八天5.1 星期一 伪彩色处理
1.伪彩色处理: 即将图像的每个像素值定义为一个索引值或代码值,然后根据其在色彩查找表里去查找,根据该地址得到真实的色彩。这个过程叫伪彩色处理,生成的叫伪彩色图像。
其在高光谱地物分类中的重要意义:
1)颜色信息的增强:伪彩色图像通常使用颜色来增强图像的视觉效果,使它们更具有吸引力和感染力。颜色信息的增强可以通过添加特定的颜色、调整颜色分布和使用特定的算法来实现,从而使图像具有更高的亮度和更宽的色域范围。
2)色彩信息的差异:伪彩色图像通常只涵盖了物体的一部分,而真彩色图像通常只考虑物体的一部分,而伪彩色处理可以将不同物体之间的颜色差异考虑在内,从而更好地反映物体的细节和特征。
3)色彩信息的计算:伪彩色处理需要计算两个或多个像元之间的色彩距离,这可以帮助识别不同物体。真彩色图像通常只考虑像元之间的颜色距离,而伪彩色处理需要考虑更多细节和特征。
第九天5.2 星期二 三篇关于HSI+lidar论文的阅读
今天主要读了三篇关于HSI结合lidar进行分类的论文,分别为:
1.结合多种特征+CNN/RF/SVM三种方法的树种分类对比
2.使用RF的地物分类,基础内容讲得很细致
3.使用RF进行的土地利用分类,其内容较简单
第十天5.3 星期三 AM3Net MSI和SAR 几种深度学习方法的分析 HSI区域 CNN种类
今天主要阅读和学习了关于AM3Net的建构模型与分析,其核心内容见专刊,其他扩展知识如下:
1.MSI和SAR的一些优势
MSI:可以捕获不同波长目标的能量散射和辐射效应
SAR:捕获特定微博波段目标的幅度和相位特性
2.几种深度学习方法的分析
1)ELM:前额神经网络算法,其他的为反向传播神经网络;有明显劣势
2)EndNet:模型参数少,但学习效率低,需要更多的训练次数来学习最好的模型
3)DeepCNN:特征编码部分网络结构简单
4)FusAtNet:基于多种注意力机制设计,尽管去掉了一些数据增强,但
5)HRWN:基于后优化的设计思路,在获得融合模型的分类结构后,还需要通过基于随机游走的主动学习算法进一步优化分类结果
3.深度学习方法相较于传统机器学习方法的优势
可以从输入数据中自动提取特征
4.三种CNN的区别与用法
1D-CNN 单一光谱信号
2D-CNN 照片图像
3D-CNN 高光谱立方体/体数据
5.高光谱区域:
可见和近红外(VNIR):400nm~1000nm 【该区域较为常见】
短波红外(SWIR):900nm~2500nm
引自:J. Wang, J. Li, Y. Shi, J. Lai and X. Tan, "AM3Net: Adaptive Mutual-learning-based Multimodal Data Fusion Network," in IEEE Transactions on Circuits and Systems for Video Technology, vol. 32, no. 8, pp. 5411-5426, Aug. 2022, doi: 10.1109/TCSVT.2022.3148257.
第十一天5.4 星期四 ※pytorch的环境配置 visdom的使用 setup安装方法
今天完成了pytorch的环境配置和visdom的使用以及anaconda创建虚拟环境的基本方法:
一、pytorch环境的总体安装步骤,以AM3Net的环境为例
1.建虚拟环境,安装pytorch(CPU+GPU),用代码检验
其中:CPU的用官网给出的指令,GPU用轮子下载
注1:在验证python时如何电脑里有多个版本的python可能会冲突报错,比如你的anaconda是python3,你的电脑里原本有python2,那么这时直接通过在cmd中使用python命令会直接转到电脑里的python2,会报错:Warning: This Python interpreter is in a conda environment, but the environment has not been activated. Libraries may fail to load. To activate this environment please see Managing environments — conda 0.0.0.dev0+placeholder documentation
解决办法:将虚拟环境目录下的python改成python37,运行python37,然后再改回python就行了
但推荐还是使用pycharm或Spyder运行,直接设置环境,以免冲突
注2:可在C:\用户\用户名下的.condarc文件(用记事本打开),查看和修改配置环境的库,如
2.安装visdom,先使用命令安装时,若出现报错:
PackagesNotFoundError: The following packages are not available from current channels:
- visdom
Current channels:- Index of /anaconda/cloud/pytorch/win-64/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
- Index of /anaconda/cloud/pytorch/noarch/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
- Index of /anaconda/pkgs/free/win-64/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
- Index of /anaconda/pkgs/free/noarch/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
- Index of /anaconda/pkgs/main/win-64/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
- Index of /anaconda/pkgs/main/noarch/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
- r/win-64
- r/noarch
To search for alternate channels that may provide the conda package you're
looking for, navigate to
and use the search bar at the top of the page.
解决方法:在 https://anaconda.org 中搜索库,然后按里面的方法显示;但要看清版本
注:visdom库会带下来一堆库,不用担心
3.安装MMCV,这个库可以用setup.py安装,也可以用指令安装,但推荐后者,使用:pip install mmcv==1.3.1rc4 -f ( )https://download.openmmlab.com/mmcv/dist/cu110/torch1.7/index.html
注:MMCV库会带下来一堆库,不用担心
4.cupy-cuda110的安装也会同visdom安装时一样出现那种问题,遇到时解决方法一致
5.numpy、scipy、sklearn(scikit-learn)安装,直接用指令即可
二、visdom相关
1.visdom安装时还可能出现问题的解决方法:
1)修改server.py文件
找到Anaconda3\Lib\site-packages\visdom\server.py文件,注释掉download那一行
2)替换static文件夹
下载地址:
替换相应的文件夹即可
2.visdom的启动指令:python -m visdom.server(在命令行终端使用)
3.验证代码:
import visdom
import torch
vis = visdom.Visdom()
x = torch.arange(1,100,0.01)
y=torch.sin(x)
vis.line(X=x, Y=y,win='sinx',opts={'title':'text1'})
三、setup安装方法
如在使用setup.py进行安装时,报错
ImportError: cannot import name ‘_nt_quote_args‘ from ‘distutils.spawn‘
解决办法:
先安装setuptools:
pip install setuptools==59.6.0
再尽显安装:
python setup.py install
第十二天5.5 星期五 conda基础指令 问题汇总 mat格式与tif格式的互相转化
一、conda的几个常用命令:
1.创建环境:conda create -n name python=3.6(你conda的版本)
2.查看现有环境:conda info --envs 或 conda env list
3.激活环境:conda activate name
4.退出环境:conda deactivate
5.删除环境:conda remove -n name --all
6.查看环境中库的列表:conda list
7.安装/卸载库:conda install/uninstall 库名+(网址)/轮子
注:如果是在pycharm中,6和7使用pip而不是conda
二、问题汇总
1.如果虚拟环境和真实环境的库冲突,就直接将真实环境中的那个移走
2.若报错
UserWarning: Cannot import torch.fx, `merge_dict` is a simple function to merge multiple dicts
warnings.warn('Cannot import torch.fx, `merge_dict` is a simple function '
是因为mmcv的版本和pytorch版本不匹配,pytorch中没有fx,但必须1.8以上的pytorch才能安装fx,其实并没有太大问题,若想要解决,要么重新安装pytorch至适应的版本,要么重新安装mmcv至适应的版本,推荐后者
3.若报错
UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.
weight_alpha = F.softmax(self.Weight_Alpha)
解决方法:这个警告信息是因为在 PyTorch 中,torch.nn.functional.softmax
函数默认对输入张量的最后一个维度进行 softmax 操作。但是在某些情况下,可能输入张量的形状不符合预期,因此 PyTorch 提醒用户显式指定在哪个维度上进行 softmax。
为了消除这个警告信息,可以将原来的代码:
weight_alpha = F.softmax(self.Weight_Alpha)
改为:
weight_alpha = F.softmax(self.Weight_Alpha, dim=-1)
其中,dim=-1
表示对张量的最后一个维度进行 softmax 操作。你也可以根据具体情况,指定其他的维度进行操作。