python计算机视觉编程——照相机模型与增强现实

news2024/11/13 10:45:20

一、针孔照相机模型

针孔照相机模型(有时称为射影照相机模型)是计算机视觉中广泛使用的照相机模型。针孔照相机模型简单,并且具有足够的精确度。这个名字来源于一种类似暗箱机的照相机。该照相机从一个小孔采集射到暗箱内部的光线。在针孔照相机模型中,在光线投影到图像平面之前,从唯一一个点经过,也就是照相机中心C。

1照相机矩阵 

照相机矩阵可以分解为: 

P=K[R|t]

标定矩阵仅和照相机自身的情况相关,在大多数情况下,倾斜参数s可以设置成0,默认设置 α=1.经过这些假设,标定矩阵变为:

2三维点的投影 

创建照相机类,处理对照相机和投影建模所需要的全部操作主要代码:

from numpy import *
from scipy import linalg


class Camera(object):
    """ Class for representing pin-hole cameras. """
    
    def __init__(self,P):
        """ Initialize P = K[R|t] camera model. """
        self.P = P
        self.K = None # calibration matrix
        self.R = None # rotation
        self.t = None # translation
        self.c = None # camera center
        
    
    def project(self,X):
        """    Project points in X (4*n array) and normalize coordinates. """
        
        x = dot(self.P,X)
        for i in range(3):
            x[i] /= x[2]    
        return x
        
        
    def factor(self):
        """    Factorize the camera matrix into K,R,t as P = K[R|t]. """
        
        # factor first 3*3 part
        K,R = linalg.rq(self.P[:,:3])
        
        # make diagonal of K positive
        T = diag(sign(diag(K)))
        if linalg.det(T) < 0:
            T[1,1] *= -1
        
        self.K = dot(K,T)
        self.R = dot(T,R) # T is its own inverse
        self.t = dot(linalg.inv(self.K),self.P[:,3])
        
        return self.K, self.R, self.t
        
    
    def center(self):
        """    Compute and return the camera center. """
    
        if self.c is not None:
            return self.c
        else:
            # compute c by factoring
            self.factor()
            self.c = -dot(self.R.T,self.t)
            return self.c



# helper functions    

def rotation_matrix(a):
    """    Creates a 3D rotation matrix for rotation
        around the axis of the vector a. """
    R = eye(4)
    R[:3,:3] = linalg.expm([[0,-a[2],a[1]],[a[2],0,-a[0]],[-a[1],a[0],0]])
    return R
    

def rq(A):
    from scipy.linalg import qr
    
    Q,R = qr(flipud(A).T)
    R = flipud(R.T)
    Q = Q.T
    
    return R[:,::-1],Q[::-1,:]

运行结果: 

 

3照相机矩阵的分解

对照相机矩阵P,需要恢复内参数K以及照相机的位置t和姿势R。矩阵分块操作称为因子分解,这里使用的矩阵因子分解方法为RQ因子分解。因为RQ因子分解的结果不唯一,分解的结果存在符号二义性,所以需要限制矩阵R为正定的,可以在求解到的结果中加入变换T来改变符号。

运行代码:

import camera
from numpy import *
from scipy import linalg

K = array([[1000,0,500],[0,1000,300],[0,0,1]])
tmp = camera.rotation_matrix([0,0,1])[:3,:3]
Rt = hstack((tmp,array([[50],[40],[30]])))
cam = camera.Camera(dot(K,Rt))

print(K,Rt)
print(cam.factor())

运行结果:

4 计算照相机中心 

 

给定照相机投影矩阵P,可以计算出空间上照相机的所在位置。照相机的中心C满足PC=0,

\boldsymbol{K}[\boldsymbol{R} \mid \boldsymbol{t}] \mathbf{C}=\boldsymbol{K} \boldsymbol{R C}+\boldsymbol{K} \boldsymbol{t}=0

于是,

C=-R^Tt

代码已经写入camera类,函数为: def center(self)

二、照相机标定

一个简单的标定方法:

需要准备一个平面矩形的标定物体(一个书本即可)、用于测量的卷尺和直尺,以及一个平面。

下面是具体操作步骤:

  1. 测量你选定矩形标定物体的边长X和dY;
  2. 将照相机和标定物体放置在平面上,使得照相机的背面和标定物体平行,同时物体位于照相机图像视图的中心,你可能需要调整照相机或者物体来获得良好的对齐效果;
  3. 测量标定物体到照相机的距离dZ;
  4. 拍摄一副图像来检验该设置是否正确,即标定物体的边要和图像的行和列对齐;
  5. 使用像素数来测量标定物体图像的宽度和高度dx和dy。

使用相似三角形可获得焦距:

f_{x}=\frac{\mathrm{d} x}{\mathrm{~d} X} \mathrm{~d} Z, \quad f_{y}=\frac{\mathrm{d} y}{\mathrm{~d} Y} \mathrm{~d} Z
 

 代码如下:

def my_calibration(sz):
    row, col = sz
    fx = 2555 * col / 2592
    fy = 2586 * row / 1936
    K = diag([fx, fy, 1])
    K[0, 2] = 0.5 * col
    K[1, 2] = 0.5 * row
    return K

三、以平面和标记物进行姿态估计 

如果图像中包含平面状的标记物体,并且以对照相机进行了标定,那么我们可以计算出照相机的姿态(旋转和平移)。这里的标记物可以为对任何平坦的物体。

姿态估计的方法:

1、先提取两幅图像的SIFT特征,然后使用RANSAC算法稳健地估计单应性矩阵

# compute features
sift.process_image('a3.jpg', 'a3.sift')
l0, d0 = sift.read_features_from_file('a3.sift')

sift.process_image('a4.jpg', 'a4.sift')
l1, d1 = sift.read_features_from_file('a4.sift')

# match features and estimate homography
matches = sift.match_twosided(d0, d1)
ndx = matches.nonzero()[0]
fp = homography.make_homog(l0[ndx, :2].T)
ndx2 = [int(matches[i]) for i in ndx]
tp = homography.make_homog(l1[ndx2, :2].T)

model = homography.RansacModel()
H, inliers = homography.H_from_ransac(fp, tp, model)

2、定义相应的三维坐标系,使标记物在X−Y平面上(Z=0),原点在标记物的某位置上 

 为了检验单应性矩阵结果的正确性,我们需要将一些简单的三维物体放置在标记物上,这里我们使用一个立方体。可以使用下面的函数来产生立方体上的点:

def cube_points(c, wid):
    """ Creates a list of points for plotting
        a cube with plot. (the first 5 points are
        the bottom square, some sides repeated). """
    p = []
    # bottom
    p.append([c[0] - wid, c[1] - wid, c[2] - wid])
    p.append([c[0] - wid, c[1] + wid, c[2] - wid])
    p.append([c[0] + wid, c[1] + wid, c[2] - wid])
    p.append([c[0] + wid, c[1] - wid, c[2] - wid])
    p.append([c[0] - wid, c[1] - wid, c[2] - wid])  # same as first to close plot

    # top
    p.append([c[0] - wid, c[1] - wid, c[2] + wid])
    p.append([c[0] - wid, c[1] + wid, c[2] + wid])
    p.append([c[0] + wid, c[1] + wid, c[2] + wid])
    p.append([c[0] + wid, c[1] - wid, c[2] + wid])
    p.append([c[0] - wid, c[1] - wid, c[2] + wid])  # same as first to close plot

    # vertical sides
    p.append([c[0] - wid, c[1] - wid, c[2] + wid])
    p.append([c[0] - wid, c[1] + wid, c[2] + wid])
    p.append([c[0] - wid, c[1] + wid, c[2] - wid])
    p.append([c[0] + wid, c[1] + wid, c[2] - wid])
    p.append([c[0] + wid, c[1] + wid, c[2] + wid])
    p.append([c[0] + wid, c[1] - wid, c[2] + wid])
    p.append([c[0] + wid, c[1] - wid, c[2] - wid])

    return array(p).T

3、有了单应性矩阵和照相机的标定矩阵,现在可以得出两个视图间的相对变换 

# 计算照相机标定矩阵
K = my_calibration((300, 400))

# 位于边长为0.2 z=0平面的三维点
box = cube_points([0, 0, 0.1], 0.1)

# 投影第一幅图像上底部的正方形
cam1 = camera.Camera(hstack((K, dot(K, array([[0], [0], [-1]])))))
# 底部正方形上的点
box_cam1 = cam1.project(homography.make_homog(box[:, :5]))


# 使用H将点变换到第二幅图像中
box_trans = homography.normalize(dot(H,box_cam1))

# 从cam1和H中计算第二个照相机矩阵
cam2 = camera.Camera(dot(H, cam1.P))
A = dot(linalg.inv(K), cam2.P[:, :3])
A = array([A[:, 0], A[:, 1], cross(A[:, 0], A[:, 1])]).T
cam2.P[:, :3] = dot(K, A)

# 使用第二个照相机矩阵投影
box_cam2 = cam2.project(homography.make_homog(box))

# 测试:将点投影在 z=0 上,应该能够得到相同的点
point = array([1,1,0,1]).T
print(homography.normalize(dot(dot(H,cam1.P),point)))
print(cam2.project(point))

4、可视化投影后的点

# plotting
im0 = array(Image.open('a3.jpg'))
im1 = array(Image.open('a4.jpg'))

figure()
imshow(im0)
plot(box_cam1[0, :], box_cam1[1, :], linewidth=3)
title('2D projection of bottom square')
axis('off')

figure()
imshow(im1)
plot(box_trans[0, :], box_trans[1, :], linewidth=3)
title('2D projection transfered with H')
axis('off')

figure()
imshow(im1)
plot(box_cam2[0, :], box_cam2[1, :], linewidth=3)
title('3D points projected in second image')
axis('off')

show()

四、增强现实(AR)

 增强现实 (Augmented Reality,AR)是将物体和相应信息放置在图像数据上的一系列操作的总称。我们会用到两个工具包:PyGame和PyOpenGL。

1PyGame和PyOpenGL

OpenGL 中这里主要使用两个部分:GL 部分包含所有以“gl”开头的函数,其中包含我们需要的大部分函数;GLU 部分是 OpenGL的实用函数库,里面包含了一些高层的函数。我们主要使用它来设置照相机投影。
pygame 部分用来设置窗口和事件控制;其中pygame.image 用来载入图像和创建 OpenGL 的纹理,pygame.locals 用来设置 OpenGL 的显示区域。

2从照相机矩阵到OpenGL格式 

1、假设我们已经获得了标定好的照相机,即已知标定矩阵 K,下面的函数可以将照相机参数转换为 OpenGL 中的投影矩阵

def set_projection_from_camera(K):
    """从照相机标定矩阵中获得视图"""
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    fx = K[0, 0]
    fy = K[1, 1]
    fovy = 2 * math.atan(0.5 * height / fy) * 180 / math.pi
    aspect = (width * fy) / (height * fx)
    near = 0.1  #定义近的和远的裁剪平面
    far = 100.0
    gluPerspective(fovy, aspect, near, far)  #设定透视
    glViewport(0, 0, width, height)

2、获得移除标定矩阵后的 3×4 针孔照相机矩阵(将 P 和 K-1 相乘),并创建一个模拟视图

def set_modelview_from_camera(Rt):
    """从照相机姿态中获得模拟视图矩阵"""
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    Rx = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])  #围绕x轴将茶壶旋转90度,使z轴向上
    R = Rt[:, :3]  #获得旋转的最佳逼近
    U, S, V = np.linalg.svd(R)
    R = np.dot(U, V)
    R[0, :] = -R[0, :]  #改变x轴的符号
    t = Rt[:, 3]  #获得平移量
    M = np.eye(4) #获得4*4的模拟视图矩阵
    M[:3, :3] = np.dot(R, Rx)
    M[:3, 3] = t
    M = M.T  #转置并压平以获得列序数值
    m = M.flatten()
    glLoadMatrixf(m)  #将模拟视图矩阵替换为新的矩阵

3、载入一幅图像,然后将其转换成一个 OpenGL 纹理,并将该纹理放置在四边形上

def draw_background(imname):
    """使用四边形绘制背景图像"""
    
    #载入背景图像,转为OpenGL纹理
    bg_image = pygame.image.load(imname).convert()
    bg_data = pygame.image.tostring(bg_image, "RGBX", 1)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    #绑定纹理
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, glGenTextures(1))
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bg_data)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    #创建四方形填充整个窗口
    glBegin(GL_QUADS)
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, -1.0, -1.0)
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, -1.0, -1.0)
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, 1.0, -1.0)
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, 1.0, -1.0)
    glEnd()
    #清除纹理
    glDeleteTextures(1)

4、将物体放置入场景中

def draw_teapot(size):  # 红色茶壶
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glEnable(GL_DEPTH_TEST)
    glClear(GL_DEPTH_BUFFER_BIT)
    # 绘制红色茶壶
    glMaterialfv(GL_FRONT, GL_AMBIENT, [0, 0, 0, 0])
    glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.5, 0.0, 0.0, 0.0])
    glMaterialfv(GL_FRONT, GL_SPECULAR, [0.7, 0.6, 0.6, 0.0])
    glMaterialf(GL_FRONT, GL_SHININESS, 0.25 * 128.0)
    glutSolidTeapot(size)


def drawFunc(size):  # 白色茶壶
    glRotatef(0.5, 5, 5, 0)  # (角度,x,y,z)
    glutWireTeapot(size)
    # 刷新显示
    glFlush()

 综合代码:

# -*- coding: utf-8 -*-
import math
import pickle
import sys
from pylab import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import pygame, pygame.image
from pygame.locals import *
import homography, camera
import sift


def cube_points(c, wid):  # 绘制立方体的一各点列表
    """ Creates a list of points for plotting
        a cube with plot. (the first 5 points are
        the bottom square, some sides repeated). """
    p = []
    # 底部
    p.append([c[0] - wid, c[1] - wid, c[2] - wid])
    p.append([c[0] - wid, c[1] + wid, c[2] - wid])
    p.append([c[0] + wid, c[1] + wid, c[2] - wid])
    p.append([c[0] + wid, c[1] - wid, c[2] - wid])
    p.append([c[0] - wid, c[1] - wid, c[2] - wid])  # 和第一个相同

    # 顶部
    p.append([c[0] - wid, c[1] - wid, c[2] + wid])
    p.append([c[0] - wid, c[1] + wid, c[2] + wid])
    p.append([c[0] + wid, c[1] + wid, c[2] + wid])
    p.append([c[0] + wid, c[1] - wid, c[2] + wid])
    p.append([c[0] - wid, c[1] - wid, c[2] + wid])  # 和第一个相同

    # 竖直边
    p.append([c[0] - wid, c[1] - wid, c[2] + wid])
    p.append([c[0] - wid, c[1] + wid, c[2] + wid])
    p.append([c[0] - wid, c[1] + wid, c[2] - wid])
    p.append([c[0] + wid, c[1] + wid, c[2] - wid])
    p.append([c[0] + wid, c[1] + wid, c[2] + wid])
    p.append([c[0] + wid, c[1] - wid, c[2] + wid])
    p.append([c[0] + wid, c[1] - wid, c[2] - wid])

    return array(p).T


def my_calibration(sz):
    row, col = sz
    fx = 2555 * col / 2592
    fy = 2586 * row / 1936
    K = diag([fx, fy, 1])
    K[0, 2] = 0.5 * col
    K[1, 2] = 0.5 * row
    return K


def set_projection_from_camera(K):  # 获取视图
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    fx = K[0, 0]
    fy = K[1, 1]
    fovy = 2 * math.atan(0.5 * height / fy) * 180 / math.pi
    aspect = (width * fy) / (height * fx)
    # 定义近和远的剪裁平面
    near = 0.1
    far = 100.0
    # 设定透视
    gluPerspective(fovy, aspect, near, far)
    glViewport(0, 0, width, height)


def set_modelview_from_camera(Rt):  # 获取矩阵
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    # 围绕x轴将茶壶旋转90度,使z轴向上
    Rx = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])
    # 获得旋转的最佳逼近
    R = Rt[:, :3]
    U, S, V = np.linalg.svd(R)
    R = np.dot(U, V)
    R[0, :] = -R[0, :]  # 改变x轴的符号
    # 获得平移量
    t = Rt[:, 3]
    # 获得4*4的的模拟视图矩阵
    M = np.eye(4)
    M[:3, :3] = np.dot(R, Rx)
    M[:3, 3] = t
    # 转置并压平以获取列序数值
    M = M.T
    m = M.flatten()
    # 将模拟视图矩阵替换成新的矩阵
    glLoadMatrixf(m)


def draw_background(imname):
    # 载入背景图像
    bg_image = pygame.image.load(imname).convert()
    bg_data = pygame.image.tostring(bg_image, "RGBX", 1)  # 将图像转为字符串描述
    glMatrixMode(GL_MODELVIEW)  # 将当前矩阵指定为投影矩阵
    glLoadIdentity()  # 把矩阵设为单位矩阵

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)  # 清楚颜色、深度缓冲
    glEnable(GL_TEXTURE_2D)  # 纹理映射
    glBindTexture(GL_TEXTURE_2D, glGenTextures(1))
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bg_data)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    # 绑定纹理
    glBegin(GL_QUADS)
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, -1.0, -1.0)
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, -1.0, -1.0)
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, 1.0, -1.0)
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, 1.0, -1.0)
    glEnd()
    glDeleteTextures(1)  # 清除纹理


def draw_teapot(size):  # 红色茶壶
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glEnable(GL_DEPTH_TEST)
    glClear(GL_DEPTH_BUFFER_BIT)
    # 绘制红色茶壶
    glMaterialfv(GL_FRONT, GL_AMBIENT, [0, 0, 0, 0])
    glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.5, 0.0, 0.0, 0.0])
    glMaterialfv(GL_FRONT, GL_SPECULAR, [0.7, 0.6, 0.6, 0.0])
    glMaterialf(GL_FRONT, GL_SHININESS, 0.25 * 128.0)
    glutSolidTeapot(size)


def drawFunc(size):  # 白色茶壶
    glRotatef(0.5, 5, 5, 0)  # (角度,x,y,z)
    glutWireTeapot(size)
    # 刷新显示
    glFlush()


width, height = 300,400


def setup():  # 设置窗口和pygame环境
    pygame.init()
    pygame.display.set_mode((width, height), OPENGL | DOUBLEBUF)
    pygame.display.set_caption("OpenGL AR demo")


# 计算特征
sift.process_image('a3.jpg', 'a3.sift')
l0, d0 = sift.read_features_from_file('a3.sift')

sift.process_image('a4.jpg', 'a4.sift')
l1, d1 = sift.read_features_from_file('a4.sift')

# 匹配特征,计算单应性矩阵
matches = sift.match_twosided(d0, d1)
ndx = matches.nonzero()[0]
fp = homography.make_homog(l0[ndx, :2].T)
ndx2 = [int(matches[i]) for i in ndx]
tp = homography.make_homog(l1[ndx2, :2].T)

model = homography.RansacModel()
H, inliers = homography.H_from_ransac(fp, tp, model)

# 计算照相机标定矩阵
K = my_calibration((300,400))
# 位于边长为0.2,z=0平面上的三维点
box = cube_points([0, 0, 0.1], 0.1)

# 投影第一幅图下个上底部的正方形
cam1 = camera.Camera(hstack((K, dot(K, array([[0], [0], [-1]])))))
# 底部正方形上的点
box_cam1 = cam1.project(homography.make_homog(box[:, :5]))

# 使用H将点变换到第二幅图像中
box_trans = homography.normalize(dot(H, box_cam1))

# 从cam1和H中计算第二个照相机矩阵
cam2 = camera.Camera(dot(H, cam1.P))
A = dot(linalg.inv(K), cam2.P[:, :3])
A = array([A[:, 0], A[:, 1], cross(A[:, 0], A[:, 1])]).T
cam2.P[:, :3] = dot(K, A)
# 使用第二个照相机矩阵投影
box_cam2 = cam2.project(homography.make_homog(box))

Rt = dot(linalg.inv(K), cam2.P)
setup()
draw_background("a4.jpg")
set_projection_from_camera(K)
set_modelview_from_camera(Rt)

draw_teapot(0.05)  # 显示红色茶壶
# drawFunc(0.05)  # 显示白色空心茶壶
pygame.display.flip()
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

 

 

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

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

相关文章

Windows 11 下使用 MSVC 2022 编译64位Nginx

一、软件准备 1、安装 Visual Studio 2022 包含单个组件&#xff1a; .NET Framework 4.6.1 目标包.NET Framework 4.6.1 SDKWindows 通用 C 运行时Windows 通用 CRT SDKMSVC v142 - VS 2019 C x64/x86 生成工具(v14.26)对 v142 生成工具(14.21)的 C/CLI 支持Clang compile fo…

Linux中MFS分布式文件系统(实战教程)全网最详细

MFS架构图 元数据服务器&#xff08;Master&#xff09;&#xff1a;在整个体系中负责管理文件系统&#xff0c;维护元数据。 元数据日志服务器&#xff08;MetaLogger&#xff09;&#xff1a;备份Master服务器的变化日志文件&#xff0c;文件类型为 changelog_ml.*.mfs。当 …

第六届机器学习、大数据与商务智能国际会议(MLBDBI 2024)

目录 主办单位 大会简介 会议组委会 征稿主题 参会方式 会议日程 重要信息 大会官网&#xff1a;www.mlbdbi.org 会议时间&#xff1a;2024年11月1-3日 会议地点&#xff1a;中国-杭州 收录检索&#xff1a;EI Compendex&#xff0c;Scopus 主办单位 大会简介 由…

SSD300模型总结

1、SSD网络结构 SSD以VGG16作为特征提取特征的基础模型&#xff0c;然后在VGG16的基础上增加了额外的卷积和池化操作来获得更多不同尺度的特征图用来检测不同大小的目标 本文主要是SSD300作为例子进行分析 整体主要分为3个部分 backbone网络&#xff1a;VGG16Extra网络&…

使用Mid360进行FAST_LIO建图,并使用Octomap在线转栅格地图

在之前的教程中&#xff0c;我们已经成功的安装了激光雷达驱动&#xff0c;成功复现了FAST_LIO&#xff0c;并使用OCtomap将点云地图转为栅格地图。 但是之前我们是建图生成了.PCD文件后&#xff0c;读取pcd文件进行离线octomap转栅格地图&#xff0c;这样在实际的场景中并不完…

Python实现贝叶斯优化器(Bayes_opt)优化卷积神经网络-双向长短时记忆循环神经网络分类模型(CNN-BiLSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 随着深度学习技术的发展&#xff0c;卷积神经网络&#xff08;Convolutional Neural Networks, CNNs&a…

Linux驱动基础 | sys文件系统

前言思考sys文件系统简介 sys文件系统是什么sys文件系统功能描述sysfs与objectsysfs接口使用 sysfs读写操作例子sysfs常用的接口sysfs常用的结构体代码实验总结 前言 上篇介绍了Linux驱动中procfs接口的创建&#xff0c;今天介绍sysfs接口的创建&#xff0c;本篇内核采用5.10版…

分支电路导体的尺寸确定和保护

本文旨在确定为分支电路负载供电的导体的尺寸和保护。 支路额定电流 NEC 第 210 条规定了分支电路导体尺寸和过流保护的一般要求。 允许额定电流或过流保护装置的设置确定了分支电路额定值 (210.18)。电路的安培额定值取决于保护导体的断路器或保险丝的额定值&#xff0c;而…

传统CV算法——图像基本操作与形态学操作

环境配置地址 图像显示 import cv2 #opencv读取的格式是BGR import numpy as np import matplotlib.pyplot as plt#Matplotlib是RGB imgcv2.imread(cat.jpg) img_gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) img_gray.shape cv2.imshow("img_gray", img_gray) cv2…

SprinBoot+Vue实验室考勤管理微信小程序的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue3.6 uniapp代码 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平…

d3dx9_43.dll文件缺失的具体处理方法,科学分析5种d3dx9_43.dll修复方法

在使用电脑的过程中&#xff0c;尤其是启动某些游戏或程序时&#xff0c;可能会弹出一条错误信息&#xff1a;“无法找到 d3dx9_43.dll”或者“d3dx9_43.dll文件缺失”。这通常表明你的系统中缺少重要的 DirectX 动态链接库(DLL)文件&#xff0c;阻碍了程序的正常运行。本文将提…

GEE数据集:欧美1950-2022年扩展春季指数(SI-x)

目录 高分辨率扩展春季指数数据库 简介 数据集说明 空间信息 代码 代码链接 APP链接 结果 引用 许可 网址推荐 0代码在线构建地图应用 机器学习 高分辨率扩展春季指数数据库 简介 扩展春季指数&#xff08;SI-x&#xff09;为研究春季开始的时间及其与气候变化的…

【加密社】如何根据.bat文件恢复密钥

加密社 看了这篇指南&#xff0c;你将了解助记词和密钥地址&#xff08;qianbao&#xff09;背后的基本原理。 以及&#xff0c;如何找回你的大饼密钥。 Not your key, not your coin 如果你不掌握自己加密货币钱包的私钥&#xff0c;那么你实际上并不能完全控制你的资产 在当今…

科研|基于SprinBoot+vue的科研管理系统(源码+数据库+文档)

科研管理系统 基于SprinBootvue的科研管理系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员功能实现 科研队伍功能实现 用户功能实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#x…

CTF Show逆向4reserve wp--mingyue

(本题难度较大&#xff0c;分析起来比较复杂&#xff0c;针对该题本文对其中比较重要的部分做了较详细的概述&#xff0c;有问题的地方&#xff0c;请指正) 第一步 查壳。本题为64位 第二步 各部分函数分析 &#xff08;一&#xff09; 分析main函数。 函数签名 int __…

达梦数据库事务管理

目录 一、事务简介 二、事务特性 1.原子性 2.一致性 3.隔离性 4.持久性 三、事务提交 1.自动提交模式 2.手动提交模式 3.隐式提交 四、事务回滚 1.自动回滚 2.手动回滚 3.回滚到保存点 4.语句级回滚 五、事务锁定 1.锁模式 &#xff08;1&#xff09;共享锁 …

WebGIS与WebGL是什么,两者之间的关系?

WebGL和 WebGlS 都是 web 技术领域的重要内容&#xff0c;特别是这几年webgis开发领域&#xff0c;和webgl打交道是必然的&#xff0c;常见的WebGL开发的基础上&#xff0c;比如二维的Leaflet、三维的Cesium也都是热门。 WebGL是一种基于 HTML5 Canvas 元素的 JavaScriptAPI&a…

sqli-labs靶场通关攻略(61-65)

Less-61 步骤一&#xff1a;查看数据库 ?id1)) and updatexml(1,concat(1,(select database())),1)-- 步骤二&#xff1a;查看表名 ?id1)) and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schemasecurity)),1)--…

【专题】2024年中国游戏出海洞察报告合集PDF分享(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p37570 2023 年全球游戏市场规模高达 6205.2 亿美元&#xff0c;且预计未来持续增长&#xff0c;这清晰地展示了该市场的巨大潜力和良好前景。 中国游戏在全球移动游戏市场的份额于 2023 年已达 37%&#xff0c;产业贡献超 30% 的市场…