【代码能力提升 | 代码阅读学习】分析 VoxelNet 的 主干

文章目录

  • 前言
  • 代码分析
    • VoxelNet model
    • 2.数据处理
      • 2.1单个样本处理
      • 2.2处理成batch
  • 最后,附上我一步步调试代码,到3D-conv

前言

代码来自:https://github.com/skyhehe123/VoxelNet-pytorch
其中 测试数据来自:https://github.com/gakkiri/simple-pointpillar

代码分析

VoxelNet model

  1. model forward()就是模型的输入,voxel_features, voxel_coords是一个 batch 的数据。

    • voxel_features: [P, T, C], voxel_coords: [P, 4]。如何知道是 batch中的第几个样本? voxel_coords中的[P, 0]维度告诉了,其中的数据巧妙处理在 文件 kitti.pytrain.py, 稍后我们介绍
    • 转换为grid tensor: voxel_indexing(), 其中sparse_features.t()应该有.t(), 不然维度不匹配报错,原代码错了。经过这一步,输出维度为[B, C, D, H, W]。【这个函数妙啊,一个索引匹配就完成了 点云=> 规则张量,美中不足的是原代码写错了,需要加个转置.t()
      • 一个小样例测试这段代码 正确与否
    import torch
    
    sparse_features = torch.tensor([[1.0, 1, 1], [2, 2, 2]])
    coords = torch.IntTensor([[0,0,0,1], [1,0,0,2]]) # [P, 4(id,x,y,z)]
    
    dense_feature = torch.zeros(3, 2, 3,3,3) # [dim, B, D, H, W]
    dense_feature[:, coords[:,0], coords[:,1], coords[:,2], coords[:,3]]= sparse_features.t()
    print(dense_feature[:, 0, 0, 0, 1])
    print(dense_feature[:, 1, 0, 0, 2])
    
    输出, 刚好索引回来
    tensor([1., 1., 1.])
    tensor([2., 2., 2.])
    
    • 然后可以经过3D-Conv,后续接你需要的 任务头head,上面才是 VoxelNet的主干,也是最难理解的地方。
class VoxelNet(nn.Module):

    def __init__(self):
        super(VoxelNet, self).__init__()
        self.svfe = SVFE()
        self.cml = CML()
        # self.rpn = RPN()

    def voxel_indexing(self, sparse_features, coords):
        """
            sparse_features: [P, C]
            coords:[P, 4]
        """
        dim = sparse_features.shape[-1]
        device = sparse_features.device

        dense_feature = Variable(torch.zeros(dim, cfg.N, cfg.D, cfg.H, cfg.W).to(device))

        dense_feature[:, coords[:,0], coords[:,1], coords[:,2], coords[:,3]]= sparse_features.t()

        dense_feature = dense_feature.transpose(0, 1)
        # print(f"dense_feature.shape = {dense_feature.shape}")
        # return dense_feature.transpose(0, 1) # dense_feature.transpose(0, 1):[ B, C, D, H, W]
        return dense_feature

    def forward(self, voxel_features, voxel_coords):

        """
            P: 一个batch合计的 voxel的数量
            T:一个voxel的点数 35
            C:每个点 的维度 7(=4 + 3)
            voxel_features: [P, T, C]
            voxel_coords: [P, 4(1+3)] => 每个voxel_coords 含4个维度,分别为 1+3,这个1就是指代这个 voxel 原来在 batch的第几个(就是这样来区分的),3表示grid的坐标
        """
        print(f"forward=============>")
        print(f'voxel_features.shape = {voxel_features.shape}, voxel_coords.shape = {voxel_coords.shape}') # voxel_features.shape = (20284, 35, 7), voxel_coords.shape = (20284, 4)

        # feature learning network
        vwfs = self.svfe(voxel_features) # vwfs:[P, C]
        
        print(f'=> vwfs.shape = {vwfs.shape}') # vwfs.shape = torch.Size([20284, 128])

        vwfs = self.voxel_indexing(vwfs,voxel_coords)
        print(f'voxel_indexing ==> vwfs.shape = {vwfs.shape}') # voxel_indexing ==> vwfs.shape = torch.Size([2, 128, 10, 400, 352]) [B, C, D, H, W]
        # convolutional middle network
        cml_out = self.cml(vwfs)
        print(f"cml_out.shape = {cml_out.shape}") # cml_out.shape = torch.Size([2, 64, 2, 400, 352])
        # # region proposal network

        # # merge the depth and feature dim into one, output probability score map and regression map
        # psm,rm = self.rpn(cml_out.view(cfg.N,-1,cfg.H, cfg.W))

        # return psm, rm

2.数据处理

2.1单个样本处理

kitti.py文件的 def __getitem__(self, i):

可以看到,每帧lidar:[N, C],读取后经过这样处理:

  • 数据增强,
  • 范围过滤,
  • 处理成规则张量preprocess, 维度从 [N, C] 变为 [P, T, C], 其中,P不定,T=35,C=7

在这里插入图片描述

它是这样 处理的,可以学习代码:
其实,我不是很明白,这里为什么要 换维度?按理说3D-Conv都一样。

        # convert to  (D, H, W)
        voxel_coords = voxel_coords[:,[2,1,0]]

    def preprocess(self, lidar):

        # shuffling the points
        np.random.shuffle(lidar)

        voxel_coords = ((lidar[:, :3] - np.array([self.xrange[0], self.yrange[0], self.zrange[0]])) / (
                        self.vw, self.vh, self.vd)).astype(np.int32)

        # convert to  (D, H, W)
        voxel_coords = voxel_coords[:,[2,1,0]]
        voxel_coords, inv_ind, voxel_counts = np.unique(voxel_coords, axis=0, \
                                                  return_inverse=True, return_counts=True)

        voxel_features = []

        for i in range(len(voxel_coords)):
            voxel = np.zeros((self.T, 7), dtype=np.float32)
            pts = lidar[inv_ind == i]
            if voxel_counts[i] > self.T:
                pts = pts[:self.T, :]
                voxel_counts[i] = self.T
            # augment the points
            voxel[:pts.shape[0], :] = np.concatenate((pts, pts[:, :3] - np.mean(pts[:, :3], 0)), axis=1)
            voxel_features.append(voxel)
        return np.array(voxel_features), voxel_coords

2.2处理成batch

train.py文件中

处理流程:从batch中取出每个样本sample,给 每个样本sample 的coord的第0列添加序号,标记 是batch的第几个样本,方便后面转换为规则张量【主要是这个】。

    def detection_collate(batch):
        voxel_features = []
        voxel_coords = []
    
        for i, sample in enumerate(batch):
            voxel_features.append(sample[0])

            voxel_coords.append(
                np.pad(sample[1], ((0, 0), (1, 0)),
                    mode='constant', constant_values=i))
        return np.concatenate(voxel_features), \
            np.concatenate(voxel_coords), \

最后,附上我一步步调试代码,到3D-conv

import torch.nn as nn
import torch.nn.functional as F
import torch
from torch.autograd import Variable
from config import config as cfg


####

# from my_kitti.py
import sys
sys.path.append(r"D:\workspace\【代码能力提升-深度学习】\voxel_and_pillar_code\VoxelNet-pytorch-master\VoxelNet-pytorch-master")


import os
import os.path
import torch.utils.data as data
import utils
from utils import box3d_corner_to_center_batch, anchors_center_to_corner, corner_to_standup_box2d_batch
from data_aug import aug_data
# from box_overlaps import bbox_overlaps
import numpy as np
import cv2

###

# conv2d + bn + relu
class Conv2d(nn.Module):

    def __init__(self,in_channels,out_channels,k,s,p, activation=True, batch_norm=True):
        super(Conv2d, self).__init__()
        self.conv = nn.Conv2d(in_channels,out_channels,kernel_size=k,stride=s,padding=p)
        if batch_norm:
            self.bn = nn.BatchNorm2d(out_channels)
        else:
            self.bn = None
        self.activation = activation
    def forward(self,x):
        x = self.conv(x)
        if self.bn is not None:
            x=self.bn(x)
        if self.activation:
            return F.relu(x,inplace=True)
        else:
            return x

# conv3d + bn + relu
class Conv3d(nn.Module):

    def __init__(self, in_channels, out_channels, k, s, p, batch_norm=True):
        super(Conv3d, self).__init__()
        self.conv = nn.Conv3d(in_channels, out_channels, kernel_size=k, stride=s, padding=p)
        if batch_norm:
            self.bn = nn.BatchNorm3d(out_channels)
        else:
            self.bn = None

    def forward(self, x):
        x = self.conv(x)
        if self.bn is not None:
            x = self.bn(x)

        return F.relu(x, inplace=True)

# Fully Connected Network
class FCN(nn.Module):

    def __init__(self,cin,cout):
        super(FCN, self).__init__()
        self.cout = cout
        self.linear = nn.Linear(cin, cout)
        self.bn = nn.BatchNorm1d(cout)

    def forward(self,x):
        # KK is the stacked k across batch
        kk, t, _ = x.shape # x:[P, T, C]
        x = self.linear(x.view(kk*t,-1))
        x = F.relu(self.bn(x))
        return x.view(kk,t,-1)

# Voxel Feature Encoding layer
class VFE(nn.Module):

    def __init__(self,cin,cout):
        super(VFE, self).__init__()
        assert cout % 2 == 0
        self.units = cout // 2
        self.fcn = FCN(cin,self.units)

    def forward(self, x, mask):
        # point-wise feauture
        pwf = self.fcn(x) # pwf:[P, T, C]
        #locally aggregated feature
        laf = torch.max(pwf,1)[0].unsqueeze(1).repeat(1,cfg.T,1)
        # point-wise concat feature
        pwcf = torch.cat((pwf,laf),dim=2) # point-wise and locally, cat起来
        # apply mask
        mask = mask.unsqueeze(2).repeat(1, 1, self.units * 2)
        pwcf = pwcf * mask.float()

        return pwcf

# Stacked Voxel Feature Encoding
class SVFE(nn.Module):

    def __init__(self):
        super(SVFE, self).__init__()
        self.vfe_1 = VFE(7,32)
        self.vfe_2 = VFE(32,128)
        self.fcn = FCN(128,128)
    def forward(self, x): # x:[P, T, C]
        mask = torch.ne(torch.max(x,2)[0], 0)
        x = self.vfe_1(x, mask)
        x = self.vfe_2(x, mask)
        x = self.fcn(x)
        # element-wise max pooling
        x = torch.max(x,1)[0] # x: [P, C], 相当于 只取每个voxel 的max feature
        return x

# Convolutional Middle Layer
class CML(nn.Module):
    def __init__(self):
        super(CML, self).__init__()
        self.conv3d_1 = Conv3d(128, 64, 3, s=(2, 1, 1), p=(1, 1, 1))
        self.conv3d_2 = Conv3d(64, 64, 3, s=(1, 1, 1), p=(0, 1, 1))
        self.conv3d_3 = Conv3d(64, 64, 3, s=(2, 1, 1), p=(1, 1, 1))

    def forward(self, x):
        x = self.conv3d_1(x)
        x = self.conv3d_2(x)
        x = self.conv3d_3(x)
        return x

# Region Proposal Network
# class RPN(nn.Module):
#     def __init__(self):
#         super(RPN, self).__init__()
#         self.block_1 = [Conv2d(128, 128, 3, 2, 1)]
#         self.block_1 += [Conv2d(128, 128, 3, 1, 1) for _ in range(3)]
#         self.block_1 = nn.Sequential(*self.block_1)

#         self.block_2 = [Conv2d(128, 128, 3, 2, 1)]
#         self.block_2 += [Conv2d(128, 128, 3, 1, 1) for _ in range(5)]
#         self.block_2 = nn.Sequential(*self.block_2)

#         self.block_3 = [Conv2d(128, 256, 3, 2, 1)]
#         self.block_3 += [nn.Conv2d(256, 256, 3, 1, 1) for _ in range(5)]
#         self.block_3 = nn.Sequential(*self.block_3)

#         self.deconv_1 = nn.Sequential(nn.ConvTranspose2d(256, 256, 4, 4, 0),nn.BatchNorm2d(256))
#         self.deconv_2 = nn.Sequential(nn.ConvTranspose2d(128, 256, 2, 2, 0),nn.BatchNorm2d(256))
#         self.deconv_3 = nn.Sequential(nn.ConvTranspose2d(128, 256, 1, 1, 0),nn.BatchNorm2d(256))

#         self.score_head = Conv2d(768, cfg.anchors_per_position, 1, 1, 0, activation=False, batch_norm=False)
#         self.reg_head = Conv2d(768, 7 * cfg.anchors_per_position, 1, 1, 0, activation=False, batch_norm=False)

#     def forward(self,x):
#         x = self.block_1(x)
#         x_skip_1 = x
#         x = self.block_2(x)
#         x_skip_2 = x
#         x = self.block_3(x)
#         x_0 = self.deconv_1(x)
#         x_1 = self.deconv_2(x_skip_2)
#         x_2 = self.deconv_3(x_skip_1)
#         x = torch.cat((x_0,x_1,x_2),1)
#         return self.score_head(x),self.reg_head(x)


class VoxelNet(nn.Module):

    def __init__(self):
        super(VoxelNet, self).__init__()
        self.svfe = SVFE()
        self.cml = CML()
        # self.rpn = RPN()

    def voxel_indexing(self, sparse_features, coords):
        """
            sparse_features: [P, C]
            coords:[P, 4]
        """
        dim = sparse_features.shape[-1]
        device = sparse_features.device

        dense_feature = Variable(torch.zeros(dim, cfg.N, cfg.D, cfg.H, cfg.W).to(device))

        dense_feature[:, coords[:,0], coords[:,1], coords[:,2], coords[:,3]]= sparse_features.t()

        dense_feature = dense_feature.transpose(0, 1)
        # print(f"dense_feature.shape = {dense_feature.shape}")
        # return dense_feature.transpose(0, 1) # dense_feature.transpose(0, 1):[ B, C, D, H, W]
        return dense_feature

    def forward(self, voxel_features, voxel_coords):

        """
            P: 一个batch合计的 voxel的数量
            T:一个voxel的点数 35
            C:每个点 的维度 7(=4 + 3)
            voxel_features: [P, T, C]
            voxel_coords: [P, 4(1+3)] => 每个voxel_coords 含4个维度,分别为 1+3,这个1就是指代这个 voxel 原来在 batch的第几个(就是这样来区分的),3表示grid的坐标
        """
        print(f"forward=============>")
        print(f'voxel_features.shape = {voxel_features.shape}, voxel_coords.shape = {voxel_coords.shape}') # voxel_features.shape = (20284, 35, 7), voxel_coords.shape = (20284, 4)

        # feature learning network
        vwfs = self.svfe(voxel_features) # vwfs:[P, C]
        
        print(f'=> vwfs.shape = {vwfs.shape}') # vwfs.shape = torch.Size([20284, 128])

        vwfs = self.voxel_indexing(vwfs,voxel_coords)
        print(f'voxel_indexing ==> vwfs.shape = {vwfs.shape}') # voxel_indexing ==> vwfs.shape = torch.Size([2, 128, 10, 400, 352]) [B, C, D, H, W]
        # convolutional middle network
        cml_out = self.cml(vwfs)
        print(f"cml_out.shape = {cml_out.shape}") # cml_out.shape = torch.Size([2, 64, 2, 400, 352])
        # # region proposal network

        # # merge the depth and feature dim into one, output probability score map and regression map
        # psm,rm = self.rpn(cml_out.view(cfg.N,-1,cfg.H, cfg.W))

        # return psm, rm


if __name__ == '__main__':
    

    class My_dataset(data.Dataset):
        def __init__(self, cfg):
            self.T = cfg.T
            self.vd = cfg.vd
            self.vh = cfg.vh
            self.vw = cfg.vw
            self.xrange = cfg.xrange
            self.yrange = cfg.yrange
            self.zrange = cfg.zrange
        
        def preprocess(self, lidar):

            # shuffling the points
            np.random.shuffle(lidar)

            voxel_coords = ((lidar[:, :3] - np.array([self.xrange[0], self.yrange[0], self.zrange[0]])) / (
                            self.vw, self.vh, self.vd)).astype(np.int32)

            # convert to  (D, H, W)
            voxel_coords = voxel_coords[:,[2,1,0]]
            voxel_coords, inv_ind, voxel_counts = np.unique(voxel_coords, axis=0, \
                                                    return_inverse=True, return_counts=True)

            voxel_features = []

            for i in range(len(voxel_coords)):
                voxel = np.zeros((self.T, 7), dtype=np.float32)
                pts = lidar[inv_ind == i]
                if voxel_counts[i] > self.T:
                    pts = pts[:self.T, :]
                    voxel_counts[i] = self.T
                # augment the points
                voxel[:pts.shape[0], :] = np.concatenate((pts, pts[:, :3] - np.mean(pts[:, :3], 0)), axis=1)
                voxel_features.append(voxel)
            return np.array(voxel_features), voxel_coords 
        
    def detection_collate(batch):
        voxel_features = []
        voxel_coords = []
    
        for i, sample in enumerate(batch):
            voxel_features.append(sample[0])

            voxel_coords.append(
                np.pad(sample[1], ((0, 0), (1, 0)),
                    mode='constant', constant_values=i))
        return np.concatenate(voxel_features), \
            np.concatenate(voxel_coords), \
    


    from config import config as cfg    
    my_dataset = My_dataset(cfg)        

    # lidar_file = self.lidar_path + '/' + self.file_list[i] + '.bin'
    lidar_file = r"D:\workspace\【代码能力提升-深度学习】\voxel_and_pillar_code\simple-pointpillar-main\simple-pointpillar-main\kitti_test_data\000000.bin"
    lidar = np.fromfile(lidar_file, dtype=np.float32).reshape(-1, 4) # (N, 4)
    print(f'lidar.shape = {lidar.shape}') # lidar.shape = (115384, 4)


    # 对单个样本lidar进行数据处理,包括数据增强,限制范围,预处理
    # 这里我们没有 gt_box3d ,所以忽略 aug_data

    # data augmentation
    # lidar, gt_box3d = aug_data(lidar, gt_box3d) 

    # specify a range
    lidar = utils.get_filtered_lidar(lidar )
    print(f'get_filtered_lidar => lidar.shape = {lidar.shape}') # get_filtered_lidar => lidar.shape = (62853, 4)
    voxel_features, voxel_coords = my_dataset.preprocess(lidar)
    print(f'voxel_features.shape = {voxel_features.shape}, voxel_coords.shape = {voxel_coords.shape}') 
    print(f'type(voxel_features) = {type(voxel_features)}, type(voxel_coords) = {type(voxel_coords)}')
    # voxel_features.shape = (10142, 35, 7) = (P, T, C(4 + 3)), voxel_coords.shape = (10142, 3) (P, C(xyz))
    # type(voxel_features) = <class 'numpy.ndarray'>, type(voxel_coords) = <class 'numpy.ndarray'>


    
    # 模拟一个 batch 两个样本
    batch = []
    batch.append((voxel_features, voxel_coords))
    batch.append((voxel_features, voxel_coords))

    batch_voxel_features, batch_voxel_coords = detection_collate(batch)

    # batch_voxel_features = Variable(torch.cuda.FloatTensor(batch_voxel_features)) # 变为 tensor类型
    batch_voxel_features = Variable(torch.FloatTensor(batch_voxel_features)) # 变为 tensor类型
    # print(f'batch_voxel_features.shape = {batch_voxel_features.shape}')
    # print(batch_voxel_coords[-5:])    

    model = VoxelNet()

    y = model(batch_voxel_features, batch_voxel_coords)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/360820.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python爬虫之豆瓣首页图片爬取

网址&#xff1a;https://movie.douban.com/ import requests from lxml import etree import re url https://movie.douban.com headers {User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/5…

CGAL5.4.1 边塌陷算法

目录 1、使用曲面网格的示例 2、使用默认多面体的示例 3、使用丰富多面体的示例 主要对1、使用曲面网格的示例 进行深度研究 CGAL编译与安装CGAL安装到验证到深入_cgal测试代码-CSDN博客 参考资料CGAL 5.4.5 - Triangulated Surface Mesh Simplification: User Manual …

卡片式 UI 设计的 8 个秘诀,让你轻松打造高颜值界面

做卡片设计最重要的是什么&#xff1f;我将在这篇文章中分享 8 最关键的细节。在此之前&#xff0c;让我们一起来对付一下。 UI 梳理卡片设计的基础&#xff0c;总结哪些场景适合卡片设计。 卡片是 UI 其中一个组件元素可以创建一个清晰的视觉单元&#xff0c;使信息更具逻辑性…

expect 语言 Here Document 多行重定向

一、expect是什么 1.1 expect定义 是建立在tcl&#xff08;tool command language&#xff09;语言基础上的一个工具&#xff0c;常被用于进行自动化控制和测试&#xff0c;解决shell脚本中交互的相关问题 1.2 怎么安装expect yum install -y expect 进行安装 二、怎么使用e…

力扣hot100 电话号码的字母组合 回溯

Problem: 17. 电话号码的字母组合 文章目录 思路复杂度&#x1f49d; Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 复杂度 时间复杂度: O ( 3 8 ) O(3^8) O(38) 空间复杂度: O ( 3 8 ) O(3^8) O(38) &#x1f49d; Code class Solution {String[] map { "…

实战项目(二)汽车保养管家系统

一、实现技术 前端技术&#xff1a;html、javascript(jquery、ajax、json)、css、layui 后端技术&#xff1a;java、mysql、servlet 开发工具&#xff1a;eclipse、vscode 二、项目描述 基于web的汽车保养管家系统的设计与实现 一、功能需求 1&#xff0e;用户功能 1.1…

《Pandas 简易速速上手小册》第1章:Pandas入门(2024 最新版)

文章目录 1.1 Pandas 简介1.1.1 基础知识1.1.2 案例&#xff1a;气候变化数据分析1.1.3 拓展案例一&#xff1a;金融市场分析1.1.4 拓展案例二&#xff1a;社交媒体情感分析 1.2 安装和配置 Pandas1.2.1 基础知识1.2.2 案例&#xff1a;个人财务管理1.2.3 拓展案例一&#xff1…

力扣 55.跳跃游戏

思路&#xff1a; 从后往前遍历&#xff0c;遇到元素为0时&#xff0c;记录对应的下标位置&#xff0c;再向前遍历元素&#xff0c;看最大的跳跃步数能否跳过0的位置&#xff0c;不能则继续往前遍历 代码&#xff1a; class Solution { public:bool canJump(vector<int>…

ip https证书多少钱

IP https证书是一种数字证书&#xff0c;用于在网络传输中保护数据的机密性和完整性。它通过使用SSL&#xff08;安全套接层&#xff09;协议&#xff0c;在客户端和服务器之间建立一条加密通道&#xff0c;确保数据在传输过程中不会被窃取或篡改。而IP https证书的价格和它的品…

基于springboot的视频点播系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

5G智慧钢铁厂数字孪生三维可视化,推进钢铁新型工业化数字化转型

5G智慧钢铁厂数字孪生三维可视化&#xff0c;推进钢铁新型工业化数字化转型。随着科技的不断发展&#xff0c;数字化转型已经成为钢铁企业转型升级的必经之路。而5G技术的广泛应用&#xff0c;为钢铁企业数字化转型提供了新的机遇。其中&#xff0c;5G智慧钢铁厂数字孪生三维可…

SpringCloud_学习笔记_1

SpringCloud01 1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#xff…

Android Studio 安装配置教程 - Windows版

Android Studio下载 安装&#xff1a; 下载&#xff1a; Android Studio Hedgehog | 2023.1.1 | Android Developers (google.cn) 安装&#xff1a; 基本不需要思考跟着走 默认下一步 默认下一步 自定义修改路径&#xff0c;下一步 默认下一步&#xff0c;不勾选 默认下一…

GEE移除landsat collection 1数据集

简介 大家好&#xff0c;我是锐多宝&#xff0c;今天刷twitter时&#xff0c;看到了这样一篇文章&#xff1a; Google earth engine宣布从 2024 年7月1日开始&#xff0c;将完全移除 Landsat Collection 1数据集&#xff0c;并推荐大家将使用Collection 1的代码改为使用Colle…

centOS+nodejs+mysql阿里云部署前后端个人网站

centOSnodejsmysql阿里云部署前后端个人网站 参考&#xff1a; 部署NodeExpressMySQL项目到阿里云轻量应用服务器 阿里云轻量应用服务器部署Node.jsReactMongoDB前后端分离项目 参考&#xff1a;在阿里云上部署nodejs服务 https 部署的原理就是你在本地测试的时候在地址栏&am…

使用Mysql实现Postgresql中窗口函数row_number的功能

1. 描述 需要根据用户id&#xff0c;查询每个人得分第二高的科目信息 2. 表结构及数据 2.1 表结构 CREATE TABLE t_score (id bigint(20) NOT NULL AUTO_INCREMENT,user_id bigint(20) NOT NULL,score double NOT NULL,subject varchar(100) NOT NULL,PRIMARY KEY (id) ) E…

知识库建设这些工具来帮忙,企业工作效率翻倍

在当今深度信息化的年代&#xff0c;知识库成了企业不可或缺的一部分&#xff0c;它的建设与管理显得格外重要。然而&#xff0c;想要建设又好又高效的知识库并非易事。好消息是&#xff0c;有很多优秀的工具可以让这个过程变得更加轻松&#xff0c;今天我们就重点来探讨其中的…

Vulnhub靶场DC-2

本机IP&#xff1a;192.168.223.128 目标IP&#xff1a;192.168.223.131 目标搜索&#xff1a;nmap -sP 192.168.223.1/24 端口搜索&#xff1a;nmap -sV -A -p- 192.168.223.131 开放了80 7744端口 访问一下web 发现进不去 目标ip被重定向到www.dc-2.com 修改一下本地DNS l…

【极数系列】Flink集成DataSource读取Socket请求数据(09)

文章目录 01 引言02 简介概述03 基于socket套接字读取数据3.1 从套接字读取。元素可以由分隔符分隔。3.2 windows安装netcat工具&#xff08;1&#xff09;下载netcat工具&#xff08;2&#xff09;安装部署&#xff08;3&#xff09;启动socket端口监听 04 源码实战demo4.1 po…

[网络安全]IIS---FTP服务器 、serverU详解

一 . FTP服务器(File Transfor Protocol) : 协议:文件传输协议 端口号:TCP: 20(数据) / 21(控制) 二 . FTP工作方式: 1.主动模式 : (FTP服务器21端口与FTP客户端产生的随机端口先建立连接 建立连接后,再使用FTP服务器21端口与FTP客户端创建的一个新的随机端口进行发送…