采用多幅图像对线扫描摄像机进行标定

news/2024/6/16 22:59:54 标签: 机器视觉

1.1 应用示例目的与思路

(1) 创建一个HALCON相机标定数据模型;

(2) 在标定数据模型中设置相机的类型和初始参数;

(3) 在标定模型中定义标定对象;

(4) 遍历HALCON标定板图像,并在标定数据模型中设置提取的点和轮廓;

(5) 相机标定获取相机的内参和外参;

(6) 检验标定效果。①将图像坐标转换为世界坐标进行测量;②将图像映射到某一测量平面中进行测量;③将世界坐标中的点投影到图像中所对应的点进行测量。

1.2 应用示例相关算子介绍

(1) get_calib_data_observ_contours( : Contours : CalibDataID, ContourName, CameraIdx, CalibObjIdx, CalibObjPoseIdx : )

功能:从标定数据模型中提取轮廓。

图像输出参数:Contours:输出轮廓;

控制输入参数1:CalibDataID:标定数据模型句柄;

控制输入参数2:ContourName:待返回的轮廓对象的名称,Default value: 'marks':提取标定板所有标记点的轮廓,'caltab':提取标定板中心6个标记点的轮廓;

控制输入参数3:CameraIdx:摄像机索引,默认值为0;

控制输入参数4:CalibObjIdx:标定板索引,默认值0;

控制输入参数5:CalibObjPoseIdx:观察到的标定板位姿的索引。

(2) set_calib_data( : : CalibDataID, ItemType, ItemIdx, DataName, DataValue : )

功能:在标定数据模型中设置数据。

控制输入参数1:CalibDataID:标定数据模型句柄;

控制输入参数2:ItemType:标定数据项的类型;

控制输入参数3:ItemIdx:受影响项目的索引(取决于选定的ItemType);

控制输入参数4:DataName:要设置的参数名称,通过在DataName中选择相应参数,可以指定在calibrate_cameras()执行标定期间应优化哪些相机参数;

控制输入参数5:DataValue:要设置的参数值。

(3) sim_caltab( : SimImage : CalPlateDescr, CameraParam, CalPlatePose, GrayBackground, GrayPlate, GrayMarks, ScaleFac : )

功能:用于生成模拟标定图像。

图形输出参数:SimImage:生成的模拟标定图像;

控制输入参数1:CalPlateDescr:标定板描述文件;

控制输入参数2:CameraParam:相机内参;

控制输入参数3:CalPlatePose:相机外部参数;

控制输入参数4:GrayBackground:图像背景的灰度值;

控制输入参数5:GrayPlate:标定板灰度值;

控制输入参数6:GrayMarks:标定标记点灰度值;

控制输入参数7:ScaleFac:减少过采样的比例因子。

(4) pose_to_hom_mat3d( : : Pose : HomMat3D)

功能:将3D位姿转换为齐次变换矩阵。

控制输入参数:Pose:3D位姿;

控制输出参数:HomMat3D:等价齐次变换矩阵。

(5) affine_trans_point_3d( : : HomMat3D, Px, Py, Pz : Qx, Qy, Qz)

功能:对输入点(Px,Py,Pz)应用任意仿射3D变换,即缩放,旋转和平移,并在(Qx, Qy,Qz)中返回结果点。

控制输入参数1:HomMat3D:齐次变换矩阵;

控制输入参数2:(Px, Py, Pz):输入的点;

控制输出参数:(Qx, Qy, Qz):变换后的输出点。

(6) project_3d_point( : : X, Y, Z, CameraParam : Row, Column)

功能:将一个或多个3D点(坐标X, Y和Z)投影到图像平面(以像素为单位),并以行和列的形式返回结果。

控制输入参数1:(X, Y, Z):相机坐标系下的3D点(X, Y, Z),也就是说,它们描述了点相对于相机的位置;

控制输入参数2:CameraParam:相机内参;

控制输出参数:(Row, Column):图像平面上投影点的行列坐标。

(7) hom_mat3d_rotate_local( : : HomMat3D, Phi, Axis : HomMat3DRotate)

功能:向齐次三维变换矩阵添加旋转,并在HomMat3DRotate中返回结果矩阵。

控制输入参数1:HomMat3D:输入变换矩阵;

控制输入参数2:Phi:旋转角度;

控制输入参数3:Axis:围绕哪一个轴旋转;

控制输出参数:HomMat3DRotate: 输出的变换矩阵。

(8) hom_mat3d_translate_local( : : HomMat3D, Tx, Ty, Tz : HomMat3DTranslate)

功能:通过向量t = (Tx,Ty,Tz)向齐次3D变换矩阵HomMat3D中添加平移,并在HomMat3DTranslate中返回结果矩阵。

控制输入参数1:HomMat3D:输入变换矩阵;

控制输入参数2:Tx:沿着x轴的平移量;

控制输入参数3:Ty:沿着y轴的平移量;

控制输入参数4:Tz:沿着z轴的平移量;

控制输出参数:HomMat3DTranslate: 输出的变换矩阵。

(9) hom_mat3d_to_pose( : : HomMat3D : Pose)

功能:将齐次变换矩阵转换为3D位态。

控制输入参数:HomMat3D:齐次变换矩阵;

控制输出参数:Pose:等效的3D位态。

(10) contour_to_world_plane_xld(Contours : ContoursTrans : CameraParam, WorldPose, Scale : )

功能:将Contours中给出的轮廓点转换为世界坐标系中的z=0平面,并在ContoursTrans中返回3D轮廓点。

图形输入参数:Contours:输入的要在图像坐标中转换的XLD轮廓;

图形输出参数:ContoursTrans:转换的在世界坐标系下的XLD轮廓;

控制输入参数1:CameraParam:相机内参;

控制输入参数2:WorldPose:相机外参;

控制输入参数3:Scale:比例或尺寸,默认值:'m'。

(11) gen_image_to_world_plane_map( : Map : CameraParam, WorldPose, WidthIn, HeightIn, WidthMapped, HeightMapped, Scale, MapType : )

功能:生成一个投影图,描述图像平面与世界坐标系z=0的平面之间的映射。

图形输出参数:Map:包含映射信息的输出图像;

控制输入参数1:CameraParam:相机内参;

控制输入参数2:WorldPose:相机外参;

控制输入参数3:(WidthIn, HeightIn):要转换的图像的宽高;

控制输入参数4:(WidthMapped, HeightMapped):映射图像的宽高;

控制输入参数5:Scale:比例或单位;

控制输入参数6:MapType:映射类型。

(12) map_image(Image, Map : ImageMapped : : )

功能:对图像进行映射变换。

图形输入参数1:Image:待映射的输入图像;

图形输入参数2:Map:包含映射信息的图像;

图形输出参数:ImageMapped:映射变换后的图像。

(13) image_to_world_plane(Image : ImageWorld : CameraParam, WorldPose, Width, Height, Scale, Interpolation : )

功能:通过将图像转换为世界坐标系中的z=0平面(测量平面)来校正图像。

图形输入参数:Image:输入图像;

图形输出参数:ImageWorld:转换图像;

控制输入参数1:CameraParam:相机内参;

控制输入参数2:WorldPose:相机外参;

控制输入参数3:(Width, Height):结果图像的宽高;

控制输入参数4:Scale:比例或单位;

控制输入参数5:Interpolation:插值类型。

1.3 应用示例代码


*相关参数初始化
dev_close_window ()
NumCalibImages := 17
read_image (Image, './line_scan_calib_imgs/calib_line_scan_01')
get_image_size (Image, Width, Height)
OWFMaxExtent := 750
dev_open_window_fit_size (0, 0, Width, Height, OWFMaxExtent, OWFMaxExtent, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_color ('white')
*设置相机内参初始值
gen_cam_par_line_scan_division (0.06, 0, 10e-6, 10e-6, Width / 2.0, 0, Width, Height, 0, 5e-5, 0, StartCamParam)
*设置相关控制参数
CalTabDescrFile := 'caltab_30mm.descr'
FMAPAlpha := 0.5
DCScaleFac := 1
*创建相机标定模型
create_calib_data ('calibration_object', 1, 1, CalibDataID)
set_calib_data_cam_param (CalibDataID, 0, [], StartCamParam)
set_calib_data_calib_object (CalibDataID, 0, CalTabDescrFile)
*确定所有标定图像的标定标记和标定板的姿态,并将其添加到标定数据模型中。
for I := 1 to NumCalibImages by 1
    read_image (Image, 'calib/calib_line_scan_' + I$'02d')
    find_calib_object (Image, CalibDataID, 0, 0, I - 1, 'alpha', FMAPAlpha)
    get_calib_data (CalibDataID, 'camera', 0, 'init_params', StartCamPar)
    *对标定板外边缘和标记点的进行可视化
    get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, I - 1)
    dev_display (Image)
    dev_display (Caltab)
    get_calib_data_observ_points (CalibDataID, 0, 0, I - 1, Row, Column, Index, StartPose)
    disp_cross (WindowHandle, Row, Column, 20, 0)
    Message := 'The start pose of the          '
    Message[1] := 'calibration plate in image ' + I$'02d' + '  '
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
endfor
dev_clear_window ()
disp_message (WindowHandle, 'Please wait...', 'window', 12, 12, 'black', 'true')
*进行相机标定(默认情况下,所有相机参数都是通过相机标定来估计的)
calibrate_cameras (CalibDataID, Error)
*获取相机内参
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)
dev_clear_window ()
Message := ['Error of the','calibration = ' + Error$'.2f']
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*读取一个显示卡尺和标定板的测试图像
read_image (Image, './line_scan_calib_imgs/caliper_line_scan')
*首先,将先前确定的相机参数设置为模型中的新的初始参数
set_calib_data_cam_param (CalibDataID, 0, [], CamParam)
* 从优化中排除所有参数,仅估计校准板的姿态
set_calib_data (CalibDataID, 'camera', 'general', 'excluded_settings', 'all')
set_calib_data (CalibDataID, 'camera', 'general', 'calib_settings', 'pose')
find_calib_object (Image, CalibDataID, 0, 0, NumCalibImages, 'alpha', FMAPAlpha)
*获取未标定的测量位姿
get_calib_data_observ_points (CalibDataID, 0, 0, NumCalibImages, Row1, Column1, Index1, Pose)
calibrate_cameras (CalibDataID, ErrorPoseOnly)
*获取标定的测量位姿
get_calib_data (CalibDataID, 'calib_obj_pose', [0,NumCalibImages], 'pose', NFinalPose)
dev_display (Image)
get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, NumCalibImages)
dev_display (Caltab)
get_calib_data_observ_points (CalibDataID, 0, 0, I - 1, Row, Column, Index, StartPose)
disp_cross (WindowHandle, Row, Column, 20, 0)
Message := ['Error of the','calibration = ' + ErrorPoseOnly$'.2f']
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*生成标定板模拟图像
SCGrayBackground := 5
SCGrayCaltab := 120
SCGrayMarks := 15
SCScaleFac := 1
sim_caltab (SimImage, CalTabDescrFile, CamParam, NFinalPose, SCGrayBackground, SCGrayCaltab, SCGrayMarks, SCScaleFac)
dev_display (SimImage)
Message := ['Simulated image', 'of the calibration plate']
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*标定板没有直接放置在卡尺上,而是围绕其x轴倾斜约21.8度。
HMRLPhi := rad(21.8)
HMTLTx := 0
HMTLTy := 0
HMTLTz := 0.00673
pose_to_hom_mat3d (NFinalPose, HomMat3D)
hom_mat3d_rotate_local (HomMat3D, HMRLPhi, 'x', HomMat3D)
hom_mat3d_translate_local (HomMat3D, HMTLTx, HMTLTy, HMTLTz, HomMat3D)
hom_mat3d_to_pose (HomMat3D, PoseNewOrigin)
*现在,(1)可以将图像坐标转换为世界坐标,然后进行测量。
*首先,用测量对象确定螺距线的图像坐标。
if (true)
    Row := 1960
    Col := 1525
    Phi := 0.955
    Length1 := 840
    Length2 := 10
else
    dev_display (Image)
    draw_rectangle2 (WindowHandle, Row, Col, Phi, Length1, Length2)
endif
MPSigma := 1.5
MPThreshold := 3
MPTransition := 'negative'
MPSelect := 'all'
GCCXSize := 6
GCCXAngle := 0
gen_measure_rectangle2 (Row, Col, Phi, Length1, Length2, Width, Height, 'bilinear', MeasureHandle)
measure_pairs (Image, MeasureHandle, MPSigma, MPThreshold, MPTransition, MPSelect, RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance)
RowPitchLine := (RowEdgeFirst + RowEdgeSecond) / 2.0
ColPitchLine := (ColumnEdgeFirst + ColumnEdgeSecond) / 2.0
dev_display (Image)
gen_cross_contour_xld (Cross, RowPitchLine, ColPitchLine, GCCXSize, GCCXAngle)
dev_set_draw ('margin')
gen_rectangle2 (Rectangle, Row, Col, Phi, Length1, Length2)
dev_set_draw ('fill')
image_points_to_world_plane (CamParam, PoseNewOrigin, RowPitchLine, ColPitchLine, 'mm', X1, Y1)
*现在,计算刻度线之间的距离
distance_pp (Y1[0:|Y1| - 2], X1[0:|X1| - 2], Y1[1:|Y1| - 1], X1[1:|X1| - 1], Distance)
ErrorPitchLines := gen_tuple_const(|Distance|,1) - Distance
disp_message (WindowHandle, 'Mean distance = ' + mean(Distance)$'.5f' + ' mm', 'window', 12, 12, 'black', 'true')
Message := 'Error:'
Message[1] := '  Mean:        ' + (mean(ErrorPitchLines) * 1000)$'5.2f' + ' microns'
Message[2] := '  Max:         ' + max(fabs(ErrorPitchLines) * 1000)$'5.2f' + ' microns'
Message[3] := '  Deviation:   ' + (deviation(ErrorPitchLines) * 1000)$'5.2f' + ' microns'
disp_message (WindowHandle, Message, 'window', 37, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*(2)在映射到测量平面的图像中进行测量。
dev_clear_window ()
parameters_image_to_world_plane_entire (Image, CamParam, PoseNewOrigin, Width, Height, ScaleForEntireImage, PoseForEntireImage)
if (true)
    gen_image_to_world_plane_map (Map, CamParam, PoseForEntireImage, Width, Height, Width, Height, ScaleForEntireImage, 'bilinear')
    map_image (Image, Map, ImageMapped)
else
    image_to_world_plane (Image, ImageMapped, CamParam, PoseForEntireImage, Width, Height, ScaleForEntireImage, 'bilinear')
endif
if (true)
    Row := 1350
    Col := 790
    Phi := rad(90)
    Length1 := 465
    Length2 := 20
else
    dev_display (ImageMapped)
    draw_rectangle2 (WindowHandle, Row, Col, Phi, Length1, Length2)
endif
gen_measure_rectangle2 (Row, Col, Phi, Length1, Length2, Width, Height, 'bilinear', MeasureHandle)
measure_pairs (ImageMapped, MeasureHandle, MPSigma, MPThreshold, MPTransition, MPSelect, RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance)
RowPitchLine := (RowEdgeFirst + RowEdgeSecond) / 2.0
ColPitchLine := (ColumnEdgeFirst + ColumnEdgeSecond) / 2.0
dev_display (ImageMapped)
gen_cross_contour_xld (Cross, RowPitchLine, ColPitchLine, 6, 0)
dev_set_draw ('margin')
gen_rectangle2 (Rectangle, Row, Col, Phi, Length1, Length2)
dev_set_draw ('fill')
*现在,再一次计算刻度线之间的距离
distance_pp (RowPitchLine[0:|RowPitchLine| - 2], ColPitchLine[0:|ColPitchLine| - 2], RowPitchLine[1:|RowPitchLine| - 1], ColPitchLine[1:|ColPitchLine| - 1], Distance)
Distance := Distance * ScaleForEntireImage * 1000.0
ErrorPitchLines := gen_tuple_const(|Distance|,1) - Distance
disp_message (WindowHandle, 'Mean distance = ' + mean(Distance)$'.5f' + ' mm', 'window', 12 + 500, 12, 'black', 'true')
Message := 'Error:'
Message[1] := '   Mean:       ' + (mean(ErrorPitchLines) * 1000)$'5.2f' + ' microns'
Message[2] := '   Max:        ' + (max(fabs(ErrorPitchLines)) * 1000)$'5.2f' + ' microns'
Message[3] := '   Deviation   ' + (deviation(ErrorPitchLines) * 1000)$'5.2f' + ' microns'
disp_message (WindowHandle, Message, 'window', 37 + 500, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*(3)可以将从原始图像中提取的xld轮廓和点变换到测量平面中
ESPAlpha := 2
ESPLow := 20
ESPHigh := 40
SSXMin := 0.7
SSXMax := 1.0
FECXMaxNumPoints := -1
FECXMaxClosureDist := 0
FECXClippingEndPoints := 0
FECXVossTabSize := 200
FECXIterations := 3
FECXClippingFactor := 2
*从标定数据模型中读取轮廓。
get_calib_data_observ_contours (CaltabCont, CalibDataID, 'caltab', 0, 0, NumCalibImages)
gen_region_contour_xld (CaltabCont, Caltab, 'filled')
dev_clear_window ()
reduce_domain (Image, Caltab, ImageReduced)
edges_sub_pix (ImageReduced, Edges, 'canny', ESPAlpha, ESPLow, ESPHigh)
select_shape_xld (Edges, SelectedXLD, 'circularity', 'and', SSXMin, SSXMax)
fit_ellipse_contour_xld (SelectedXLD, 'fitzgibbon', FECXMaxNumPoints, FECXMaxClosureDist, FECXClippingEndPoints, FECXVossTabSize, FECXIterations, FECXClippingFactor, RowMark, ColMark, Phi1, Radius1, Radius2, StartPhi, EndPhi, PointOrder)
gen_cross_contour_xld (CrossMark, RowMark, ColMark, GCCXSize, GCCXAngle)
dev_display (ImageMapped)
contour_to_world_plane_xld (SelectedXLD, ContoursWorld, CamParam, PoseForEntireImage, ScaleForEntireImage)
image_points_to_world_plane (CamParam, PoseForEntireImage, RowMark, ColMark, ScaleForEntireImage, XMark, YMark)
gen_cross_contour_xld (CrossMarkWorld, YMark, XMark, GCCXSize, GCCXAngle)
disp_message (WindowHandle, 'Original image', 'window', 577, 12, 'black', 'true')
disp_message (WindowHandle, 'Mapped image', 'window', 12, 12, 'black', 'true')
disp_arrow (WindowHandle, 2700, 400, 650, 700, 10)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*(4)将世界坐标中的点投影到图像中所对应的点进行测量。
PITWPCCenterRow := 2500
PITWPCCenterCol := 1500
dev_clear_window ()
dev_display (ImageReduced)
dev_display (CrossMark)
parameters_image_to_world_plane_centered (CamParam, NFinalPose, PITWPCCenterRow, PITWPCCenterCol, Width, Height, ScaleForCenteredImage, PoseForCenteredImage)
*首先,将图像投影到校准板所在的平面上
image_to_world_plane (Image, ImageMappedCP, CamParam, PoseForCenteredImage, Width, Height, ScaleForCenteredImage, 'bilinear')
*然后,提取标定板标记
dev_set_color ('yellow')
find_calib_object (ImageMappedCP, CalibDataID, 0, 0, NumCalibImages + 1, 'alpha', FMAPAlpha)
get_calib_data_observ_contours (CaltabCont, CalibDataID, 'caltab', 0, 0, NumCalibImages + 1)
gen_region_contour_xld (CaltabCont, Caltab, 'filled')
reduce_domain (ImageMappedCP, Caltab, ImageReducedCP)
edges_sub_pix (ImageReducedCP, Edges, 'canny', ESPAlpha, ESPLow, ESPHigh)
select_shape_xld (Edges, ContoursWorld, 'circularity', 'and', SSXMin, SSXMax)
fit_circle_contour_xld (ContoursWorld, 'algebraic', FECXMaxNumPoints, FECXMaxClosureDist, FECXClippingEndPoints, FECXIterations, FECXClippingFactor, YMarkFromWorldContours, XMarkFromWorldContours, Radius, StartPhi1, EndPhi1, PointOrder1)
*并投影到行扫描图像中
pose_to_hom_mat3d (PoseForCenteredImage, HomMat3DForCenteredImage)
affine_trans_point_3d (HomMat3DForCenteredImage, XMarkFromWorldContours * ScaleForCenteredImage, YMarkFromWorldContours * ScaleForCenteredImage, gen_tuple_const(|XMarkFromWorldContours|,0), XCamMark, YCamMark, ZCamMark)
project_3d_point (XCamMark, YCamMark, ZCamMark, CamParam, RowMarkFromWorldContour, ColMarkFromWorldContour)
gen_cross_contour_xld (CrossMarkFromWorldContour, RowMarkFromWorldContour, ColMarkFromWorldContour, GCCXSize, GCCXAngle)
calc_min_distance_between_point_sets (RowMark, ColMark, RowMarkFromWorldContour, ColMarkFromWorldContour, DR, DC, D)
disp_message (WindowHandle, 'Mean distance = ' + mean(D)$'.3f' + ' pixel', 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'Original image', 'window', 530, 12, 'black', 'true')
disp_message (WindowHandle, 'Mapped image', 'window', 100, 12, 'black', 'true')
disp_arrow (WindowHandle, 1100, 1050, 2850, 550, 10)


http://www.niftyadmin.cn/n/5039760.html

相关文章

Automation Anywhere推出新的生成式AI自动化平台,加速提高企业生产力

在9 月 19 日的Imagine 2023 大会上,智能自动化领域的领导者 Automation Anywhere 宣布对其自动化平台进行扩展。推出了新的 Responsible AI Layer,并宣布了四项关键产品更新,包括全新的 Autopilot,它可以利用生成式 AI &#xff…

服务器的维护是如何操作

服务器的维护是如何操作 服务器可以说是不可或缺的资源,因为现在网络技术发达,我们的生活也都离不开网络的存在,我们想要获取的业务、资料等大多是通过网络进行,所以想要顺应潮流并获得发展,肯定需要服务器来将企业的相…

zabbix监控日志

目录 前言 一、zabbix (一)概述 (二)zabbix的优点 1、强大的功能和灵活的扩展性 2、高可靠性和可扩展性 3、全面的监控和告警功能 4、免费开源和活跃的社区支持 (三)zabbix的应用场景 1、IT基础设…

LeetCode 75 - 01 : 最小面积矩形

type pair struct{x, y int }func minAreaRect(points [][]int)int{mp : map[pair]struct{}{}// 将二维数组中的坐标映射到map中for i : range points{mp[pair{points[i][0], points[i][1]}] struct{}{}}// 将结果设置为一个最大值,防止影响求最小值的逻辑res : ma…

(c/c++)——STL

文章目录 一、迭代器(iterator)二、容器1、string2、Vector(最常用)3、list4、map5、unordered_map6、queue三、算法1、for_each2、find_if3、sort一、迭代器(iterator) 思考:模板的思想就是传迭代器。一个函数,如果传对象的地址或引用,那它只支持某种类型的容器;如…

3D模型格式转换工具HOOPS Exchange与iBase-t的Solumina集成:支持用户查询与编辑模型

iBase-t是一家软件公司,致力于简化复杂产品的构建和维护。iBase-t 于 1986 年在南加州成立,提供的解决方案可确保全球范围内制造、质量以及维护、修理和大修 (MRO) 运营的数字连续性。iBase-t 的 Solumina 制造运营平台是一种云原生解决方案,…

AcWing.第121场周赛

以下是acwing第121场比赛的abc三题 比赛地址 : 竞赛 - AcWing A. AcWing 5149. 简单计算 题目链接 : 5149. 简单计算 - AcWing题库 思路 : 直接模拟&#xff0c;用floor()函数来实现下取整 代码 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(…

提升利润的秘密武器:超好用的跨境电商系统源码推荐

在竞争激烈的电商市场中&#xff0c;提高利润是每个卖家的追求。而跨境电商系统源码成为了许多成功卖家的秘密武器。本文将揭示为什么选择跨境电商系统源码&#xff0c;以及它在利润提升方面的重要作用。 超好用的跨境电商系统源码推荐 如果你正在寻找一款功能强大、易于使用…