计算机视觉(相机标定;内参;外参;畸变系数)

2023-05-16

目录

一、预备知识

1、坐标系变换过程(相机成像过程)

(1)相机坐标系转换为图像坐标系(透视投影变换遵循的是针孔成像原理)

(2)齐次坐标的引入原因:(为什么引入齐次坐标???)

2、内参与外参矩阵的构成

3、畸变参数

二、相机标定

1、张正友标定法(光学标定)及其求解思路

 2、求解内参矩阵与外参矩阵的思路:

(1)计算内参与外参矩阵的乘积M

(2)求解内参矩阵A

(3)求解外参矩阵(R1 R2 T)

三、参数优化

1、L-M算法

2、相机标定步骤

四、相关代码及其实验结果

1、相同角度的相机标定

(1)正面

内参矩阵:

畸变参数

旋转矩阵

 平移矢量

 反投影误差

 (2)侧面

内参矩阵

畸变参数

 旋转矩阵

 平移向量

反投影误差

 2、不同角度的相机标定

内参矩阵

畸变参数

旋转矩阵

平移矩阵

反投影误差

6、总结


一、预备知识

1、坐标系变换过程(相机成像过程)

相机成像过程涉及到四个坐标系的变换,变换关系如下:

(U,V,W)是世界坐标系,经过刚体变换(如:旋转、平移)后变为了相机坐标系,再次经过透视投影转变为了图像坐标系,最后经仿射变换转换为了像素坐标系(u,v)。转换关系如下(Z是尺度因子):

(1)相机坐标系转换为图像坐标系(透视投影变换遵循的是针孔成像原理

(2)齐次坐标的引入原因:(为什么引入齐次坐标???)

总结如下:

a. 升维---把图像的变换表示为矩阵相乘的形式,以进行统一计算

图像的变换大多可以使用矩阵乘法来表示变换前后像素的映射关系,但是平移关系却只能使用矩阵加法表示,无法使用矩阵乘法表示。在表示图像变换时(如平移、旋转、缩放),矩阵涉及到乘法与加法,会使计算增加。

所以通过升维的方式来统一矩阵的形式,进而减少计算量。

b. 升维---把无穷远的坐标表示为可运用计算的形式

例子:如果笛卡尔坐标系下的点(3,4)移动到无穷远处,此时的坐标为(oo,oo),使用齐次坐标就可以表示为(3,4,0)。

发现:使用齐次坐标,可以表示平行线在透视空间的无穷远处交于一点。在欧氏空间,这变得没有意义,所以欧式坐标不能表示。

齐次坐标转为欧式空间(3,4,5)=> (3/5,4/5) ---(6,8,10)=> (3/5,4/5)---(24,32,40)=> (3/5,4/5)

由此可以发现:齐次坐标具有规模不变性

2、内参与外参矩阵的构成

内参矩阵:只与相机本身有关,取决于相机的内部参数。

外参矩阵:相机拍摄图片不同,相应的参数会发生变化,即随着世界坐标系与相机坐标系的相对位置而变。

在相机标定求参数中,共有11个参数变量。其中,相机的内部参数有5个:焦距,像主点坐标,畸变参数;相机的外部参数有6个:旋转,平移。

内参矩阵表示为

 其中, f为像距,dX、dY分别表示X、Y方向上的一个像素在相机感光板上的物理长度,即一个像素在感光板上是多少毫米,u0,v0分别表示相机感光板中心在像素坐标系下的坐标,θ表示感光板的横边和纵边之间的角度(  90°表示无误差)。

外参矩阵表示为

  其中,R表示旋转矩阵,  T表示平移矢量。

3、畸变参数

畸变主要分为径向畸变和切向畸变。

径向畸变:沿着透镜半径方向分布的畸变;

产生原因:是由透镜质量引起的,光线在远离透镜中心的地方比靠近中心的地方更加弯曲。

径向畸变主要包括桶形畸变和枕形畸变两种。

切向畸变:切向畸变是由于透镜本身与相机传感器平面(像平面)或图像平面不平行而产生的。

 切向畸变主要发生在相机传感器和镜头不平行的情况下;因为有夹角,所以光透过镜头传到图像传感器上时,成像位置发生了变化。

畸变模型:

 径向畸变模型:

 切向畸变模型:

 径向畸变+切向畸变模型:

 畸变模型中(x',y')为畸变后的归一化图像坐标,(x,y)为理想的无畸变的归一化的图像坐标。

 r为图像像素点到图像中心点的距离,即r^{^{2}}=x^{2}+y^{^{2}}  。

 其中,k1、k2、k3是径向畸变参数;p1、p2切向畸变参数。

在无畸变的标定中,假设内参矩阵为 K,那么经过畸变之后会在矩阵中增加一个畸变参数。

——发生径向畸变之后——

二、相机标定

同步标定内部参数和外部参数,一般包括两种策略:

a. 光学标定: 利用已知的几何信息(如定长棋盘格)实现参数求解;

b. 自标定: 在静态场景中利用 structure from motion估算参数。

通过空间中已知坐标的(特征)点 (Xi,Yi,Zi),以及它们在图像中的对应坐标 (ui,vi),直接估算 11 个待求解的内部和外部参数。

1、张正友标定法(光学标定)及其求解思路

 参考:张正友相机标定法

张正友标定法利用棋盘格标定板图像,利用相应图像检测算法得到每个角点的像素坐标 (u,v)。

张正友标定法将世界坐标系固定于棋盘格上,则棋盘格上任一点的物理坐标W=0 ,由于标定板的世界坐标系是人为事先定义好的,标定板上每一个格子的大小是已知的,我们可以计算得到每一个角点在世界坐标系下的物理坐标(U,V,W=0)。

我们将利用这些信息:每一个角点的像素坐标(u,v) ,每一个角点在世界坐标系下的物理坐标(U,V,W=0),来进行相机的标定,获得相机的内外参矩阵、畸变参数。

 2、求解内参矩阵与外参矩阵的思路:

将世界坐标系固定于棋盘格上,则棋盘格上任一点的物理坐标 W=0,因此,原单点无畸变的成像模型可以化为下式。其中,(R1 R2 T)为旋转矩阵R的前两列。

1. 计算内参与外参矩阵的乘积M--> 2. 求解内参矩阵A--> 3. 求解外参矩阵(R1 R2 T)

(1)计算内参与外参矩阵的乘积M

 其中x=(u,v,1)^{T}X=(X,Y,Z,1)^{T},M矩阵是齐次矩阵,有8个未知元素,每一个标定板上的角点,将提供两个约束方程。一张图片上只需4个角点即可求出矩阵M,一张图片上的角点多于4个时,可以使用最小二乘法求解最佳M。

(2)求解内参矩阵A

利用M1=A(R1,R2,T)求解内擦矩阵A。

 R1,R2作为旋转矩阵的两列,具有单位正交性,满足以下公式:

R_{1}^{T}R_{2}=0, R_{1}^{T}R_{1}=R_{2}^{T}R_{2}=1

R_{1}=A^{-1}M_{1} , R_{2}=A^{-1}M_{2} ,,知

M_{1}^{T}A^{-T}A^{-1}M_{2}^{T}=0,

M_{1}^{T}A^{-T}A^{-1}M_{1}^{T}=M_{2}^{T}A^{-T}A^{-1}M_{2}^{T}=1

A^{-T}A^{-1}=B,则

 其中,B为对称阵。

M_{1}^{T}BM_{2}^{T}=0

M_{1}^{T}BM_{1}^{T}=M_{2}^{T}BM_{2}^{T}=1

可记为M_{i}^{T}BM_{j}^{T}=v_{ij}b,其中b=[B_{_{11}}, B_{_{12}},B_{_{22}},B_{_{13}},B_{_{23}},B_{_{33}} ]

    

每张标定板图片可以提供一个vb=0的约束关系,该约束关系含有两个约束方程。但是,向量b有6个未知元素。取3张标定板照片即可求解向量b 。当标定板图片数大于3时,用最小二乘法拟合最佳的向量 b,并得到矩阵B ;进而求出内参矩阵A。

 v_{0}=\frac{B_{12}B_{13}-B_{11}B_{23}}{B_{11}B_{22}-B_{12}^{2}}

\alpha =\sqrt{\frac{1}{B_{11}}

\beta =\sqrt{\frac{B_{11}}{B_{11}B_{22}-B_{12}^{2}}}

\gamma =-{B_{12}\alpha ^{2}}\beta

u_{0}=\frac{\gamma v_{0}}{\beta }-B_{13}\alpha ^{2}

(3)求解外参矩阵(R1 R2 T)

对于不同的图片,标定板和相机的位置关系已经改变,此时每一张图片对应的外参矩阵都是不同的。

H=(R_{1},R_{2},T) 知外参矩阵可表示为:

 (R_{1},R_{2},T)=A^{-1}H

即可求出每一张图片的外参矩阵(R_{1},R_{2},T)

完整的外参矩阵中旋转矩阵R有三列,其中通过计算R3=R1×R2,即可得到完整的外参矩阵。

三、参数优化

我们的总逻辑是,在进行内参矩阵和外参矩阵的求解的时候,我们假设不存在畸变;在进行畸变系数的求解的时候,假设求得的内参矩阵和外参矩阵是无误差的。最后,我们再通过L-M算法对于参数进行迭代优化。(张正友相机标定法仅考虑了畸变模型中影响较大的径向畸变)

1、L-M算法

L-M方法全称Levenberg-Marquardt方法,是非线性回归中回归参数最小二乘估计的一种估计方法。这种方法是把最速下降法和线性化方法(泰勒级数)加以综合的一种方法。因为最速下降法适用于迭代的开始阶段参数估计值远离最优值的情况,而线性化方法,即高斯牛顿法适用于迭代的后期,参数估计值接近最优值的范围内。两种方法结合起来可以较快地找到最优值  。

LM算法的迭代式:

由上式知:L-M算法是高斯牛顿法与梯度下降法的结合:当u很小时,矩阵J接近矩阵G,其相当于高斯-牛顿法,此时迭代收敛速度快,当u很大时,其相当于梯度下降法,此时迭代收敛速度慢。因此LM算法即具有高斯-牛顿法收敛速度快、不容易陷入局部极值的优点,也具有梯度下降法稳定逼近最优解的特点。

在LM算法的迭代过程中,需要根据实际情况改变u的大小来调整步长:

(1) 如果当前轮迭代的目标函数值大于上轮迭代的目标函数值,即f_{k+1}>f_{k},说明当前逼近方向出现偏差,导致跳过了最优点,需要通过增大u值来减小步长。

(2) 如果当前轮迭代的目标函数值小于上轮迭代的目标函数值,即f_{k+1}<f_{k},说明当前步长合适,可以通过减小u值来增大步长,加快收敛速度。

2、相机标定步骤

1. 打印一张棋盘格A4纸张(黑白间距已知),并贴在一个平板上;

2. 针对棋盘格拍摄若干张图片;

3. 在图片中检测特征点(Harris角点);

4. 根据角点位置信息及图像中的坐标,求解内参矩阵与外参矩阵的积M ;

5. 利用B矩阵计算出5个内部参数得内部矩阵A,以及 6个外部参数 ;

6. 求解畸变参数;

7. 设计优化目标并实现参数的优化。

四、相关代码及其实验结果

引用代码:张正友相机标定法

import os
import numpy as np
import cv2
import glob


def calib(inter_corner_shape, size_per_grid, img_dir, img_type):
    # criteria: only for subpix calibration, which is not used here.
    # criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
    w, h = inter_corner_shape
    # cp_int: corner point in int form, save the coordinate of corner points in world space in 'int' form
    # like (0,0,0), (1,0,0), (2,0,0) ....,(10,7,0).
    cp_int = np.zeros((w * h, 3), np.float32) #返回来一个给定形状和类型的用0填充的数组  54行3列
    cp_int[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2) #  三维网格坐标划分  行2列

    # cp_world: corner point in world space, save the coordinate of corner points in world space.
    cp_world = cp_int * size_per_grid

    obj_points = []  # the points in world space
    img_points = []  # the points in image space (relevant to obj_points)
    images = glob.glob(img_dir + os.sep + '**.' + img_type)
    for fname in images:
        img = cv2.imread(fname)
        gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # find the corners, cp_img: corner points in pixel space.
        ret, cp_img = cv2.findChessboardCorners(gray_img, (w, h), None)
        # if ret is True, save.
        if ret == True:
            # cv2.cornerSubPix(gray_img,cp_img,(11,11),(-1,-1),criteria)
            obj_points.append(cp_world)
            img_points.append(cp_img)
            # view the corners
            cv2.drawChessboardCorners(img, (w, h), cp_img, ret)
            cv2.namedWindow('FoundCorners', cv2.WINDOW_NORMAL)
            cv2.resizeWindow("FoundCorners", 600, 600)  # 设置窗口大小
            cv2.imshow('FoundCorners', img)
            cv2.waitKey(1)
    cv2.destroyAllWindows()
    # calibrate the camera
    ret, mat_inter, coff_dis, v_rot, v_trans = cv2.calibrateCamera(obj_points, img_points, gray_img.shape[::-1], None,
                                                                   None)
#    print(("ret:"), ret)
    print(("internal matrix:\n"), mat_inter)
    # in the form of (k_1,k_2,p_1,p_2,k_3)
    print(("------------------------------------------------------------------"))
    print(("distortion cofficients:\n"), coff_dis) #畸变系数k1,k2,k3径向畸变系数, p1,p2是切向畸变系数。
    print(("------------------------------------------------------------------"))
    print(("rotation vectors:\n"), v_rot)
    print(("------------------------------------------------------------------"))
    print(("translation vectors:\n"), v_trans)
    print(("------------------------------------------------------------------"))
    # calculate the error of reproject
    # 反投影误差
    # 通过反投影误差,我们可以来评估结果的好坏。越接近0,说明结果越理想。
    # 通过之前计算的内参数矩阵、畸变系数、旋转矩阵和平移向量,使用cv2.projectPoints()计算三维点到二维图像的投影,
    # 然后计算反投影得到的点与图像上检测到的点的误差,最后计算一个对于所有标定图像的平均误差,这个值就是反投影误差
    total_error = 0
    for i in range(len(obj_points)):
        img_points_repro, _ = cv2.projectPoints(obj_points[i], v_rot[i], v_trans[i], mat_inter, coff_dis)
        error = cv2.norm(img_points[i], img_points_repro, cv2.NORM_L2) / len(img_points_repro)
        total_error += error
    print(("Average Error of Reproject: "), total_error / len(obj_points))
    return mat_inter, coff_dis

def dedistortion(inter_corner_shape, img_dir, img_type, save_dir, mat_inter, coff_dis):
    w, h = inter_corner_shape
    images = glob.glob(img_dir + os.sep + '**.' + img_type)
    for fname in images:
        img_name = fname.split(os.sep)[-1]
        img = cv2.imread(fname)
        newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mat_inter, coff_dis, (w, h), 0, (w, h))  # 自由比例参数
        dst = cv2.undistort(img, mat_inter, coff_dis, None, newcameramtx)
        # clip the image
        # x,y,w,h = roi
        # dst = dst[y:y+h, x:x+w]
        cv2.imwrite(save_dir + os.sep + img_name, dst)
    print('Dedistorted images have been saved to: %s successfully.' % save_dir)

if __name__ == '__main__':
    inter_corner_shape = (9, 6)
    size_per_grid = 0.026
    img_dir = ".\\pic\\photo5"
    img_type = "jpg"
    # calibrate the camera
    mat_inter, coff_dis = calib(inter_corner_shape, size_per_grid, img_dir, img_type)
    # dedistort and save the dedistortion result.
    save_dir = ".\\pic\\photo5-ch"
    if (not os.path.exists(save_dir)):
        os.makedirs(save_dir)
    dedistortion(inter_corner_shape, img_dir, img_type, save_dir, mat_inter, coff_dis)


1、相同角度的相机标定

(1)正面

 其中: 5张图片(1-5.jpg)10张图片(1-10.jpg)15张图片(1-15.jpg) 

内参矩阵:

5张图片

 10张图片

15张图片

畸变参数

5张图片

 10张图片

15张图片

旋转矩阵

5张图片

 10张图片

 15张图片

   

 平移矢量

5张图片

 10张图片

 15张图片

 反投影误差

5张图片

 10张图片

 15张图片

 (2)侧面

 其中: 5张图片(1-5.jpg)10张图片(1-10.jpg)15张图片(1-15.jpg)

内参矩阵

5张图片

 10张图片

15张图片

畸变参数

5张图片

 10张图片

15张图片

 旋转矩阵

5张图片

 10张图片

  15张图片

  

  平移向量

5张图片

10张图片

15张图片

   

 反投影误差

5张图片

 10张图片

 15张图片

 2、不同角度的相机标定

 其中: 5张图片(1-5.jpg)10张图片(1-10.jpg)15张图片(1-15.jpg) 20张图片(1-20.jpg)

内参矩阵

5张图片

10张图片

15张图片

20张图片

畸变参数

5张图片

10张图片

15张图片

20张图片

旋转矩阵

5张图片

10张图片

15张图片 

20张图片

 

平移矩阵

5张图片

10张图片

15张图片

 

20张图片

 

反投影误差

5张图片

10张图片

15张图片

20张图片

6、总结

对于不同的图片,内参矩阵A为定值;对于同一张图片,内参矩阵A,外参矩阵(R1,R2,T)为定值;对于同一张图片上的单点,内参矩阵A,外参矩阵 (R1,R2,T),尺度因子Z为定值。

对于同一个相机,相机的内参矩阵取决于相机的内部参数,无论标定板和相机的位置关系是怎么样的,相机的内参矩阵不变。

外参矩阵反映的是标定板和相机的位置关系。对于不同的图片,标定板和相机位置的关系有变化,所以每张图片对应的外参矩阵都是不同的。

通过反投影误差,我们可以来评估结果的好坏。越接近0,说明结果越理想。

我使用的角点形状为(9,6),角点之间的距离为0.026cm。

经过对不同拍摄角度的不同数量的实验对比,知:

1、经过相同角度的拍摄知:

(1)对于不同数量棋盘格,内参矩阵略有变化。

(2)畸变系数包含径向畸变与切向畸变,系数会随着棋盘格的数量发生变化。

(3)旋转矩阵、平移矢量针对不同的图片具有在不同数量的实验中的值略有变化。

正面10张图片中变化较大,可能时因为拍摄角度有晃动的原因。

(4)反投影误差随着我们棋盘格的数量变化不大。

2、经过不同角度的拍摄知:

(1)对于不同数量棋盘格,内参矩阵变化明显。

(2)畸变系数包含径向畸变与切向畸变,系数会随着棋盘格的不同数量的实验有变化。

(3)旋转矩阵、平移矢量针对不同的图片具有不同的值,相同的照片在不同数量的实验中,值的差异较大。

(4)反投影误差随着我们棋盘格的数量会逐渐增大。

通过反投影误差,我们可以来评估结果的好坏。越接近0,说明结果越理想。

3、由拍摄角度差异知:

无论拍摄角度、还是实验所使用的棋盘格的数量而言,内参矩阵,外参矩阵,畸变参数,反投影误差都有变化。即:每一次标定的结果都会发生变化。

每次标定的结果不同,可能的来源有这么几个:
a. 计算的内外参数的初值不同,可能因为相机标定过程中,使用迭代优化时没有收敛到最小值,只是收敛到了局部最小值。
b. 标定获得数据不稳定,标定板的大小不合适,这个影响也很大。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机视觉(相机标定;内参;外参;畸变系数) 的相关文章

  • iOS开发,如何让xib关联一个UIView?

    我们创建UIView时 xff0c 默认是没有xib选项的 xff0c 那么如何让xib跟UIView关联 xff1f 还有 xff0c 为什么创建时默认没有xib xff0c 苹果这样做肯定有他自己的想法吧
  • 如何把未知长度的字符串从末尾截掉指定的字串呢?

    如 xff1a 字串 xff1a 沈阳市公安局电话 想截掉尾部的 电话 xff0c 如何实现呢 xff1f
  • android 怎样实现从文本框获得用户名和密码,自动登录网站?

    现有一需求 xff0c 要求从两个文本框输入用户名和密码 xff0c 点击登录后自动登录某网站
  • 字符数组结束符'0'的问题

    字符数组结束符 0 的问题 char str 10 61 I a m h a p p y 如果花括号中提供的字符个数大于数组长度 xff0c 则按语法错误处理 xff1b 若小于数组长度 xff0c 则只将这些字符数组中前面那些元素 xff
  • 切换JDK版本运行java命令时报Error: could not open xxx解决方法

    安装了jdk8和jdk11两个版本 xff0c 并配置好环境变量后 切换jdk8没有问题 xff0c 切换jdk11时输入java version检查版本出现了如下图片问题 xff1b 解决方案1 xff1a 将环境变量path中 JAVA
  • 阿里云服务器ubuntu18.04安装可视化界面

    这里写目录标题 一 远程连接ubuntu二 安装可视化界面三 安装过程中的问题 一 远程连接ubuntu 输入root密码即可 xff08 这个为实例密码 xff09 二 安装可视化界面 依次输入以下shell命令 apt span cla
  • 奇偶检验等N、O、E、M、S 五种串口检验位类型

    一 检验位 在串行通讯所发送数据的最后一位 xff0c 用来粗略的检验数据在传输过程中是否有出错 二 检验位的五种类型 1 N xff08 None 没有 xff09 无校验 不加校验位 xff0c 可以少传输一位数据 2 O xff08
  • Onvif登录海康、大华摄像机(IPC)提示权鉴失败的问题解决

    最近用我们的Onvif设备发现客户端测试 xff0c 发现连接某些摄像机Onvif获取不到设备信息 xff0c 提示401权鉴失败 确认用户名和密码都没错的情况下 xff0c 都还是失败 xff0c 软件提示信息截图如下 xff1a 我们测
  • 反解析Android APK

    重命名APK为zip 并解压到当前文件中 下载dex解析工具dex2jar link https github com pxb1988 dex2jar releases tag v2 2 SNAPSHOT 2021 10 31 解析文件命令
  • 大数加法越界处理

    大数越界处理 当数据很大时 xff0c 求中点的方法 i 43 j 2的结果有可能会超出 int 类型的取值范围 在此情况下 xff0c 我们需要换一种计算中点的写法 i 43 j 有可能超出 int 的取值范围 int m 61 i 43
  • idea使用断言

    测试程序 public class TestAssert public static void main String args String s1 61 null assert s1 61 null 默认assert不起作用 需开启 ve
  • 2018年面试总结 -- 多线程很重要,多总结很重要

    2018年面试总结 先后面试了Android Linux C C 43 43 QT 得到的结论有以一下几条 xff1a 1 多线程作为一个高级话题太重要了 几乎每种开发环境下都会问到 xff0c 无论是Android还是QT xff1b 2
  • 平常使用的小问题【Windows11开启不了热点,开启热点后连不上去】

    故障现象 xff1a xff08 1 xff09 连接设备一直显示obtaining ip address xff08 2 xff09 电脑没有显示连接的设备 解决措施 xff1a xff08 1 xff09 先转到设置 xff08 2 x
  • IOException: No such file or directory 问题解决

    文章目录 问题描述 xff1a 注册权限动态申请权限总结 xff1a 问题描述 xff1a Android开发 xff0c 在访问文件夹创建文件的时候 xff0c 报错IOException No such file or director
  • 2020(春)工程伦理MOOC期末考试答案

    单选题 多选题 判断题
  • Git中Fork使用

    GitLab或者GitHub中的Fork可以理解为一个物理副本 xff0c 用来管理代码的一种手段 在参与开源项目代码贡献时 xff0c 通常不会直接获得源代码仓库的Developer权限 这点和一般公司开发不太一样 xff0c 公司一般都
  • 在OK6410上运行QT程序找不到libQtGui.so.4的解决

    想在OK6410上运行自己经过交叉编译的QT程序 xff0c OK6410上烧写的是光盘所带的Linux系统 xff0c 运行程序时出现以下现象 xff1a qt server error while loading shared libr
  • Docker的安装

    这篇文章原文是我2016年10月份写的 xff0c 当时在研究docker xff0c 上周六不经意翻了出来 xff0c 由于3月换工作 xff0c 新环境比较忙 xff0c 没时间写些东西 xff0c 所以先把之前写的东西放一下 xff0
  • CRAZEPONY飞控学习(一)

    在不久前曾研究过最近最为流行的开源飞控Pixhawk的源代码 xff0c 但是由于在这之前没有接触过操作系统这个概念 xff0c 在不知道代码执行流程的情况下看了几个星期的时间 xff0c 脑子里还是一团乱 xff0c 所以决定还是从裸机开
  • PHP常用的设计模式

    php常用的设计模式 xff1a 1 单例模式 xff08 构造方法私有化 xff0c 对外提供实例化对象的静态调用方法 xff09 class Site span class token punctuation span public s

随机推荐

  • 003.多线程-主线程、守护线程、用户线程的区别

    对于线程的分类 xff0c 我们可以简单划分为 xff1a 主线程 xff08 每个进程只有一个主线程 xff09 子线程 主线程 xff1a main方法 子线程 xff1a 非主线程皆是子线程 子线程中可以简单划分为 xff1a 守护线
  • Ubuntu中在当前目录下打开终端

    在Ubuntu中 xff0c 打开终端可以通过Ctrl 43 Alt 43 T来打开 xff0c 但其打开的是 下的 xff0c 如果进入指定的目录 xff0c 便需要通过cd命令来进行切换 xff0c 故本文提供一个可以通过鼠标右键来在当
  • C语言经典面试题100道(校对详解版)

    题目非本人整理 xff0c 转载于https blog csdn net qq 42613510 article details 81225935 做了校对与详解 xff0c 方便大家参考 最后编程答案自己做的 xff0c 还没写完 xff
  • 浅谈FreeRTOS任务启动与切换流程

    一个轻量级操作系统最核心的地方就在于任务的执行与切换 xff0c 像FreeRTOS和ucOS 在任务启动与切换方面都差不多 xff0c 本文主要从枝干而省去了所有细枝末节让你最快的了解操作系统的任务创建与切换 以正点原子FreeRTOS移
  • 状态机编程思维学习笔记(C语言)

    前言 不摸鱼摆烂的第一天 目录 前言C语言面对对象特性引入函数指针结构体中套用函数指针宏定义中 纯替换 状态机概念状态机实现后文 C语言面对对象特性引入 众所周知 xff0c C 43 43 是由C语言编写而成 xff0c 因此 xff0c
  • stm32串口中断收发数据环形缓冲区的设计

    Function Name USART2 IRQHandler Description This function handles USART2 global interrupt request Input None Output None
  • 多线程的守护线程和等待线程结束方法

    守护线程的含义是 xff1a 如果当前运行的所有线程都是守护线程 xff0c 则程序直接结束 package thread 64 ClassName Test7 64 Author 瞿肖 64 Date 2022 7 11 14 32 pu
  • 用数学规划的方式求解优化问题

    本文介绍如何用数学语言对实际中的优化问题进行建模 通过建立数学模型 我们利用现成的求解器可以便捷地计算出最优解 或可行解 运输问题 考虑三个粮食储量分别是100 200 300的仓库 单位 吨 下文省略 我们需要把粮食运送给4个客户 其需求
  • 操作系统磁盘管理

    文章目录 01 知识概述部分02 课程知识回顾说明03 磁盘管理知识体系结构04 磁盘管理物理结构05 磁盘管理分区操作问题 xff1a 新添加硬盘无法识别 分区操作1 xff1a fdisk xff08 操作时可看10点的视频 xff09
  • ROS学习——Rviz(更新中)

    固定架 两个框架中最重要的是固定框架 固定框架是用于表示 世界 框架的参考框架 这通常是 地图 或 世界 或类似名称 xff0c 但也可以是例如里程表框架 如果将固定框架错误地设置为例如机器人的底座 xff0c 则机器人曾经见过的所有物体都
  • Boost型Ladrc控制双闭环电路 双闭环控制

    Boost型Ladrc控制双闭环电路 双闭环控制 xff08 1 xff09 电压外环采用简化Ladrc控制器 xff0c 简化线性自抗扰控制 xff0c 采用PD控制 43 三阶LESO状态观测器 xff0c xff08 2 xff09
  • 【STM32】HAL库——串口中断通信(二)

    由于调试过程中发现Proteus 8有些许bug xff0c 串口中断采用STM32F103RCT6开发板进行讲解 前期准备 xff1a STM32CubeMXSTM32F103RCT6开发板IDE Keil xff08 MDK ARM x
  • Detected problems with API compatibility...修复

    Detected problems with API compatibility 修复 一 xff0c Detected problems with API 问题产生 博主接手年代过于老旧项目 xff0c 在最新安卓版本P等都会出现该弹窗提
  • docker 标记(Tag),推送(push),拉取(pull)你自己的镜像

    链接 https blog csdn net jpiverson article details 50731568 里面的有很详细的步骤和见解 1 输入docker images命令来查看当前的镜像列表 2 找到镜像的id 3 使用IMAG
  • ASSERT: "false" in file qasciikey.cpp, line 501

    pycharm利用moba xterm的x server远程开发 xff0c 在用cv2显示图片时报错 xff1a ASSERT 34 false 34 in file qasciikey cpp line 501 代码 xff1a cv2
  • nvidia-smi命令输出结果缓慢

    可能的原因和解决办法 xff1a 当前已经打开了节能模式 xff08 需要关闭节能模式 xff0c 切换到持久模式 xff09 如何关闭节能模式 xff1a span class token comment 修改或创建配置文件 span s
  • ESP8266深度学习之一初识设备

    一 ESP8266是什么 xff1f 总的来说ESP8266是一款单片机 xff0c 而且是一款自带WIFI功能的单片机 它是安信可公司众多单片机中的一种 xff0c 同时它也有很多种型号可以供我们选择使用 二 ESP8266有什么特点 x
  • 什么是RTK?

    国内习惯把GNSS接收机叫成RTK这倒是真的 xff0c 因为RTK技术的普及 xff0c 让大家对接收机的作用就 限定 在了RTK xff0c 在之前没有RTK时 xff0c 接收机就是接收机 目前 xff0c GNSSj接收机约99 的
  • STM32F103VCT6 高级定时器的PWM输出

    要求得到下列波形 xff0c 死区时间1us CH1和CH1之间的相位差事3us 频率50HZ 1 xff0c To get TIM1 counter clock at 72MHz the prescaler is computer as
  • 计算机视觉(相机标定;内参;外参;畸变系数)

    目录 一 预备知识 1 坐标系变换过程 xff08 相机成像过程 xff09 xff08 1 xff09 相机坐标系转换为图像坐标系 xff08 透视投影变换遵循的是针孔成像原理 xff09 xff08 2 xff09 齐次坐标的引入原因