相机模型Omnidirectional Camera(全方位摄像机)
1. 背景
大多数商用相机都可以描述为针孔相机,通过透视投影进行建模。然而,有些投影系统的几何结构无法使用传统针孔模型来描述,因为成像设备引入了非常高的失真。其中一些系统就是全方位摄像机。
有几种方法可以制作全向相机。屈光照相机(Dioptric cameras)使用成形透镜的组合(例如鱼眼透镜;见图1a),并且可以达到甚至大于180度的视野(即略大于半球)。折反射相机(Catadioptric cameras)将标准相机与成型镜(如抛物面镜、双曲面镜或椭圆镜)相结合,在水平面上提供360度的视野,在仰角(elevation)上提供100度以上的视野。在图1b中,您可以看到使用双曲镜的折反射相机示例。最后,多折射相机使用多个具有重叠视场的相机,迄今为止是唯一提供真正全向(球形)视场(即4π立体视场)的相机。
折反射相机最早于1990年由Yagi和Kawato引入机器人学,他们使用折反射相机定位机器人。直到2000年,由于新的制造技术和精密工具,鱼眼相机才开始普及,使其视野增加到180度甚至更多。然而,直到2005年,这些相机才被小型化到1-2厘米的大小,并且它们的视野增加到190度甚至更大)。
2. 模型原理
Ocam模型成像参考D Scaramuzza,可分为两个过程,先将相机坐标系下的坐标转换成ocam坐标系下的角度,再根据θ计算畸变系数,进而计算像素坐标,需要注意Ocam相机是左手系,存在一个相机坐标系到Ocam坐标系的坐标变换,其θ角度与Fisheye不同。
2.1. Central omnidirectional cameras
当被观察物体的光线在3D中的一个点(称为投影中心或单有效视点)相交时,视觉系统被称为中心(图2)。此属性称为单一有效视点属性。透视相机(perspective camera)是中央投影系统的一个示例,因为所有光线(optical rays)在一个点(即相机光学中心)相交。
所有现代鱼眼相机都是中心的,因此,它们满足单一有效视点特性。相反,中央折反射相机只能通过适当选择镜子形状和相机与镜子之间的距离来构建。正如Baker和Nayar[6]所证明的,满足单视点特性的镜族是一类旋转(扫描)圆锥截面,即双曲、抛物线和椭圆镜。对于双曲线镜和椭圆镜,通过确保相机中心(即针孔或透镜中心)与双曲线(椭圆)的一个焦点重合来实现单视点特性(图3)。对于抛物面反射镜,必须在相机和反射镜之间插入正交透镜,这使得抛物面反射镜反射的平行光线可能会聚到相机中心(图3)。
单一有效视点之所以如此理想,是因为它允许用户从全向相机拍摄的图片中生成几何正确的透视图像(图4)。这是可能的,因为在单视点约束下,感知图像中的每一个像素测量是通过视点的光在特定方向上的辐照度。当全向相机的几何形状已知时,即相机校准时,可以为每个像素预先计算出该方向。因此,可以将每个像素测量的辐照度值映射到视点任意距离的平面上,形成平面透视图像。此外,可以将图像映射到以单个视点为中心的球体上,即球形投影(图4,底部)。单视点属性如此重要的另一个原因是它允许用户应用著名的视极几何理论,这对从运动到结构非常重要。极向几何适用于任何中央相机,无论是透视还是全向。
2.2. Omnidirectional camera model and calibration
直观地说,全向相机的模型比标准透视相机稍微复杂一点。该模型确实应该考虑折反射相机的镜面反射,或者鱼眼相机的镜头折射。由于这一领域的文献相当多,本章回顾了两种不同的预测
这些模型已经成为全方位视觉和机器人技术的标准。此外,
已经为这两个模型开发了Matlab工具箱,全世界的专家和非专家都在使用它们。
第一种模型称为中央折反射相机的统一投影模型。它是由Geyer和Daniilidis(后来由Barreto和Araujo[8]改进)在2000年开发的,他们的优点是提出了一个包括所有三种类型的中央折反射相机的模型,即使用双曲镜、抛物面镜或椭圆镜的相机。这个模型是专门为中央折反射相机开发的,对鱼眼相机无效。用折反射透镜近似鱼眼透镜模型通常是可能的-然而,只有有限的精度-在[9]中进行了研究。
相反,第二种模型将中心折反射相机和鱼眼相机统一在一个通用模型下,也称为泰勒模型。它由Scaramuzza等人在2006年开发[10,11],其优点是折反射相机和屈光相机都可以用同一个模型来描述,即一个泰勒多项式。
2.3. Unified model for central catadioptric cameras(中央折反射相机的统一模型)
Geyer和Daniilidis在2000年发表的具有里程碑意义的论文中指出,每一种折反射(抛物线、双曲线、椭圆线)和标准透视投影都等价于从一个以单一视点为中心的球体到一个以垂直于平面且距离较远的平面为投影中心的平面的投影映射。从球体的中心。图5总结了这一点。
本节的目标是找到场景点的观看方向和其对应图像点的像素坐标之间的关系。Geyer和Daniilidis的投影模型遵循四个步骤。设P = (x, y, z)为以C为中心的镜像参照系中的场景点(图5)。为了方便起见,我们假设镜子的对称轴与相机的光轴完全对齐。我们还假设相机和镜子的x轴和y轴是对齐的。因此,相机和镜像参考系的不同只是沿z轴的平移。
第一步是将场景点投射到单位球体上;因此:
然后将点坐标转换为以c为中心的新参照系= (0,0,…);因此:
范围在0(平面镜)和1(抛物面镜)之间。的正确值。可以通过知道圆锥曲线的焦点和直侧肌之间的距离d得到,如表1所示。圆锥剖面的直腹侧是通过平行于圆锥剖面准线的焦点的弦。
然后将p投影到距离c1的归一化图像平面上;因此,
最后,通过本征参数矩阵K将该点m映射到摄像机图像点p= (u, v, 1);因此,
很容易证明函数g.1是双射的,它的逆g由:
∝表示g与右边的量成正比。为了得到归一化因子,只要将g(m)归一化到单位球上就足够了。
式(6)可通过对式(3)求逆,加上p_s必须在单位球上的约束而得,因此。从这个约束条件,我们得到了zs作为xm和ym的函数的表达式。更多细节可以在[12]中找到。
可以看出式(6)是中心折反相机投影模型的核心。它表示了归一化图像平面上的点m与镜像参考系中单位向量Ps之间的关系。注意,对于平面镜,我们,成为透视相机的投影方程。
该模型已被证明能够准确地描述所有中心折反相机(抛物面镜、双曲镜和椭圆镜)和标准透视相机。Ying和Hu[9]在2004年提出了对鱼眼镜头模型的扩展。然而,通过折反射光学相机来接近鱼眼相机只能在有限的精度下工作。这主要是因为,虽然可以用精确的参数函数(抛物线、双曲线、椭圆)表示三种中心折射率相机,但鱼眼镜头的投影模型因相机而异,并取决于镜头的视场。为了克服这个问题,提出了一个新的统一模型,将在下一节中进行描述。
2.4. Unified model for catadioptric and fisheye cameras(折射率相机和鱼眼相机的统一模型)
该统一模型由Scaramuzza等人在2006年提出[10,11]。与前一个模型的主要区别在于函数g的选择。针对鱼眼相机参数化模型知识不足的问题,提出了利用泰勒多项式的方法,通过标定过程求出泰勒多项式的系数和度。因此,规范化的关系像点m= (xm, ym, 1)和鱼眼的单位向量Ps(镜子)参考系可以写成:
其中, 。读者可能已经注意到,多项式的一阶项(即)不见了。这是根据观察得出的,在ρ = 0处计算的多项式的一阶导数对于折反射相机和鱼眼相机都必须是零(这是通过微分(6)对折反射相机进行验证的直接方法)。还要注意,由于它的多项式性质,这个表达式可以包含折反射相机、鱼眼相机和透视相机。这可以通过适当地选择多项式的次数来实现。正如作者所强调的,阶数为3或4的多项式能够非常准确地建模所有折反射相机和市场上可用的多种鱼眼相机。这一模型适用于广泛的商业相机是其成功的根源。
2.5. Omnidirectional camera calibration
全向摄像机的标定与标准视角摄像机的标定类似。同样,最流行的方法利用了用户在不同位置和方向上显示的平面网格。对于全向相机来说,标定图像是在相机周围拍摄的,而不是在单面拍摄的,这一点非常重要。这是为了补偿相机和后视镜之间可能出现的偏差。
值得一提的是,目前有三种开源的Matlab校准工具箱,它们的区别主要在于所采用的投影模型和校准模式的类型。
3. ocam图转多张针孔图
3.1. Python实现
import numpy as np""" Reads file containing the ocamcalib parameters exported from the Matlab toolbox """
def get_ocam_model(filename):o = {}with open(filename) as f:lines = [l for l in f]l = lines[2]data = l.split()o['length_pol'] = int(data[0])o['pol'] = [float(d) for d in data[1:]]l = lines[6]data = l.split()o['length_invpol'] = int(data[0])o['invpol'] = [float(d) for d in data[1:]]l = lines[10]data = l.split()o['xc'] = float(data[0])o['yc'] = float(data[1])l = lines[14]data = l.split()o['c'] = float(data[0])o['d'] = float(data[1])o['e'] = float(data[2])l = lines[18]data = l.split()o['height'] = int(data[0])o['width'] = int(data[1])return odef get_ocam_model_from_json(camera_name, camera_calib_dict):o = {}o['length_pol'] = camera_calib_dict[camera_name]['intrinsic_param']['cam2world_len']o['pol'] = [float(d) for d in camera_calib_dict[camera_name]['intrinsic_param']['cam2world']]o['length_invpol'] = camera_calib_dict[camera_name]['intrinsic_param']['world2cam_len']o['invpol'] = [float(d) for d in camera_calib_dict[camera_name]['intrinsic_param']['world2cam']]o['xc'] = camera_calib_dict[camera_name]['intrinsic_param']['center'][0]o['yc'] = camera_calib_dict[camera_name]['intrinsic_param']['center'][1]o['c'] = camera_calib_dict[camera_name]['intrinsic_param']['affine_c']o['d'] = camera_calib_dict[camera_name]['intrinsic_param']['affine_d']o['e'] = camera_calib_dict[camera_name]['intrinsic_param']['affine_e']o['width'] = camera_calib_dict[camera_name]['ImgSize'][0]o['height'] = camera_calib_dict[camera_name]['ImgSize'][1]print ('o = ', o)return odef cam2world(point2D, o):point3D = []invdet = 1.0/(o['c']-o['d']*o['e'])xp = invdet*((point2D[0]-o['xc']) - o['d']*(point2D[1]-o['yc']))yp = invdet*(-o['e']*(point2D[0]-o['xc']) + o['c']*(point2D[1]-o['yc']))r = np.linalg.norm([xp,yp])zp = o['pol'][0]r_i = 1.0for i in range(1,o['length_pol']):r_i *= rzp += r_i*o['pol'][i]invnorm = 1.0/np.linalg.norm([xp,yp,zp])point3D.append(invnorm*xp)point3D.append(invnorm*yp)point3D.append(invnorm*zp)return point3Ddef world2cam_bak(point3D, o):point2D = [] norm = np.linalg.norm(point3D[:2])if norm != 0:theta = np.arctan(point3D[2]/norm)invnorm = 1.0/normt = thetarho = o['invpol'][0]t_i = 1.0for i in range(1,o['length_invpol']):t_i *= trho += t_i*o['invpol'][i]x = point3D[0]*invnorm*rhoy = point3D[1]*invnorm*rhopoint2D.append(x*o['c']+y*o['d']+o['xc'])point2D.append(x*o['e']+y+o['yc'])else:point2D.append(o['xc'])point2D.append(o['yc'])return point2Ddef world2cam(point3D, o):point2D = [] norm = np.linalg.norm(point3D[:2])if norm != 0:theta = np.arctan(point3D[2]/norm)invnorm = 1.0/normt = thetarho = o['invpol'][0]t_i = 1.0for i in range(1,o['length_invpol']):t_i *= trho += t_i*o['invpol'][i]x = point3D[0]*invnorm*rhoy = point3D[1]*invnorm*rhopoint2D.append(x + y*o['e'] + o['xc'])point2D.append(x*o['d'] + y*o['c'] + o['yc'])else:point2D.append(o['xc'])point2D.append(o['yc'])return point2Ddef create_perspective_undistortion_LUT(o, sf):mapx = np.zeros((o['height'],o['width'])) mapy = np.zeros((o['height'],o['width'])) Nxc = o['height']/2.0Nyc = o['width']/2.0 Nz = -o['width']/sf for i in range(o['height']):for j in range(o['width']):M = []M.append(i - Nxc)M.append(j - Nyc)M.append(Nz)m = world2cam(M, o) mapx[i,j] = m[1]mapy[i,j] = m[0]return mapx, mapy# horizontal_angle_offset, in degree, [-90, 90], default = 0
def create_perspective_undistortion_LUT_Focal(o, persp_height, persp_width, focal, horizontal_angle_offset):mapx = np.zeros((persp_height,persp_width)) mapy = np.zeros((persp_height,persp_width)) Nxc = persp_width/2.0 Nyc = persp_height/2.0Nz = -focal theat = horizontal_angle_offset*np.pi/180.0rotation = np.array([ np.cos(theat), 0, np.sin(theat),0, 1, 0,-np.sin(theat), 0, np.cos(theat)]).reshape(3,3)#print(rotation)for i in range(persp_height):for j in range(persp_width):M = []M.append(j - Nxc)M.append(i - Nyc)M.append(Nz)M_ary = np.array(M).reshape(3,-1)#print(M_ary)M_ary_rot = np.dot(rotation, M_ary).astype(np.float64)#print(M_ary_rot)m = world2cam(M_ary_rot.reshape(3).tolist(), o) mapx[i,j] = m[0]mapy[i,j] = m[1]return mapx, mapydef create_panoramic_undistortion_LUT(Rmin, Rmax, o):mapx = np.zeros((o['height'],o['width'])) mapy = np.zeros((o['height'],o['width'])) for i in range(o['height']):for j in range(o['width']):theta = -(float(j))/o['width']*2*np.pirho = Rmax - float(Rmax-Rmin)/o['height']*imapx[i,j] = o['yc'] + rho*np.sin(theta)mapy[i,j] = o['xc'] + rho*np.cos(theta)return mapx, mapy
3.2. C++实现
#include <map>
#include <string>
#include <math.h>
#include <Eigen/Dense>
#include <opencv2/core/core.hpp>
#include <jsoncpp/json/json.h>typedef std::pair<cv::Mat, cv::Mat> LUT;struct OcamModel{int length_pol, length_invpol, height, width;float xc, yc, c, d, e;std::vector<float> pol, invpol;
};// used
OcamModel get_ocam_model(std::string filename){OcamModel o;return o;
}OcamModel get_ocam_model_from_json(std::string camera_name, std::map<std::string, Json::Value> camera_calib_dict){OcamModel o;o.length_pol = camera_calib_dict[camera_name]["intrinsic_param"]["cam2world_len"].asInt();Json::Value vec = camera_calib_dict[camera_name]["intrinsic_param"]["cam2world"];for(auto x : vec)o.pol.push_back(x.asFloat());o.length_invpol = camera_calib_dict[camera_name]["intrinsic_param"]["world2cam_len"].asInt();vec = camera_calib_dict[camera_name]["intrinsic_param"]["world2cam"];for(auto x : vec)o.invpol.push_back(x.asFloat());o.xc = camera_calib_dict[camera_name]["intrinsic_param"]["center"][0].asFloat();o.yc = camera_calib_dict[camera_name]["intrinsic_param"]["center"][1].asFloat();o.c = camera_calib_dict[camera_name]["intrinsic_param"]["affine_c"].asFloat();o.d = camera_calib_dict[camera_name]["intrinsic_param"]["affine_d"].asFloat();o.e = camera_calib_dict[camera_name]["intrinsic_param"]["affine_e"].asFloat();o.width = camera_calib_dict[camera_name]["ImgSize"][0].asInt();o.height = camera_calib_dict[camera_name]["ImgSize"][1].asInt();// std::cout << "o.length_pol = " << o.length_pol << std::endl;// std::cout << "o.length_invpol = " << o.length_invpol << std::endl;// std::cout << "o.height = " << o.height << std::endl;// std::cout << "o.width = " << o.width << std::endl;// std::cout << "o.xc = " << o.xc << std::endl;// std::cout << "o.yc = " << o.yc << std::endl;// std::cout << "o.c = " << o.c << std::endl;// std::cout << "o.d = " << o.d << std::endl;// std::cout << "o.e = " << o.e << std::endl;return o;
}cv::Vec3f cam2world(cv::Vec2f p2, OcamModel o){float invdet = 1.0 / (o.c-o.d*o.e);float xp = invdet * ((p2(0)-o.xc) - o.d*(p2(1) - o.yc));float yp = invdet * (-o.e*(p2(0) - o.xc) + o.c * (p2(1) - o.yc));float r = sqrt(xp * xp + yp * yp);float zp = o.pol[0];float r_i = 1.0;for(int i = 1; i<o.length_pol; i++){r_i *= r;zp += r_i * o.pol[i];}float invnorm = 1.0 / sqrt(xp * xp + yp * yp + zp * zp);return cv::Vec3f(invnorm * xp, invnorm * yp, invnorm * zp);
}cv::Vec2f world2cam(cv::Vec3f p3, OcamModel o){float norm = sqrt(p3(0) * p3(0) + p3(1) * p3(1));if(norm == 0)return cv::Vec2f(o.xc, o.yc);float theta = atan(p3(2) / norm);float invnorm = 1.0 / norm;float t = theta;float rho = o.invpol[0];float t_i = 1.0;for(int i = 1; i<o.length_invpol; i++){t_i *= t;rho += t_i * o.invpol[i];}float x = p3[0] * invnorm * rho;float y = p3[1] * invnorm * rho;return cv::Vec2f(x + y*o.e + o.xc, x*o.d + y*o.c + o.yc);
}LUT create_perspective_undistortion_LUT_Focal(OcamModel o, int persp_height, int persp_width, int focal, int horizontal_angle_offset){cv::Mat mapx(persp_height, persp_width, CV_32FC1), mapy(persp_height, persp_width, CV_32FC1);// std::vector<std::vector<float>> mapy(persp_height, std::vector<float>(persp_width));float Nxc = (float)persp_width / 2.0;float Nyc = (float)persp_height / 2.0;float Nz = -(float)focal;float theta = (float)horizontal_angle_offset * M_PI / 180.0;Eigen::Matrix3f rotation;rotation << cos(theta), 0, sin(theta), 0, 1, 0, -sin(theta), 0, cos(theta);for (int i = 0; i<persp_height; i++) {// uchar *ptrx = mapx.ptr<uchar>(i);// uchar *ptry = mapy.ptr<uchar>(i);for(int j = 0; j<persp_width; j++){Eigen::Vector3f p3(j-Nxc, i-Nyc, Nz);Eigen::Vector3f v3 = rotation * p3;cv::Vec2f m = world2cam(cv::Vec3f(v3[0], v3[1], v3[2]), o);// std::cout << m << std::endl;// *ptrx = m[0]; ptrx++;// *ptry = m[1]; ptry++;mapx.at<float>(i, j) = m[0];mapy.at<float>(i, j) = m[1];}}return {mapx, mapy};
}LUT create_panoramic_undistortion_LUT(float Rmin, float Rmax, OcamModel o){cv::Mat mapx(o.height, o.width, CV_32FC1), mapy(o.height, o.width, CV_32FC1);for(int i = 0; i<o.height; i++){for(int j = 0; j<o.width; i++){float theta = -2 * M_PI * (float)j / o.width;float rho = Rmax - (float)(Rmax - Rmin) * (float)i / (float)o.height;mapx.at<float>(i, j) = o.yc + rho * sin(theta);mapy.at<float>(i, j) = o.xc + rho * cos(theta);}}return {mapx, mapy};
}
4. 坐标投影到像素
4.1. 3D到2D投影
class SVCCalibrationSDK:def __init__(self, intrinsic_param, width, height):self.image_size = np.array([height, width]) # rows, colsself.world2cam = np.array(intrinsic_param["world2cam"]).reshape(-1, 1)self.world2cam_len = np.array(intrinsic_param["world2cam_len"])self.svc_rotation = np.array([[1., intrinsic_param["affine_e"]],[intrinsic_param["affine_d"], intrinsic_param["affine_c"]]])self.svc_translation = np.array(intrinsic_param["center"])def cam_to_pixel(self, points):num_points = len(points)if num_points == 0:return np.empty((0, 3))else:norm = np.sqrt(np.sum(points[:, 0:2] * points[:, 0:2], axis=1, keepdims=True))theta = np.arctan(points[:, 2:3] * (-1 / norm))poly_theta = np.power(theta, np.arange(self.world2cam_len))rho = (poly_theta @ self.world2cam)pixels = (points[:, 0:2] * (rho / norm)) @ self.svc_rotation + self.svc_translationreturn pixels
4.2. 2D到3D投影
其中:,所以的有效系数的个数不一定与f的有效系数一样
参考文献
A Toolbox for Easily Calibrating Omnidirectional Cameras
Omnidirectional Camera
https://sites.google.com/site/scarabotix/ocamcalib-omnidirectional-camera-calibration-toolbox-for-matlab
相机模型 Omnidirectional Camera(全方位摄像机)_中心折反射相机-CSDN博客
相关文章:
相机模型Omnidirectional Camera(全方位摄像机)
1. 背景 大多数商用相机都可以描述为针孔相机,通过透视投影进行建模。然而,有些投影系统的几何结构无法使用传统针孔模型来描述,因为成像设备引入了非常高的失真。其中一些系统就是全方位摄像机。 有几种方法可以制作全向相机。屈光照相机(D…...
论文阅读——Align before Fuse
Align before Fuse: Vision and Language Representation Learning with Momentum Distillation image-text contrastive learning(ITC)用在单模态,masked language modeling (MLM) and image-text matching (ITM) 用在多模态。 单模态编码器的表示上引入了中间图像…...
鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Rating)
提供在给定范围内选择评分的组件。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Rating(options?: { rating: number, indicator?: boolean }) 从API version 9开始&#…...
Unity中的网格创建和曲线变形
Unity中的网格创建和曲线变形 3D贝塞尔曲线变形贝塞尔曲线基础线性公式二次方公式三次方公式 Unity 实现3D贝塞尔曲线变形准备工作脚本概述变量定义 变量解析函数解析 获取所有子节点GetAllChildren 获取所有子节点UpdateBezierBend 控制点更新CalculateBezier Bezier 曲线公式…...
day0 3r文档docker部署
3R编码 | 3R教室 - 最好的数字游民学习与交流俱乐部! (3rcd.com) window安装wsl下载不下来,正好有个服务器,就用linux吧密钥长度不匹配,设置一下长度即可 文档启动不成功,单独下载了下nginx,docker pull nginx:latest …...
PSCA复位控制集成之复位信号
组件可能支持两种基本的复位类型。 • 冷复位:重置组件中的所有逻辑。用作上电复位。 • 热复位:重置组件中的大部分逻辑。通常,复位的范围是所有功能逻辑。不包括在热复位中的逻辑会随组件类型而变化,但通常会排除诸如调试和 R…...
C#,数值计算,数据测试用的对称正定矩阵(Symmetric Positive Definite Matrix)的随机生成算法与源代码
C.Hermite 1、对称矩阵 对称矩阵(Symmetric Matrices)是指以主对角线为对称轴,各元素对应相等的矩阵。在线性代数中,对称矩阵是一个方形矩阵,其转置矩阵和自身相等。1855年,埃米特(C.Hermite,1822-1901年)证明了别的数学家发现的一些矩阵类的特征根的特殊性质,如称为埃…...
EventWaitHandle 和 lock使用区别
EventWaitHandle 和 lock 语句在 C# 中都是用于线程同步的机制,但它们之间有着显著的区别和不同的使用场景。下面是它们之间的主要对比和区别: EventWaitHandle 定义:EventWaitHandle 是用于跨进程或跨线程同步的低级别同步原语。它允许一个…...
【图论】树链剖分
本篇博客参考: 【洛谷日报#17】树链剖分详解Oi Wiki 树链剖分 文章目录 基本概念代码实现常见应用路径维护:求树上两点路径权值和路径维护:改变两点最短路径上的所有点的权值求最近公共祖先 基本概念 首先,树链剖分是什么呢&…...
Requests教程-17-请求代理设置
上一小节我们学习了requests解决乱码的方法,本小节我们讲解一下requests设置代理的方法。 代理基本原理 代理实际上指的就是代理服务器, 英文叫作proxy server ,它的功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中…...
python内置函数 G
python内置函数 G Python 解释器内置了很多函数和类型,任何时候都能使用。 G 名称描述getattr从对象中获取属性值。globals返回当前全局符号表的字典。 getattr(object, name) getattr(object, name) getattr(object, name, default) getattr() 是 Python 中…...
深入了解 Spring boot的事务管理机制:掌握 Spring 事务的几种传播行为、隔离级别和回滚机制,理解 AOP 在事务管理中的应用
🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 &a…...
机械产品CE-MD认证测试项目介绍
机械产品CE-MD认证测试项目介绍 一、引言 随着欧洲市场的日益开放和全球化进程的加速,越来越多的机械产品进入欧洲市场。为确保这些产品的安全性和符合性,欧洲联盟(EU)引入了CE认证制度。同时,对于医疗器械类产品&…...
金融知识分享系列之:MACD指标精讲
金融知识分享系列之:MACD指标精讲 一、MACD指标二、指标原理三、MACD指标参考用法四、MACD计算步骤五、MACD分析要素六、根据快线DIF位置判断趋势七、金叉死叉作为多空信号八、快线位置交叉信号九、指标背离判断行情反转十、差离值的正负十一、差离值的变化十二、指…...
王道c语言-100元有几种换法
Description 一张面值100元的人民币换成10元、5元、2元和1元面值的票子。要求换正好40张,且每种票子至少一张。问:有几种换法? #include <stdio.h> int main() {int count 0;int i, j, t, k, ret 0;for (i 1; i < 37; i) {for …...
c++野指针如何处理?
什么是野指针? 野指针指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为NULL避免,而只能通过养成良好的编程习惯来尽力减少,对野指针进行操作很容易造成程序错误。 野指针产生…...
关于大根堆,set重载运算符
题目描述 \,\,\,\,\,\,\,\,\,\,制定合理的日程能够帮助利用好时间进行加训,加训和加训。 \,\,\,\,\,\,\,\,\,\,新学期开始了,应该好好学习了!凌晨两点整,加睡失败的你在为新一天的各项重要事件制定闹钟。 \,\,\,\,\,\,\,\,\,\, \,…...
Algae c++
描述 问题陈述 池塘中藻类的发展情况如下。 假设年初i水藻的总重量为xi克。对于 i≥2000,下列公式成立: xi1rxi−D 给你r、D和x2000。请依次计算 x2001、...、x2010 并打印出来。 输入描述 输入内容由标准输入法提供,格式…...
开发常用的一些工具总结
开发常用的一些工具总结 记录一些常用的开发软件. Android 开发相关 : Android studio 安卓开发者必备的编辑器,也是我用过最好用的编辑器.还可以用来写JNI 和C.Android studio 插件 : GsonFormatLeakCanary 其他 VS Code :轻量级的开发工具,插件非常多,很好用,但是上手难度…...
k8s Yaml语法解析
YAML是一个类似 XML、JSON 的标记性语言。它强调以数据为中心,并不是以标识语言为重点。因而YAML本身的定义比较简单,号称"一种人性化的数据格式语言"。 YAML的语法比较简单,主要有下面几个: 1、大小写敏感 2、使用缩进…...
【晴问算法】提高篇—动态规划专题—最长公共子序列
题目描述 现有两个字符串s1与s2,求s1与s2的最长公共子序列的长度(子序列可以不连续)。 输入描述 第一行为字符串s1,仅由小写字母组成,长度不超过100; 第一行为字符串s2…...
Greetings
Problem - 1915F - Codeforces 题意 给一些(l,r)找到所有能够包含(l,r)的数目 引入 也就是找逆序对个数 要用到归并排序中的思想: //https://www.luogu.com.cn/problem/P1216 #include<iostream> #include<cstdio> #include<stack> #include…...
JS03-函数
函数 使用函数 // 函数声明function sayHi(){document.write(Hello!<br>)}for(let i 1; i < 6; i){// 函数调用sayHi()}函数封装 function getScore(arr){sum 0for( let i 0; i < arr.length; i){sum arr[i]}document.write(sum)}getScore([99, 66, 100])函数…...
MySQL | CRUD
目录 1. Create 2. Retrieve 2.1. SELECT列 2.1.1. 全列查询 2.1.2. 指定列查询 2.1.3. 查询字段为表达式 2.1.4. 为查询结果指定别名 2.1.5. 结果去重 2.2. WHERE条件 2.2.1. 年龄小于19的同学 2.2.2. id在2~3的同学 2.2.3. id为1和4的同学 2.2.4. 姓张的同学及张…...
【电路笔记】-MOSFET作为开关
MOSFET 作为开关 文章目录 MOSFET 作为开关1、概述2、MOSFET特性曲线2.1 截住区域2.2 饱和区域3、MOSFET作为开关的示例4、功率MOSFET电机控制5、P沟道MOSFET作为开关6、互补MOSFET作为开关电机控制器当 MOSFET 在截止区和饱和区之间工作时,MOSFET 是非常好的电子开关,用于控…...
SpringBoot+Vue项目(Vue3环境搭建 + 基础页面)
文章目录 1.项目基本介绍2.安装Node.js(SSM部分安装过)3.初始化前端工程1.创建一个文件夹 springboot_vue2.创建vue项目1.在刚才创建的文件夹下打开命令行,使用脚手架搭建项目2.选择手动配置3.选择三个4.选择vue35.选择路由模式6.选择包管理方…...
elementui el-table表格自动循环滚动【超详细图解】
效果如图 1. 当表格内容超出时,自动滚动,滚动到最后一条之后在从头滚动。 2. 鼠标移入表格中,停止滚动;移出后,继续滚动。 直接贴代码 <template><div><div class"app-container"><e…...
关于学习的一点粗浅见解
我们学习的每一个领域,大多都有着宽泛的知识面,那在学习过程中,我们是应该一开始就专钻一个方向(即深度),还是应该先扩展知识面(即广度)?个人认为,应该先扩展知识面宽度,然后再精研某个方向&…...
[java基础揉碎]Object类详解
目录 equals方法: hashCode: toString: finalize: equals方法: 和equals对比 1.: 既可以判断基本类型,又可以判断引用类型 2.: 如果判断基本类型,判断的是值是否相等。示例: int i10; double d10.0; 3.:如果判断引用类型,判断的是地址是…...
23.1 微服务理论基础
23.1 微服务基础 1. 微服务介绍2. 微服务特点3. 微服务优缺点4. 微服务两大门派5. 微服务拆分6. 微服务扩展6.1 服务扩展6.2 按需扩展7. 微服务重要模块******************************************************************************************************************...
怎么做类似站酷的网站/seo精灵
分布式任务调度:XXL-JOB框架部署&使用&原理详解 1. 概述2. 部署2.1 拉取源码2.2 导入IDEA2.3 初始化数据库2.4 配置文件2.5 编译运行2.6 部署3. 使用3.1 xxljob-demo3.2 两种使用方式3.3 添加执行器3.4 测试4. XXL-JOB架构设计4.1 架构图4.2 工作原理<...
女生做网站编辑怎么样/新乡seo优化
1、打开设置 2、勾选编码格式,在这里可以设置分别设置IDE、Project、File等级别的编码格式。 3、查看、修改各个文件的编码 4、当右击编辑界面时,可以直接设置当前文件的编码 转载于:https://www.cnblogs.com/begin1949/p/4967140.html...
自助建站系统网站建设系统网站建设网站建设/企业软文怎么写
声明:本篇随笔来源于极客学院python学习之通过微信控制电脑,但内容不尽相同,实现的思想是面向过程,抛弃了许多东西。(如日志打印等,这里不作分析,有兴趣的读者可以去极客学院找教学视频看看&…...
2020网络游戏排行榜/关键词优化骗局
这篇文章主要介绍了Python如何计算语句执行时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下魔法命令In [1]:#%time 对单个语句执行时间计时用法放在需要计算的语句前面%time sum(range(1000))Wall time: 0 n…...
可以转app的网站怎么做的/推广软文范例100字
一、什么是快照 HDFS快照是文件系统的只读时间点副本。可以在文件系统的子树或整个文件系统上拍摄快照。快照的一些常见用例是数据备份,防止用户错误和灾难恢复。 二、使用快照的优势 官网解释: 快照创建是即时的:成本是O(1&#…...
wordpress 如何安装/小说关键词搜索器
点击上方入口立即【自由构建 探索无限】一起共赴年度科技盛宴!前言随着机器学习的不断发展和在各个行业的使用,很多企业已经从最初关注构建模型、算法选择到了现在如何构建自己的机器学习平台,在该平台上实现从数据处理、模型训练、模型部署和…...