畸变校正与极线校正(具体原理+Matlab代码)

2023-05-16

附:相关需要的工具函数源代码(投影函数、校正矩阵计算等)见最下面

1. 畸变校正

1.1 形成原因

图像畸变一般有两种,第一种是透镜本身的形状有问题,使得图像发生径向畸变;第二种是透镜安装时与成像平面之间不完全平行,导致图像发生切向畸变。畸变会导致图像中物体的形状与实际物体的形状不相同,比如直线变成曲线、矩形拉长等。故而想要得到实际真实图像,必须要根据之前对相机进行标定得到的参数对图像进行畸变的去除。
在这里插入图片描述
(a)径向畸变

在这里插入图片描述
(b)切向畸变
图像畸变示意

1.2 消除办法

畸变去除的基本思路为:

  1. 假设图像没有发生畸变,将图像由图像坐标系转换到相机坐标系(归一化相机坐标系,即距离为1)
  2. 根据之前标定好的相机参数,计算畸变之后相机坐标系上的点坐标
  3. 根据相机内参将畸变之后的相机坐标系上的点坐标变换到图像坐标系下
  4. 根据计算的点坐标与原始图像进行插值。
    具体的原理解析,可以参考文章https://blog.csdn.net/shyjhyp11/article/details/109506149,推导过程非常详细。
function [img_correct,newOrigin] = ImgDistortionCorrection(img,camera,OutputView)
%undistortImage Correct image for lens distortion.
%   [J, newOrigin] = undistortImage(I, intrinsics) removes lens distortion
%   from image I, and returns the result as image J. I can be a grayscale
%   or a truecolor image. intrinsics is either cameraParameters or
%   cameraIntrinsics object.
%
%   newOrigin is a 2-element vector containing the [x,y] location of the 
%   origin of the output image J in the intrinsic coordinates of the input 
%   image I. Before using extrinsics, pointsToWorld, or triangulate 
%   functions you must add newOrigin to the coordinates of points detected 
%   in undistorted image J in order to transform them into the intrinsic 
%   coordinates of the original image I.
%   If 'OutputView' is set to 'same', then newOrigin is [0, 0]. 
if OutputView=='same'
    % Para init 
    [X,Y] = meshgrid(0:size(img,2)-1,0:size(img,1)-1);
    c_x = camera.center(1,1);
    c_y = camera.center(1,2);
    f_x = camera.focal(1,1);
    f_y = camera.focal(1,2);
    k1 = camera.dis(1,1);
    k2 = camera.dis(1,2);
    g1 = camera.dis(1,3);
    g2 = camera.dis(1,4);
    k3 = camera.dis(1,5);
    % calculate point in camrera coordinate system
    x1 = (X-c_x)/f_x;
    y1 = (Y-c_y)/f_y;
    % calculate dis_point in camrera coordinate system
    r2 = x1.^2+y1.^2;
    x2 = x1.*(1+k1*r2+k2*r2.^2+k3*r2.^3)+2*g1*x1.*y1+g2*(r2+2*x1.^2);
    y2 = y1.*(1+k1*r2+k2*r2.^2+k3*r2.^3)+2*g2*x1.*y1+g1*(r2+2*y1.^2);
    % (u, v) undis (u_d, v_d)
    % calculate dis point in image coordinate system
    u_d = f_x*x2 + c_x+1;
    v_d = f_y*y2 + c_y+1;
    % interp to get undis image
    img_correct = interp2(img, u_d, v_d);
    newOrigin = [0,0];
end
end

注意事项:
(1)与OPENCV结果进行过对比,matlab中的矩阵序号需要减去1以成为坐标,但是仍然存在一定误差,具体原因不明确,希望有大佬给出解释。

2. 极线校正

2.1 基本原因

进行畸变校正获取到真实图像后,为了方便下一步的立体匹配,还需要进行极线校正,即将左右两个相机平面变成一个平面,然后每一行像素相互对应。(下文代码大部分搬运自matlab标定工具箱)

2.2 基本流程

  1. 计算两个相机平面校正至水平的变换矩阵(但是相机中心以及前后仍存在距离)。
    设世界坐标系为左相机坐标系,右相机到左相机的旋转矩阵为R,平移为T,设同一点在左相机为 P 1 P_1 P1,右相机为 P 2 P_2 P2,则可得 P 2 = R P 1 + T P_2=RP_1+T P2=RP1+T
    利用罗德里格斯公式,可将旋转矩阵变换为旋转向量 n ∗ θ n*\theta nθ(向量方向 n n n为旋转轴,模 θ \theta θ为旋转角度),将旋转角度一份为二,得到 n ∗ θ / 2 n*\theta/2 nθ/2,再反向变换为旋转矩阵 r r r
    则将相机1坐标系旋转 r ′ r' r,相机2坐标系旋转 r r r,则两个相机坐标系理应平行。旋转后两个坐标系下的P点应该变换为 P 1 ′ = r P 1 P_1^{'}=rP_1 P1=rP1, P 2 ′ = r ′ P 2 P_2^{'}=r'P_2 P2=rP2,可以变换成 P 2 ′ = r ′ ∗ ( R P 1 + T ) = P 1 ′ + r ′ ∗ T P_2^{'}=r'*(RP_1+T)=P_1^{'}+r'*T P2=r(RP1+T)=P1+rT
    % R、T are right camera to left camera,R*C2+T=C1
    % P2=RP1+T
    % Bring the 2 cameras in the same orientation by rotating them "minimally":
    r_r = rodrigues(-camera2.R/2);
    r_l = r_r';
    t = r_r * camera2.T';
  1. 计算两个平行平面将中心变换到一致的变换矩阵,即将两个坐标系一起进行变换直到基线与X轴平行。(两个坐标系前后一致,且基线与X轴平行)
    极线可以视作T,因此计算T到X轴的变换矩阵R2,然后同时对两个坐标系进行变换即可 。
    矩阵计算方法:
    (1)计算T到X的旋转角度,点乘除以模再计算acos即可。
    (2)计算旋转轴,即T与X轴都垂直的方向,叉乘除以两个模即可。
    (3)基于罗德里格斯公式计算旋转矩阵。
  % Rotate both cameras so as to bring the translation vector in alignment with the (1;0;0) axis:
    if abs(t(1)) > abs(t(2))
        type_stereo = 0;
        uu = [1;0;0]; % Horizontal epipolar lines
    else
        type_stereo = 1;
        uu = [0;1;0]; % Vertical epipolar lines
    end
    if dot(uu,t)<0
        uu = -uu; % Swtich side of the vector
    end
    
    % rotate to make the epipolar lines of the two camera images horizontal,the x-axis coincides with t.
    ww = cross(t,uu);
    ww = ww/norm(ww);
    ww = acos(abs(dot(t,uu))/(norm(t)*norm(uu)))*ww; % Rotation angle modulo times the rotation axis
    R2 = rodrigues(ww);
  1. 虽然相机坐标系已经校正, 但是左右相机内参仍然不同,图像坐标系上仍然不会对齐因此需要对内参进行更改,将左右相机 f x , f y f_x,f_y fx,fy设置成相同,理论上还有个 α \alpha α,但一般不做考虑。
    (1)设置新的内参,将左右相机 f x , f y f_x,f_y fx,fy设置成相同,为了简化,直接取平均值。
   % Computation of the *new* intrinsic parameters for both left and right cameras:
   % Vertical focal length *MUST* be the same for both images (here, we are trying to find a focal length that retains as much information contained in the original distorted images):
   fc_y_new = min(camera1.focal(1,2),camera2.focal(1,2));
   
   % For simplicity, let's pick the same value for the horizontal focal length as the vertical focal length (resulting into square pixels):
   fc_left_new = round([fc_y_new;fc_y_new]);
   fc_right_new = round([fc_y_new;fc_y_new]);

(2)计算前两步旋转变换之后,如果想将相机坐标系得到的中心点变换到图像坐标系,偏移应该是多少,以确保得到更多图像。首先将原始图像四个角点变换到归一化相机坐标系,然后将其投影到新的图像坐标系(旋转变换后的图像坐标系)下,用理论图像中心点减去四个角点的平均值,即可得到偏移值 c x , c y c_x,c_y cx,cy,为了考虑左右都取较多图像,因此需要取平均值,根据是水平校正还是竖直校正选取平均 c x 或 c y c_x或c_y cxcy

    % Select the new principal points to maximize the visible area in the rectified images
    % normalize_pixel: Transform the four corners of the original image to the normalized camera plane
    % project_points2:Project the four corners of the normalized plane to the transformed camera coordinate plane, and set new f_x, f_y and c_x, c_y.
    cc_left_new = [(nx-1)/2;(ny-1)/2] - mean(project_points2([normalize_pixel([0  nx-1 nx-1 0; 0 0 ny-1 ny-1],fc_left,cc_left,kc_left,alpha_c_left);[1 1 1 1]],rodrigues(R_L),zeros(3,1),fc_left_new,[0;0],zeros(5,1),0),2);
    cc_right_new = [(nx-1)/2;(ny-1)/2] - mean(project_points2([normalize_pixel([0  nx-1 nx-1 0; 0 0 ny-1 ny-1],fc_right,cc_right,kc_right,alpha_c_right);[1 1 1 1]],rodrigues(R_R),zeros(3,1),fc_right_new,[0;0],zeros(5,1),0),2);
    % For simplivity, set the principal points for both cameras to be the average of the two principal points.
    if ~type_stereo
        %-- Horizontal stereo
        cc_y_new = (cc_left_new(2) + cc_right_new(2))/2;
        cc_left_new = [cc_left_new(1);cc_y_new];
        cc_right_new = [cc_right_new(1);cc_y_new];
    else
        %-- Vertical stereo
        cc_x_new = (cc_left_new(1) + cc_right_new(1))/2;
        cc_left_new = [cc_x_new;cc_left_new(2)];
        cc_right_new = [cc_x_new;cc_right_new(2)];
    end
    
    % Of course, we do not want any skew or distortion after rectification:

(3)根据最新参数,重新计算图像变换以及插值。

% Pre-compute the necessary indices and blending coefficients to enable quick rectification: 
% The original image is changed in the function when Irec_junk_left is calculated, so it cannot be directly used as the corrected image
[Irec_junk_left,ind_new_left,ind_1_left,ind_2_left,ind_3_left,ind_4_left,a1_left,a2_left,a3_ left,a4_left] = rect_index(zeros(ny,nx),R_L,fc_left,cc_left,kc_left,alpha_c_left,KK_left_new);
[Irec_junk_right,ind_new_right,ind_1_right,ind_2_right,ind_3_right,ind_4_right,a1_right,a2_right,a3_right,a4_right] = rect_index(zeros(ny,nx),R_R,fc_right,cc_right,kc_right,alpha_c_right,KK_right_new);

clear Irec_junk_left Irec_junk_right

%图像校正 
img_left_rectified = zeros(ny,nx);
img_left_rectified(ind_new_left) = a1_left .* img_left(ind_1_left) + a2_left .* img_left(ind_2_left) + a3_left .* img_left(ind_3_left) + a4_left .* img_left(ind_4_left);
  

完整函数代码如如下

function [img_left_rectified, img_right_rectified,Q,R1] = PolarlineCorrection(img_left, ...
    img_right, camera1,camera2,flag,alpha,type_stereo)
% rectifyStereoImages Rectifies a pair of stereo images.
%   [img_left_rectified, img_left_rectified] = rectifyStereoImages(img_left, img_right, camera1,camera2) 
%   rectifies img_left and img_right, a pair of truecolor or grayscale stereo images.
%   camera1 and camera2 are stereoParameters object containing the parameters of
%   the stereo camera system. img_left_rectified and img_right_rectified are the rectified images.
% 
%   param flags Operation flags that may be zero or CALIB_ZERO_DISPARITY . If the flag is set CALIB_ZERO_DISPARITY,
%   the function makes the principal points of each camera have the same pixel coordinates in the
%   rectified views. And if the flag is not set, the function may still shift the images in the
%    horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the
%   useful image area.
%
%   param alpha Free scaling parameter. If it is -1 or absent, the function performs the default
%   scaling. Otherwise, the parameter should be between 0 and 1. alpha=0 means that the rectified
%   images are zoomed and shifted so that only valid pixels are visible (no black areas after
%   rectification). alpha=1 means that the rectified image is decimated and shifted so that all the
%   pixels from the original images from the cameras are retained in the rectified images (no source
%   image pixels are lost). Obviously, any intermediate value yields an intermediate result between
%   those two extreme cases.

if flag==0 && alpha == -1
    
    %Test: init para
    alpha_c_left = 0;
    kc_left =zeros(1,5);
    alpha_c_right = 0;
    kc_right =zeros(1,5);
    fc_left =camera1.focal';
    fc_right =camera2.focal';
    cc_left = camera1.center';
    cc_right = camera2.center';
    
    % R、T are right camera to left camera,R*C2+T=C1
    % P2=RP1+T
    % Bring the 2 cameras in the same orientation by rotating them "minimally":
    r_r = rodrigues(-camera2.R/2);
    r_l = r_r';
    t = r_r * camera2.T';
    
    % Rotate both cameras so as to bring the translation vector in alignment with the (1;0;0) axis:
    if abs(t(1)) > abs(t(2))
        type_stereo = 0;
        uu = [1;0;0]; % Horizontal epipolar lines
    else
        type_stereo = 1;
        uu = [0;1;0]; % Vertical epipolar lines
    end
    if dot(uu,t)<0
        uu = -uu; % Swtich side of the vector
    end
    
    % rotate to make the epipolar lines of the two camera images horizontal,the x-axis coincides with t.
    ww = cross(t,uu);
    ww = ww/norm(ww);
    ww = acos(abs(dot(t,uu))/(norm(t)*norm(uu)))*ww; % Rotation angle modulo times the rotation axis
    R2 = rodrigues(ww);
    
    % Global rotations to be applied to both views:
    R_R = R2 * r_r;
    R_L = R2 * r_l;
    
    % The resulting rigid motion between the two cameras after image rotations (substitutes of om, R and T):
    R_new = eye(3);
    om_new = zeros(3,1);
    T_new = R_R*camera2.T';
    
    nx = size(img_left,2);
    ny = size(img_left,1);
    
    % Computation of the *new* intrinsic parameters for both left and right cameras:
    % Vertical focal length *MUST* be the same for both images (here, we are trying to find a focal length that retains as much information contained in the original distorted images):
    fc_y_new = min(camera1.focal(1,2),camera2.focal(1,2));
    
    % For simplicity, let's pick the same value for the horizontal focal length as the vertical focal length (resulting into square pixels):
    fc_left_new = round([fc_y_new;fc_y_new]);
    fc_right_new = round([fc_y_new;fc_y_new]);
    
    % Select the new principal points to maximize the visible area in the rectified images
    % normalize_pixel: Transform the four corners of the original image to the normalized camera plane
    % project_points2:Project the four corners of the normalized plane to the transformed camera coordinate plane, and set new f_x, f_y and c_x, c_y.
    cc_left_new = [(nx-1)/2;(ny-1)/2] - mean(project_points2([normalize_pixel([0  nx-1 nx-1 0; 0 0 ny-1 ny-1],fc_left,cc_left,kc_left,alpha_c_left);[1 1 1 1]],rodrigues(R_L),zeros(3,1),fc_left_new,[0;0],zeros(5,1),0),2);
    cc_right_new = [(nx-1)/2;(ny-1)/2] - mean(project_points2([normalize_pixel([0  nx-1 nx-1 0; 0 0 ny-1 ny-1],fc_right,cc_right,kc_right,alpha_c_right);[1 1 1 1]],rodrigues(R_R),zeros(3,1),fc_right_new,[0;0],zeros(5,1),0),2);
    % For simplivity, set the principal points for both cameras to be the average of the two principal points.
    if ~type_stereo
        %-- Horizontal stereo
        cc_y_new = (cc_left_new(2) + cc_right_new(2))/2;
        cc_left_new = [cc_left_new(1);cc_y_new];
        cc_right_new = [cc_right_new(1);cc_y_new];
    else
        %-- Vertical stereo
        cc_x_new = (cc_left_new(1) + cc_right_new(1))/2;
        cc_left_new = [cc_x_new;cc_left_new(2)];
        cc_right_new = [cc_x_new;cc_right_new(2)];
    end
    
    % Of course, we do not want any skew or distortion after rectification:
alpha_c_left_new = 0;
alpha_c_right_new = 0;
kc_left_new = zeros(5,1);
kc_right_new = zeros(5,1);


% The resulting left and right camera matrices:
KK_left_new = [fc_left_new(1) fc_left_new(1)*alpha_c_left_new cc_left_new(1);0 fc_left_new(2) cc_left_new(2); 0 0 1];
KK_right_new = [fc_right_new(1) fc_right_new(1)*alpha_c_right cc_right_new(1);0 fc_right_new(2) cc_right_new(2); 0 0 1];

% The sizes of the images are the same:
nx_right_new = nx;
ny_right_new = ny;
nx_left_new = nx;
ny_left_new = ny;

% Save the resulting extrinsic and intrinsic paramters into a file:
fprintf(1,'Saving the *NEW* set of intrinsic and extrinsic parameters corresponding to the images *AFTER* rectification under Calib_Results_stereo_rectified.mat...\n\n');
save Calib_Results_stereo_rectified om_new R_new T_new  fc_left_new cc_left_new kc_left_new alpha_c_left_new KK_left_new fc_right_new cc_right_new kc_right_new alpha_c_right_new KK_right_new nx_right_new ny_right_new nx_left_new ny_left_new

% Let's rectify the entire set of calibration images:

fprintf(1,'Pre-computing the necessary data to quickly rectify the images (may take a while depending on the image resolution, but needs to be done only once - even for color images)...\n\n');

% Pre-compute the necessary indices and blending coefficients to enable quick rectification: 
% The original image is changed in the function when Irec_junk_left is calculated, so it cannot be directly used as the corrected image
[Irec_junk_left,ind_new_left,ind_1_left,ind_2_left,ind_3_left,ind_4_left,a1_left,a2_left,a3_ left,a4_left] = rect_index(zeros(ny,nx),R_L,fc_left,cc_left,kc_left,alpha_c_left,KK_left_new);
[Irec_junk_right,ind_new_right,ind_1_right,ind_2_right,ind_3_right,ind_4_right,a1_right,a2_right,a3_right,a4_right] = rect_index(zeros(ny,nx),R_R,fc_right,cc_right,kc_right,alpha_c_right,KK_right_new);

clear Irec_junk_left Irec_junk_right

%图像校正 
img_left_rectified = zeros(ny,nx);
% rect_Img_left(ind_new_left) = uint8(a1_left .* src_Img_left(ind_1_left) + a2_left .* src_Img_left(ind_2_left) + a3_left .* src_Img_left(ind_3_left) + a4_left .* src_Img_left(ind_4_left));
img_left_rectified(ind_new_left) = a1_left .* img_left(ind_1_left) + a2_left .* img_left(ind_2_left) + a3_left .* img_left(ind_3_left) + a4_left .* img_left(ind_4_left);
  
img_right_rectified = zeros(ny,nx);
% rect_Img_right(ind_new_right) = uint8(a1_right .*
% src_Img_right(ind_1_right) + a2_right .* src_Img_right(ind_2_right) + a3_right .* src_Img_right(ind_3_right) + a4_right .* src_Img_right(ind_4_right));
img_right_rectified(ind_new_right) = a1_right .* img_right(ind_1_right) + a2_right .* img_right(ind_2_right) + a3_right .* img_right(ind_3_right) + a4_right .* img_right(ind_4_right);

Q = zeros(4,4);
Q(1,1)=1;
Q(1,4)=-cc_left_new(1);
Q(2,2)=1;
Q(2,4)=-cc_left_new(2);
Q(3,4)=fc_left_new(1);
Q(4,3)=-1/T_new(1);
Q(4,4) = (cc_left_new(1)-cc_right_new(1))/(T_new(1));
R1= R_L;
end

end


3. 注意问题总结

1.畸变校正与极线校正本质上是两件事,因此可以单独先进行畸变校正,再进行极线校正(畸变参数设置为0),也可以直接极线校正时顺带将畸变校正完成(输入畸变参数)。
2.旋转矩阵变换时,当坐标系2到坐标系1的旋转矩阵为R,平移为T,设同一点在坐标系1为 P 1 P_1 P1,坐标系2为 P 2 P_2 P2,则可得 P 2 = R P 1 + T P_2=RP_1+T P2=RP1+T,而非 P 1 = R P 2 + T P_1=RP_2+T P1=RP2+T
3.此函数使用时需要调用部分maltba标定工具箱的计算函数,具体源代码可见https://download.csdn.net/download/zhangpan333/85445628

参考文章:
[1]畸变校正原理 https://blog.csdn.net/shyjhyp11/article/details/109506149
[2] 极线校正原理 https://blog.csdn.net/weixin_44083110/article/details/117635824

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

畸变校正与极线校正(具体原理+Matlab代码) 的相关文章

  • 开源贴片机OpenPnp使用体验

    平时做板子比较多 xff0c 一直想整一个贴片机 xff0c 但是据说国产的桌面贴片机用起来都不咋地 xff0c 而且价格也不菲 xff0c 带视觉的将近2W 思来想去选择了OpenPnP xff0c 一方面价格便宜 xff0c 另一方面开
  • 【干货】STM32通过ADC模拟看门狗实现掉电保存

    1 前言 很多时候我们需要将程序中的一些参数 数据等存储在EEPROM或者Flash中 xff0c 达到掉电保存的目的 但有些情况下 xff0c 程序需要频繁的修改这些参数 xff0c 如果每次修改参数都进行一次保存 xff0c 那将大大降
  • 【开源项目】SFUD--通用串口Flash驱动库的移植和使用

    1 简介 SFUD 是一款开源的串行 SPI Flash 通用驱动库 由于现有市面的串行 Flash 种类居多 xff0c 各个 Flash 的规格及命令存在差异 xff0c SFUD 就是为了解决这些 Flash 的差异现状而设计 xff
  • STM32F0系列中断向量映射问题

    最近用Cortex M0内核的STM32F030K6T6做个东西 xff0c 需要做IAP升级 xff0c 发现它的中断向量与M3 M4等内核的单片机不太一样 xff0c 这里分享给大家 IAP升级需要一个BootLoader程序 xff0
  • STM32定时器实现红外接收与解码

    1 NEC协议 红外遥控是一种比较常用的通讯方式 xff0c 目前红外遥控的编码方式中 xff0c 应用比较广泛的是NEC协议 NEC协议的特点如下 xff1a 载波频率为 38KHz 8 位地址和 8位指令长度 地址和命令2次传输 xff
  • SPI读写SD卡速度有多快?

    SD卡是一个嵌入式中非常常用的外设 xff0c 可以用于存储一些大容量的数据 但用单片机读写SD卡速度一般都有限 xff08 对于高速SD卡 xff0c 主要是受限于单片机本身的接口速度 xff09 xff0c 在高速 实时数据存储时可能会
  • SPI方式读写SD卡速度有多快?

    很久没有写公众号了 xff0c 一方面忙 xff0c 另一方面也不知道写些什么内容 xff0c 大家如果有想了解的 xff08 前提是我也懂 xff09 xff0c 可以后台发送给我 今天主要来测试一下SPI读写SD卡的速度 SD卡是一个嵌
  • 火狐浏览器添加脚本(可代替手动做一些操作)

    首先打开火狐浏览器的更多组件 xff0c 在扩展中搜索Greasemonkey 然后点击安装 安装成功后点立即重启 重新打开浏览器后浏览器右上角会有一个猴子的图标 点击下标按钮 xff0c 新建用户脚本 xff0c 新建用户脚本可以随意命名
  • SDIO读写SD卡速度有多快?

    前两天测试了SPI方式读写SD卡的速度 SPI方式读写SD卡速度测试 xff0c 今天来测试一下SDIO方式的读写速度 测试条件 xff1a 单片机 xff1a STM32F407VET6 编译环境 xff1a MDK 5 30 43 HA
  • STM32CubeMx+HAL库实现USB CDC+MSC复合设备

    之前的文章中介绍过STM32的USB应用 xff0c 包括虚拟串口 xff08 CDC xff09 和大容量存储设备 xff08 MSC xff09 今天来介绍USB实现CDC和MSC复合设备的方法 硬件 xff1a STM32F407VE
  • 基于STM32CubeMx的USB CDC+MSC复合设备

    之前的文章中介绍过STM32的USB应用 xff0c 包括虚拟串口 xff08 CDC xff09 和大容量存储设备 xff08 MSC xff09 今天来介绍USB实现CDC和MSC复合设备的方法 硬件 xff1a STM32F407VE
  • go标准库httputil.ReverseProxy简单介绍和使用避坑

    很久没水博客了 xff0c 今天就来水一篇 xff0c 说说go标准库的httputil ReverseProxy httputil ReverseProxy顾名思义 xff0c http的反向代理 xff0c 可以类比nginx的反向代理
  • (二)Ardupilot软件分析及代码架构

    先要搞明白ardupilot是怎么实现飞行控制的 xff1f 然后再看文件 1 建立两个基本坐标系 xff1a 地理坐标系和载体坐标系 xff0c 保证两个基本坐标系的正确转化 一般使用旋转矩阵实现坐标系转换 xff1a 四元数运算 q01
  • STM32F103 实例应用——实现透传转发串口

    一 预期准备 实现机制 xff1a 空闲中断 43 DMA中断接收不定长串口数据 开发工具 xff1a STM32F103芯片 xff0c keil5 xff0c usb转ttl工具 预计实现效果 xff1a 串口1接收数据然后透传给串口2
  • 解决:ORA-06550 字符串长度限制在范围 (1...32767)

    错误信息 ORA 06550 第 1 行 第 782 列 PLS 00215 字符串长度限制在范围 1 32767 解决 本例是配置存储过程job的job action 61 gt 39 Declare FLAG Number 20 FAI
  • gcc、make、makefile、cmake、cmakelists区别

    转自 xff1a http www zhihu com question 36609459 辉常哥 1 gcc是GNU Compiler Collection xff08 就是GNU编译器套件 xff09 xff0c 也可以简单认为是编译器
  • FIFO和DMA

    FIFO SPI端口增加了FIFO xff0c 使得传输数据有了缓冲区间 FIFO存储器是一个先入先出的双口缓冲器 xff0c 即第一个进入其内的数据第一个被移出 xff0c 其中一个存储器的输入口 xff0c 另一个口是存储器的输出口 主
  • 蓝桥杯C语言基础练习 十进制转十六进制

    代码 xff08 解法类似十进制转二 八进制 xff09 include lt stdio h gt char getnum int z switch z case 0 return 39 0 39 break case 1 return
  • Linux和Windows下使用printf的差别

    1 Linux系统下 一般而言 xff0c 大家都知道printf是带有行缓冲的函数 xff0c printf把打印的消息先输出到行缓冲区 xff0c 在以下几种情况下 xff1a 1 程序结束时调用exit 0 return xff1b
  • Could not connect ot Redis No route to host问题解决

    局域网内访问另外一台服务器上的redis 报错 Could not connect to Redis No route to host 问题解决 发现是防火墙问题 于是设置 iptables N REDIS iptables A REDIS

随机推荐

  • 大数据挑战赛-鼠标轨迹识别

    大数据挑战赛 鼠标轨迹识别 xff0c 竞赛官网 xff1a http bdc saikr com c cql 34541 1 我们看一下整个竞赛的详情 赛题描述 鼠标轨迹识别当前广泛运用于多种人机验证产品中 xff0c 不仅便于用户的理解
  • 暴力破解字典列表

    GitHub上的 xff1a https github com danielmiessler SecLists tree master Passwords Leaked Databases https github com duyetdev
  • Burpsuite技巧之MD5加密密码爆破、带验证码爆破

    一 Burpsuite技巧之MD5加密密码爆破 现在有很多后台都不再是明文传输 xff0c 改成了各种各样的加密方式 今天就拿MD5加密方式做一个演示 xff0c 举一反三 xff0c 希望对新手有用 如图 xff0c MD5加密了密码 x
  • 解决ubuntu连不上网络,输入ifconfig只显示本地环回问题

    使用虚拟机打开ubuntu后发现无法连接网络 首先我使用了ping www baidu com 然后通过命令sudo service network manager restart重启服务后仍然没有用 于是输入命令ifconfig查看网卡
  • https://mp.weixin.qq.com/s/ilO6DZwRpWdrruKm4J8CMw

    近日安全漏洞频发 xff0c 小编在此收集了近期大家会比较关注的漏洞 xff0c 做个总结 xff0c 供大家查漏补缺 xff0c 若有缺失 xff0c 欢迎留言补充 目录 一 OA系统 二 E mail 三 Web中间件 四 源代码管理
  • 浅谈JavaScript、ES5、ES6

    什么是JavaScript JavaScript一种动态类型 弱类型 基于原型的客户端脚本语言 xff0c 用来给HTML网页增加动态功能 xff08 好吧 xff0c 概念什么最讨厌了 xff09 动态 xff1a 在运行时确定数据类型
  • js声明变量的三种方式

    JS 声明变量的三种方式 xff08 1 xff09 使用变量步骤 xff1a a 声明 gt b 赋值 gt 3 调用 正确用法 xff1a lt script type 61 34 text javascript 34 gt 方式一 x
  • JS中[感叹号]function(){}()的理解

    这种写法 xff0c 是一种 96 立即执行函数 96 的写法 xff0c 即IIFE等设计模式 这种函数在函数定义的地方就直接执行了 理解IIFE设计模式的关键是要认识到 xff0c 在ES6之前 xff0c JavaScript仅具有函
  • Python:查找字符在字符串中的位置

    str 1 61 39 wo shi yi zhi da da niu 39 char 1 61 39 i 39 nPos 61 str 1 index char 1 print nPos 运行结果 xff1a 7 61 61 61 61
  • Multipart/form-data POST文件上传详解

    理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据 xff0c 都是通过form表达提交的 xff0c 代码如下 lt form method 61 34 post 34 action 61 34 http w
  • IIS6、IIS7和IIS8各版本的差别

    一 写在前面 目前市面上所用的IIS版本估计都是 gt 61 6 0的 所以我们主要以下面三个版本进行讲解 服务器版本IIS默认版本server20036 0server20087 0server20128 0 二 IIS6的请求过程 由图
  • Http请求头中X-Requested-With的含义

    昨天看代码的时候 xff0c 看到了这个一句 String requestedWith 61 HttpServletRequest request getHeader 34 X Requested With 34 X Requested W
  • 云台、RS485简介与区别

    云台 云台 xff08 Pan amp Tilt amp Zoom xff09 xff0c 缩写为PTZ 云台就是两个交流电机组成的安装平台 xff0c 可以分别围绕一中心轴作水平和垂直的运动 xff0c 将摄像机安装于其上 xff0c 实
  • ubuntu14.04版本下ulimit连接数限制的解决方法

    Linux对于每个用户 xff0c 系统限制其最大进程数 为提高性能 xff0c 可以根据设备资源情况 xff0c 设置各linux 用户的最大进程数 可以使用ulimit a查看当前限制 xff1a 对于一些服务的资源限制 xff0c 如
  • 防止全局变量重复定义

    问题 xff1a 在 h文件中定义了全局变量 并用 ifndef identifier h define identifier h endif 但是依然出现重复定义问题 分析 xff1a ifndef这套条件编译是为了防止同一个 c文件中包
  • Checksum 校验和

    一 校验数据的一般算法比较 都是通过对数据进行校验产生一个校验值 xff0c 用来校验数据完整性 不同点 xff1a 算法不同 CRC采用多项式除法 xff0c MD5和SHA1使用的是替换 轮转等方法 xff1b 校验值的长度不同 CRC
  • GPIO小综合-按键实验

    之前用寄存器操作实现了跑马灯和蜂鸣器 这次接着输入寄存器IDR捕获按键 并且综合亮灯和发出声音 xff0c 作为寄存器GPIO小综合练习 首先查KEY的电路图 xff0c 分别用到了ACD几个时钟 KEY0对应PC8 xff0c KEY1对
  • 数据结构入门

    概念 数据 Data xff1a 是客观事物的符号表示 在计算机科学中指的是所有能输入到计算机中并被计算机程序处理的符号的总称 数据元素 Data Element xff1a 是数据的基本单位 xff0c 在程序中通常作为一个整体来进行考虑
  • Linux系统发布项目完整教程

    目录 1 后端代码打包 1 1后端代码中文件上传路径修改 1 2 后端代码打包 1 3 后端项目发布 2 前端静态资源打包 2 1 项目中关于路径修改的说明 2 2模拟域名访问的设置 修改HOSTS文件 2 3 前端请求路径修改 2 4 前
  • 畸变校正与极线校正(具体原理+Matlab代码)

    附 xff1a 相关需要的工具函数源代码 xff08 投影函数 校正矩阵计算等 xff09 见最下面 1 畸变校正 1 1 形成原因 图像畸变一般有两种 xff0c 第一种是透镜本身的形状有问题 xff0c 使得图像发生径向畸变 xff1b