【NeRF数据集】LLFF格式数据集处理colmap结果记录

news2024/9/22 14:42:08

【NeRF数据集】LLFF格式数据集处理colmap结果记录

      • 1. 基于colmap的配置与运行,获取图像及其对应的相机位姿;
      • 2. 使用 LLFF格式数据集制作,将匹配的位姿转化为LLFF格式;
      • 3. 上传所需文件和设置配置文件,将所需文件上传至NeRF对应文件夹并设置配置文件。

1. 基于colmap的配置与运行,获取图像及其对应的相机位姿;

colmap配置见链接 处理流程大概如下:

  1. 按照上述链接配置colmap运行环境,使用iphone获取场景内容数作为数据,
  2. 再创建一个文件路径 /data/output/sift/ 再在这个文件路径中创建 x.db
    在这里插入图片描述
mkdir  /data/output/sift/
touch  kf5_sift.db

在这里插入图片描述
4. 基于收集拍摄的视频,使用脚本处理获取照片,提取特征点 相机模型悬着 simple_pinhole
在这里插入图片描述
7c84d40adfc1f1889e3df40.png)

  1. feature matching ,然后重建选择FILE->Export all model 保存数据
    在这里插入图片描述
    好像结果还不错
    在这里插入图片描述

2. 使用 LLFF格式数据集制作,将匹配的位姿转化为LLFF格式;

为什么要使用llff格式数据?
而不是直接输入图像数据,当然也可以,只是存在2个问题,1是收敛速度变慢,2是重建效果变差。
LLFF格式数据可以将对应图片参数、相机位姿和相机参数简洁有效地存储在一个npy文件中,以方便python读取,且NeRF模型源码拥有直接对LLFF格式数据集进行训练的配置和模块,便于研究者使用。下面将详细展示其制作流程。而上面这些数据正是colmap的输出结果,见1中导出的结果。

得到COLMAP位姿匹配数据后,我们要对每张图片的位姿信息进行格式转换,转换为LLFF格式方便Nerf模型读取。

打开LLFF脚本,打开imgs2poses.py文件,修改如下内容,改为刚才的工作目录,然后在终端运行该代码
在这里插入图片描述

或者 File 导出 export model,新建名称为sparse保存的位置,sparse文件下的0文件作为输出结果,这里包含具体见上图

在这里插入图片描述

创建文件路径与名称如下:
在这里插入图片描述

python imgs2poses.py  /home/nolo/data/human/out/kf5_sift/

官网这个原始代码存在错误,报错信息如下

ERROR: the correct camera poses for current points cannot be accessed在这里插入图片描述
这里是匹配的位姿和图片数目不同

通常来讲,如果用于匹配的图片拍摄的比较好,是不会出现匹配不上位姿的情况,但是如果出现了,就需要手动剔除匹配不到位姿的图片,可以通过在 LLFF/llff/poses/pose_utils.py 文件的32行左右添加如下代码:
也可以在原始的代码上做如下修改:

修复后 pose_utils.py 如下:

import numpy as np
import os
import sys
import imageio
import skimage.transform

from llff.poses.colmap_wrapper import run_colmap
import llff.poses.colmap_read_model as read_model

def save_views(realdir,names):
    with open(os.path.join(realdir,'view_imgs.txt'), mode='w') as f:
        f.writelines('\n'.join(names))
    f.close()


def load_save_pose(realdir):

    # load colmap data
    camerasfile = os.path.join(realdir, 'sparse/0/cameras.bin')
    camdata = read_model.read_cameras_binary(camerasfile)

    list_of_keys = list(camdata.keys())
    cam = camdata[list_of_keys[0]]
    print( 'Cameras', cam)

    h, w, f = cam.height, cam.width, cam.params[0]
    hwf = np.array([h,w,f]).reshape([3,1])

    imagesfile = os.path.join(realdir, 'sparse/0/images.bin')
    imdata = read_model.read_images_binary(imagesfile)

    real_ids = [k for k in imdata]

    w2c_mats = []
    bottom = np.array([0,0,0,1.]).reshape([1,4])

    names = [imdata[k].name for k in imdata]
    print( 'Images #', len(names))

    # if (len(names)< 32):
    #     raise ValueError(f'{realdir} only {len(names)} images register, need Re-run colmap or reset the threshold')


    perm = np.argsort(names)
    sort_names = [names[i] for i in perm]
    save_views(realdir,sort_names)

    for k in imdata:
        im = imdata[k]
        R = im.qvec2rotmat()
        t = im.tvec.reshape([3,1])
        m = np.concatenate([np.concatenate([R, t], 1), bottom], 0)
        w2c_mats.append(m)

    w2c_mats = np.stack(w2c_mats, 0)
    c2w_mats = np.linalg.inv(w2c_mats)

    poses = c2w_mats[:, :3, :4].transpose([1,2,0])
    poses = np.concatenate([poses, np.tile(hwf[..., np.newaxis], [1,1,poses.shape[-1]])], 1)

    points3dfile = os.path.join(realdir, 'sparse/0/points3D.bin')
    pts3d = read_model.read_points3d_binary(points3dfile)

    # must switch to [-u, r, -t] from [r, -u, t], NOT [r, u, -t]
    poses = np.concatenate([poses[:, 1:2, :], poses[:, 0:1, :], -poses[:, 2:3, :], poses[:, 3:4, :], poses[:, 4:5, :]], 1)

    # save pose
    pts_arr = []
    vis_arr = []
    for k in pts3d:
        pts_arr.append(pts3d[k].xyz)
        cams = [0] * poses.shape[-1]
        for ind in pts3d[k].image_ids:
            if len(cams) < real_ids.index(ind):
                print('ERROR: the correct camera poses for current points cannot be accessed')
                return
            cams[real_ids.index(ind)] = 1
        vis_arr.append(cams)

    pts_arr = np.array(pts_arr)
    vis_arr = np.array(vis_arr)
    print( 'Points', pts_arr.shape, 'Visibility', vis_arr.shape)
    zvals = np.sum(-(pts_arr[:, np.newaxis, :].transpose([2,0,1]) - poses[:3, 3:4, :]) * poses[:3, 2:3, :], 0)
    valid_z = zvals[vis_arr==1]
    print( 'Depth stats', valid_z.min(), valid_z.max(), valid_z.mean() )

    save_arr = []
    for i in perm:
        vis = vis_arr[:, i]
        zs = zvals[:, i]
        zs = zs[vis==1]
        close_depth, inf_depth = np.percentile(zs, .1), np.percentile(zs, 99.9)

        save_arr.append(np.concatenate([poses[..., i].ravel(), np.array([close_depth, inf_depth])], 0))
    save_arr = np.array(save_arr)

    np.save(os.path.join(realdir, 'poses_bounds.npy'), save_arr)


def load_colmap_data(realdir):
    
    camerasfile = os.path.join(realdir, 'sparse/0/cameras.bin')
    print("camerasfile_path:", camerasfile)
    camdata = read_model.read_cameras_binary(camerasfile)

    # print("camdate: ", camdata)
    # cam = camdata[camdata.keys()[0]]
    list_of_keys = list(camdata.keys())
    cam = camdata[list_of_keys[0]]
    print( 'Cameras', len(cam))

    h, w, f = cam.height, cam.width, cam.params[0]
    # w, h, f = factor * w, factor * h, factor * f
    hwf = np.array([h,w,f]).reshape([3,1])

    # print(hwf)
    
    imagesfile = os.path.join(realdir, 'sparse/0/images.bin')
    print("imagesfile_path:", imagesfile)
    imdata = read_model.read_images_binary(imagesfile)

    # print(imdata)
    
    w2c_mats = []
    bottom = np.array([0,0,0,1.]).reshape([1,4])
    
    names = [imdata[k].name for k in imdata]
    print( 'Images #', len(names))
    perm = np.argsort(names)
    for k in imdata:
        im = imdata[k]
        R = im.qvec2rotmat()
        t = im.tvec.reshape([3,1])
        m = np.concatenate([np.concatenate([R, t], 1), bottom], 0)
        w2c_mats.append(m)
    
    w2c_mats = np.stack(w2c_mats, 0)
    c2w_mats = np.linalg.inv(w2c_mats)
    
    poses = c2w_mats[:, :3, :4].transpose([1,2,0])
    poses = np.concatenate([poses, np.tile(hwf[..., np.newaxis], [1,1,poses.shape[-1]])], 1)
    
    points3dfile = os.path.join(realdir, 'sparse/0/points3D.bin')
    pts3d = read_model.read_points3d_binary(points3dfile)
    
    # must switch to [-u, r, -t] from [r, -u, t], NOT [r, u, -t]
    poses = np.concatenate([poses[:, 1:2, :], poses[:, 0:1, :], -poses[:, 2:3, :], poses[:, 3:4, :], poses[:, 4:5, :]], 1)

    # print("poses", poses)
    # print("pts3d shape: ", pts3d.shape())
    # print("perm: ",perm)
    return poses, pts3d, perm


def save_poses(basedir, poses, pts3d, perm):
    pts_arr = []
    vis_arr = []
    for k in pts3d:
        pts_arr.append(pts3d[k].xyz)
        cams = [0] * poses.shape[-1]
        for ind in pts3d[k].image_ids:
            # print("cams_len: ",len(cams))
            # print("ind: ",ind)
            if len(cams) < ind - 1:
                print('ERROR: the correct camera poses for current points cannot be accessed')
                return
            cams[ind-1] = 1
        vis_arr.append(cams)

    pts_arr = np.array(pts_arr)
    vis_arr = np.array(vis_arr)
    print( 'Points', pts_arr.shape, 'Visibility', vis_arr.shape )
    
    zvals = np.sum(-(pts_arr[:, np.newaxis, :].transpose([2,0,1]) - poses[:3, 3:4, :]) * poses[:3, 2:3, :], 0)
    valid_z = zvals[vis_arr==1]
    print( 'Depth stats', valid_z.min(), valid_z.max(), valid_z.mean() )
    
    save_arr = []
    for i in perm:
        vis = vis_arr[:, i]
        zs = zvals[:, i]
        zs = zs[vis==1]
        close_depth, inf_depth = np.percentile(zs, .1), np.percentile(zs, 99.9)
        # print( i, close_depth, inf_depth )
        
        save_arr.append(np.concatenate([poses[..., i].ravel(), np.array([close_depth, inf_depth])], 0))
    save_arr = np.array(save_arr)

    print("save_arr: ", save_arr)
    np.save(os.path.join(basedir, 'poses_bounds.npy'), save_arr)
            



def minify_v0(basedir, factors=[], resolutions=[]):
    needtoload = False
    for r in factors:
        imgdir = os.path.join(basedir, 'images_{}'.format(r))
        if not os.path.exists(imgdir):
            needtoload = True
    for r in resolutions:
        imgdir = os.path.join(basedir, 'images_{}x{}'.format(r[1], r[0]))
        if not os.path.exists(imgdir):
            needtoload = True
    if not needtoload:
        return
    
    def downsample(imgs, f):
        sh = list(imgs.shape)
        sh = sh[:-3] + [sh[-3]//f, f, sh[-2]//f, f, sh[-1]]
        imgs = np.reshape(imgs, sh)
        imgs = np.mean(imgs, (-2, -4))
        return imgs
    
    imgdir = os.path.join(basedir, 'images')
    imgs = [os.path.join(imgdir, f) for f in sorted(os.listdir(imgdir))]
    imgs = [f for f in imgs if any([f.endswith(ex) for ex in ['JPG', 'jpg', 'png', 'jpeg', 'PNG']])]
    imgs = np.stack([imageio.imread(img)/255. for img in imgs], 0)
    
    for r in factors + resolutions:
        if isinstance(r, int):
            name = 'images_{}'.format(r)
        else:
            name = 'images_{}x{}'.format(r[1], r[0])
        imgdir = os.path.join(basedir, name)
        if os.path.exists(imgdir):
            continue
        print('Minifying', r, basedir)
        
        if isinstance(r, int):
            imgs_down = downsample(imgs, r)
        else:
            imgs_down = skimage.transform.resize(imgs, [imgs.shape[0], r[0], r[1], imgs.shape[-1]],
                                                order=1, mode='constant', cval=0, clip=True, preserve_range=False, 
                                                 anti_aliasing=True, anti_aliasing_sigma=None)
        
        os.makedirs(imgdir)
        for i in range(imgs_down.shape[0]):
            imageio.imwrite(os.path.join(imgdir, 'image{:03d}.png'.format(i)), (255*imgs_down[i]).astype(np.uint8))
            



def minify(basedir, factors=[], resolutions=[]):
    needtoload = False
    for r in factors:
        imgdir = os.path.join(basedir, 'images_{}'.format(r))
        if not os.path.exists(imgdir):
            needtoload = True
    for r in resolutions:
        imgdir = os.path.join(basedir, 'images_{}x{}'.format(r[1], r[0]))
        if not os.path.exists(imgdir):
            needtoload = True
    if not needtoload:
        return
    
    from shutil import copy
    from subprocess import check_output
    
    imgdir = os.path.join(basedir, 'images')
    imgs = [os.path.join(imgdir, f) for f in sorted(os.listdir(imgdir))]
    imgs = [f for f in imgs if any([f.endswith(ex) for ex in ['JPG', 'jpg', 'png', 'jpeg', 'PNG']])]
    imgdir_orig = imgdir
    
    wd = os.getcwd()

    for r in factors + resolutions:
        if isinstance(r, int):
            name = 'images_{}'.format(r)
            resizearg = '{}%'.format(int(100./r))
        else:
            name = 'images_{}x{}'.format(r[1], r[0])
            resizearg = '{}x{}'.format(r[1], r[0])
        imgdir = os.path.join(basedir, name)
        if os.path.exists(imgdir):
            continue
            
        print('Minifying', r, basedir)
        
        os.makedirs(imgdir)
        check_output('cp {}/* {}'.format(imgdir_orig, imgdir), shell=True)
        
        ext = imgs[0].split('.')[-1]
        args = ' '.join(['mogrify', '-resize', resizearg, '-format', 'png', '*.{}'.format(ext)])
        print(args)
        os.chdir(imgdir)
        check_output(args, shell=True)
        os.chdir(wd)
        
        if ext != 'png':
            check_output('rm {}/*.{}'.format(imgdir, ext), shell=True)
            print('Removed duplicates')
        print('Done')
            
        
        
        
def load_data(basedir, factor=None, width=None, height=None, load_imgs=True):
    
    poses_arr = np.load(os.path.join(basedir, 'poses_bounds.npy'))
    poses = poses_arr[:, :-2].reshape([-1, 3, 5]).transpose([1,2,0])
    bds = poses_arr[:, -2:].transpose([1,0])
    
    img0 = [os.path.join(basedir, 'images', f) for f in sorted(os.listdir(os.path.join(basedir, 'images'))) \
            if f.endswith('JPG') or f.endswith('jpg') or f.endswith('png')][0]
    sh = imageio.imread(img0).shape
    
    sfx = ''
    
    if factor is not None:
        sfx = '_{}'.format(factor)
        minify(basedir, factors=[factor])
        factor = factor
    elif height is not None:
        factor = sh[0] / float(height)
        width = int(sh[1] / factor)
        minify(basedir, resolutions=[[height, width]])
        sfx = '_{}x{}'.format(width, height)
    elif width is not None:
        factor = sh[1] / float(width)
        height = int(sh[0] / factor)
        minify(basedir, resolutions=[[height, width]])
        sfx = '_{}x{}'.format(width, height)
    else:
        factor = 1
    
    imgdir = os.path.join(basedir, 'images' + sfx)
    if not os.path.exists(imgdir):
        print( imgdir, 'does not exist, returning' )
        return
    
    imgfiles = [os.path.join(imgdir, f) for f in sorted(os.listdir(imgdir)) if f.endswith('JPG') or f.endswith('jpg') or f.endswith('png')]
    if poses.shape[-1] != len(imgfiles):
        print( 'Mismatch between imgs {} and poses {} !!!!'.format(len(imgfiles), poses.shape[-1]) )
        return
    
    sh = imageio.imread(imgfiles[0]).shape
    poses[:2, 4, :] = np.array(sh[:2]).reshape([2, 1])
    poses[2, 4, :] = poses[2, 4, :] * 1./factor
    
    if not load_imgs:
        return poses, bds
    
    # imgs = [imageio.imread(f, ignoregamma=True)[...,:3]/255. for f in imgfiles]
    def imread(f):
        if f.endswith('png'):
            return imageio.imread(f, ignoregamma=True)
        else:
            return imageio.imread(f)
        
    imgs = imgs = [imread(f)[...,:3]/255. for f in imgfiles]
    imgs = np.stack(imgs, -1)  
    
    print('Loaded image data', imgs.shape, poses[:,-1,0])
    return poses, bds, imgs

    
            
            
    
def gen_poses(basedir, match_type, factors=None):
    
    files_needed = ['{}.bin'.format(f) for f in ['cameras', 'images', 'points3D']]
    if os.path.exists(os.path.join(basedir, 'sparse/0')):
        files_had = os.listdir(os.path.join(basedir, 'sparse/0'))
    else:
        files_had = []
    if not all([f in files_had for f in files_needed]):
        print( 'Need to run COLMAP' )
        run_colmap(basedir, match_type)
    else:
        print('Don\'t need to run COLMAP')
        
    print( 'Post-colmap')

    print("basedir: {}".format(basedir))

    load_save_pose(basedir)

    # poses, pts3d, perm = load_colmap_data(basedir)

    # print('load_colmap_data success: ',poses.shape," ",pts3d.__len__()," ",perm.shape)
    # save_poses(basedir, poses, pts3d, perm)
    
    if factors is not None:
        print( 'Factors:', factors)
        minify(basedir, factors)
    
    print( 'Done with imgs2poses' )
    
    return True
    

imgs2poses.py

from llff.poses.pose_utils import gen_poses
import sys

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--match_type', type=str, 
					default='exhaustive_matcher', help='type of matcher used.  Valid options: \
					exhaustive_matcher sequential_matcher.  Other matchers not supported at this time')
parser.add_argument('scenedir', type=str,
                    default='/home/nolo/data/doll/test/',
                    help='input scene directory')
args = parser.parse_args()

if args.match_type != 'exhaustive_matcher' and args.match_type != 'sequential_matcher':
	print('ERROR: matcher type ' + args.match_type + ' is not valid.  Aborting')
	sys.exit()

if __name__=='__main__':
    gen_poses(args.scenedir, args.match_type)

运行完成后,得到如下提示(注意红框内是之前匹配上的图片名称,这个下面会用到):
在这里插入图片描述
此时,工作目录下产生poses_bounds.npy文件 生成文件如下:

在这里插入图片描述

3. 上传所需文件和设置配置文件,将所需文件上传至NeRF对应文件夹并设置配置文件。

最后,需要将相关文件上传至NeRF代码的相应文件夹中。
再工程 nerf-pytorch 工程的config中添加 doll.txt 配置文件

expname = doll_test
basedir = ./logs
datadir = ./data/nerf_llff_data/doll
dataset_type = llff

factor = 8
llffhold = 8

N_rand = 1024
N_samples = 64
N_importance = 64

use_viewdirs = True
raw_noise_std = 1e0

完成数据制作!!!

配置nerf-pytorch 工程 ,开始训练!!!!

/ws/nerf-pytorch$ 
python run_nerf.py --config configs/doll.txt

训练结果如下:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

numpy数组05-numpy的索引和切片

numpy中可以对其中的某一行&#xff08;列&#xff09;进行数据处理。 上节课我们已经取出了CSV文件中的二维数组&#xff0c;本次对这个二维数组为例&#xff0c;进行练习操作。 示例代码如下&#xff1a; import numpy as npus_file_path "US_video_data_numbers.cs…

5大自动化测试的Python框架,看完就能涨薪5k 【实用干货】

目前&#xff0c;它在Tiobe指数中排名第三个&#xff0c;仅次于Java和C。随着该编程语言的广泛使用&#xff0c;基于Python的自动化测试框架也应运而生&#xff0c;且不断发展与丰富。 因此&#xff0c;开发与测试人员在为手头的项目选择测试框架时&#xff0c;需要考虑许多方…

FX3U-1PG使用

作为扩展模块的安装 伺服驱动器的参数设置 1.设置为0&#xff0c;为位置模式&#xff0c;发送脉冲控制&#xff1b; 2. 设置旋转方向&#xff0c;以及脉冲方式&#xff0c;通常设置为01&#xff0c;因为FX3U-1PG只支持正方向脉冲负方向脉冲方式&#xff1b; 当然想改变电机运…

显化的跨渠道整合:迅腾文化助力企业拓展销售渠道

显化的跨渠道整合&#xff1a;迅腾文化助力企业拓展销售渠道 在数字化浪潮的推动下&#xff0c;企业的销售渠道日趋多元化。面对复杂多变的市场环境&#xff0c;企业需要一种有效的方式来整合各个销售渠道&#xff0c;以实现更高效的销售拓展。广州迅腾文化传播有限公司的显化…

MySQL中的六种日志你都懂么?不懂!那就必须看看

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

Linux 进程(七) 进程地址空间

虚拟地址/线性地址 学习c语言的时候我们经常会用到 “&” 符号&#xff0c;以及下面这张表&#xff0c;那么取出来的地址是否对应的是真实的物理地址呢&#xff1f;下面我们来写代码一步一步的验证。 从上面这张图不难看出&#xff0c;从正文代码&#xff0c;到命令行参数环…

当你明白了这句话,你就开始赚到钱了

哈喽&#xff0c;大家好啊&#xff0c;我是雷工&#xff01; 曾经看到稻盛和夫说过这么一句话&#xff1a; 其实钱并不是赚来的&#xff0c;而是你帮助别人解决问题后给你的回报。 这天发生了件小事&#xff0c;让我对这句话有了更深的认识。 一、 缘起 自从开始记笔记&…

洗地机有没有必要买?家用洗地机推荐

随着生活水平的提高&#xff0c;人们对家居环境的卫生和清洁要求也相应提高&#xff0c;因此家用洗地机作为一种现代化的清洁工具逐渐受到了广泛关注和青睐。那么&#xff0c;洗地机到底有没有必要买? 洗地机对于一些家庭确实是非常有必要的&#xff0c;特别是对于工作繁忙、…

springboot整合webservice使用总结

因为做的项目中用到了webservice,所以在此总结一下。 一、webservice简介 Web Service也叫XML Web Service, WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求&#xff0c;轻量级的独立的通讯技术。是通过SOAP在Web上提供的软件服务&#xff0c;使…

YOLOv7独家原创改进:提出一种新的Shape IoU,更加关注边界框本身的形状和尺度,对小目标检测也很友好 | 2023.12.29收录

💡💡💡本文改进:一种新的Shape IoU方法,该方法可以通过关注边界框本身的形状和尺度来计算损失,解决边界盒的形状和规模等固有属性对边界盒回归的影响。 💡💡💡对小目标检测涨点明显,在VisDrone2019、PASCAL VOC均有涨点 收录YOLOv7原创自研 https://blog.csdn…

【损失函数】Quantile Loss 分位数损失

1、介绍 Quantile Loss&#xff08;分位数损失&#xff09;是用于回归问题的一种损失函数&#xff0c;它允许我们对不同分位数的预测误差赋予不同的权重。这对于处理不同置信水平的预测非常有用&#xff0c;例如在风险管理等领域。 当我们需要对区间预测而不单是点预测时 分位…

由于找不到kernel32.dll无法继续执行此代码的解决方法

使用Windows 7操作系统&#xff0c;我一直被一个名为“kernel32.dll”的问题所困扰。kernel32.dll是Windows操作系统中非常重要的一个动态链接库文件&#xff0c;它包含了许多基本的系统函数&#xff0c;如内存管理、文件操作等。因此&#xff0c;当这个文件丢失或损坏时&#…

GPT科研助手!论文助手!编程助手!AIGC/机器学习/深度学习/卷积神经网络/地球科学/AI绘图等模块

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

【双指针算法】-- 左右指针

左右指针 前言一、双指针算法二、左右指针1.用于在已排序数组中找到两个数使其和为特定值2.在字符串中判断是否为回文 总结 前言 今天在刷Leetcode的时候觉得自己双指针掌握的还是不错的记录一下,写个学习笔记,也方便以后翻阅,如果也帮助到你了,那真是太好啦! 本篇介绍的是左右…

[DevOps-05] Jenkins实现CI/CD操作

一、简要说明 基于Jenkins拉取GitLab的SpringBoot代码进行构建发布到测试环境实现持续集成 基于Jenkins拉取GitLab指定发行版本的SpringBoot代码进行构建发布到生产环境实现CD实现持续部署 二、准备Springboot工程 1、IDEA新建工程 2、填写项目工程信息 3、选择Springboot版本…

Dubbo开发系列

一、概述 以上是 Dubbo 的工作原理图&#xff0c;从抽象架构上分为两层&#xff1a;服务治理抽象控制面 和 Dubbo 数据面 。 服务治理控制面。服务治理控制面不是特指如注册中心类的单个具体组件&#xff0c;而是对 Dubbo 治理体系的抽象表达。控制面包含协调服务发现的注册中…

模型训练不再数据顾虑,微软研究团队使用【合成数据】来训练模型

微软研究团队最新成果&#xff1a;他们已经开始使用【合成数据】来训练AI模型了。微软使用大语言模型生成了近100种语言、数十万个文本嵌入任务的“模拟”文本数据&#xff0c;然后用这些数据来训练 AI 。这大幅度降低了训练成本&#xff0c;提高了效率&#xff0c;同时还减少了…

VirtualBox + Redhat7.6 +Oracle19C 数据库安装

软件工具&#xff1a; 虚拟化工具&#xff1a;VirtualBox-6.1.26-145957-Win.exe操作系统镜像&#xff1a;rhel-server-7.6-x86_64-dvd.iso远程连接工具&#xff1a;XmanagerPowerSuite-7.0.0004r.exe、SecureCRT 8.5.3数据库版本镜像&#xff1a;LINUX.X64_193000_grid_home.…

《深入理解C++11:C++11新特性解析与应用》笔记六

第六章 提高性能及操作硬件的能力 6.1 常量表达式 6.1.1 运行时常量性与编译时常量性 大多数情况下&#xff0c;const描述的是运行时常量性&#xff0c;也即是运行时数据的不可更改性。但有时候我们需要的却是编译时的常量性&#xff0c;这是const关键字无法保证的。例如&am…

【JavaSE】string与StringBuilder和StringBuffer

区别&#xff1a; 不可变性&#xff1a; String&#xff1a; String 类是不可变的&#xff0c;一旦创建就不能被修改。对字符串的任何操作都会创建一个新的字符串对象。StringBuffer&#xff1a; StringBuffer 是可变的&#xff0c;允许对字符串进行修改&#xff0c;而不创建新…