測量3D翼片的距離與角度

1,目的。

  • 測量3D翼片的距離與角度。
  • 說明:
    1. 標注A 紅色框選的區域即為翼片,本示例的3D 對象共有3個翼片待測。
    2. L1L2的距離、L1L2的角度即為所求的翼片距離與角度。
      在這里插入圖片描述

在這里插入圖片描述在這里插入圖片描述


2,原理。

  1. 使用線結構光模型(標定模式)獲取作為參考對象的 3D 點云,以及結構光模型默認的lightPlaneposemovementpose
  2. 使用三個光平面與 作為參考對象的 3D 點云對象相交,獲取光平面與 3D 對象的交集點云,將該交集點云投影到2D 平面形成輪廓。
  3. 篩選出所需的輪廓L1L2,求出3組 L1L2的距離均值,角度均值,將該值作為標準值。
  4. 使用結構光模型獲取被測的 3D 點云,并將該3D點云與參考對象的3D點云進行表面匹配獲取Pose。
  5. 對三個光平面進行剛體變化,保證光平面與被測的3D點云相切,獲取切平面。
  6. 對被測對象的切平面進行投影,篩選出輪廓,計算輪廓的距離與角度是否在規定的范圍內。

3,程序解析。

3.1,創建參考 3D 對象樣本。
* 參考案例庫:inspect_3d_surface_intersections.hdev* 目的:測量三個金屬薄片翅凸起的角度與距離*
* ------------Part01,建立參考 3D 對象樣本* 1.1,配置線性結構光模型。
* 模式為‘calibration’,該模式將生成默認的lightpanelpose與movementpose,如果缺省則這兩個位姿為空
NumDisparityProfiles := 441
read_image (DisparityProfile, 'sheet_of_light/metal_part_1_disparity_line_000')
create_sheet_of_light_model (DisparityProfile, 'calibration', 'offset_scale', SheetOfLightModelID)
* 設置校準方法‘offset_scale’的縮放因子
* 使得重建的三維物體模型近似給出
* 單位毫米
ScaleX := 1
ScaleY := 4
ScaleZ := 0.5
set_sheet_of_light_param (SheetOfLightModelID, 'scale_x', ScaleX)
set_sheet_of_light_param (SheetOfLightModelID, 'scale_y', ScaleY)
set_sheet_of_light_param (SheetOfLightModelID, 'scale_z', ScaleZ)
* 
* 1.2,定義物體背景 z 軸分界值
MinZ := 220
* 
* Initialize display
dev_update_off ()
set_system ('clip_region', 'false')
dev_close_window ()
get_image_size (DisparityProfile, DisparityProfileWidth, DisparityProfileHeight)
WindowEnlargement := 350
WindowWidth := DisparityProfileWidth + WindowEnlargement
WindowHeight := NumDisparityProfiles
dev_open_window (0, 0, WindowWidth, WindowHeight, 'black', WindowHandle)
dev_set_part (0, 0, WindowHeight - 1, WindowWidth - 1)
get_part (WindowHandle, PartRow1, PartColumn1, PartRow2, PartColumn2)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('fill')
* 
* 1.3,定義一些可視化參數
VisualizationPlaneSize := 150
VisualizationCamParam := [0.01,0,6e-6,6e-6,WindowWidth / 2,WindowHeight / 2,WindowWidth,WindowHeight]
VisualizationPose := [-1550,680,5390,122,1,357,0]
VisualizationColors := ['magenta','blue','orange']
* 
* 1.4,通過收集測量值來創建參考樣本
* 通過 線激光測量模型 將視差輪廓轉換為3D對象模型
gen_image_const (DisparityImageVis, 'uint2', DisparityProfileWidth, NumDisparityProfiles)
for Index := 0 to NumDisparityProfiles - 1 by 1* Add the next disparity profile to the sheet of light modelread_image (ImageModel, 'sheet_of_light/metal_part_1_disparity_line_' + Index$'03d')set_profile_sheet_of_light (ImageModel, SheetOfLightModelID, [])* Accumulated profiles for visualizationget_grayval (ImageModel, gen_tuple_const(DisparityProfileWidth,0), [0:DisparityProfileWidth - 1], Disparities)set_grayval (DisparityImageVis, gen_tuple_const(DisparityProfileWidth,Index), [0:DisparityProfileWidth - 1], Disparities)if (Index % 5 == 4)dev_display (DisparityImageVis)Message := 'Disparity image of the reference sample'Message[1] := 'Adding disparity profile ' + (Index + 1) + '/' + NumDisparityProfilesdisp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')endif
endfor* 1.5,顯示引用樣本的視差圖像
dev_display (DisparityImageVis)
stop ()
disp_message (WindowHandle, '引用樣本的視差圖', 'window', 12, 12, 'black', 'true')* 1.6,獲取標定測量的三維對象(參考樣本對象)
get_sheet_of_light_result_object_model_3d (SheetOfLightModelID, Model3DFull)* 最小外接長方體(min_x, min_y, min_z, max_x, max_y, max_z)。此屬性長度為 6。
get_object_model_3d_params (Model3DFull, 'bounding_box1', BoundingBox1)* 1.7,去除背景后的樣本 3D 對象
MaxZ := BoundingBox1[5]
select_points_object_model_3d (Model3DFull, 'point_coord_z', MinZ, MaxZ, Model3D)
clear_object_model_3d (Model3DFull)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Prepare the 3D object model for the intersection with
* the planes and to allow the alignment of the intersection
* planes to the objects to be inspected
dev_clear_window ()
dev_set_part (PartRow1, PartColumn1, PartRow2, PartColumn2)* 1.8,顯示去除背景后的 3D 引用
disp_object_model_3d (WindowHandle, Model3D, VisualizationCamParam, VisualizationPose, [], [])
Message := '準備參考模型'
Message[1] := ' - triangulate 3D object model and'
Message[2] := ' - create surface model for alignment'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')* 1.9,計算 3D 模型的法線,并將法線信息附加到輸入的模型
surface_normals_object_model_3d (Model3D, 'mls', 'mls_force_inwards', 'true', ObjectModel3DNormals)* 1.10,將離散的點數數據轉換為三角網格模型
triangulate_object_model_3d (ObjectModel3DNormals, 'greedy', 'greedy_remove_small_surfaces', 200, ObjectModel3DReference, Information)
clear_object_model_3d (Model3D)
clear_object_model_3d (ObjectModel3DNormals)

釋疑解析:

  1. surface_normals_object_model_3d (Model3D, 'mls', 'mls_force_inwards', 'true', ObjectModel3DNormals)

    用于計算3D物體模型的表面法線,具體參數解析如下:

    1. 核心功能:
      • 采用移動最小二乘法(MLS)計算3D點云數據的曲面法線
      • 輸出帶法線信息的3D對象模型(ObjectModel3DNormals)
    2. 關鍵參數說明:
      • Model3D:輸入3D點云模型句柄
      • 'mls':當前唯一支持的法線計算方法
      • mls_force_inwards':強制法線指向模型內部的控制參數
      • 'true':啟用上述強制內指功能
    3. 技術原理:
      通過MLS算法對每個點的k鄰域擬合曲面(平面或高階多項式),計算投影點的法線方向。當啟用mls_force_inwards時,系統會調整法線方向使其一致指向模型內部。

  2. triangulate_object_model_3d (ObjectModel3DNormals, 'greedy', 'greedy_remove_small_surfaces', 200, ObjectModel3DReference, Information)

    用于將3D點云數據轉換為三角網格模型,具體參數解析如下:

    1. 核心功能:
      • 采用貪心算法(greedy)進行曲面重建
      • 可移除表面積小于指定閾值的小面片
      • 輸出三角化后的3D模型(ObjectModel3DReference)和重建信息(Information)
    2. 關鍵參數說明:
      • ObjectModel3DNormals:輸入帶法線的3D模型句柄
      • 'greedy':指定使用貪心三角化算法
      • 'greedy_remove_small_surfaces':小面片過濾功能開關
      • 200:面積閾值(單位取決于輸入模型),小于該值的面片將被移除
    3. 技術特點:
      • 貪心算法通過迭代連接最近鄰點形成三角形,效率較高但可能丟失細節
      • 法線信息可提高重建準確性
      • 小面片過濾能有效去除噪聲和離群點

3.2,創建表面匹配模型,切平面位姿
*---------------------Part02,創建表面匹配模型,翼片的切平面位姿* 2.1,Create a surface model for alignment
create_surface_model (ObjectModel3DReference, 0.03, 'model_invert_normals', 'true', SurfaceModelID)
* 
* 2.2,定義與翼片相切的位姿,平面
create_pose (300, 230, 250, -90, 0, 0, 'Rp+T', 'gba', 'point', PoseIntersectionPlane1)
create_pose (300, 900, 250, -90, 0, 0, 'Rp+T', 'gba', 'point', PoseIntersectionPlane2)
create_pose (300, 1570, 250, -90, 0, 0, 'Rp+T', 'gba', 'point', PoseIntersectionPlane3)
gen_plane_object_model_3d (PoseIntersectionPlane1, [-1,-1,1,1] * VisualizationPlaneSize, [-1,1,1,-1] * VisualizationPlaneSize, IntersectionPlane1)
gen_plane_object_model_3d (PoseIntersectionPlane2, [-1,-1,1,1] * VisualizationPlaneSize, [-1,1,1,-1] * VisualizationPlaneSize, IntersectionPlane2)
gen_plane_object_model_3d (PoseIntersectionPlane3, [-1,-1,1,1] * VisualizationPlaneSize, [-1,1,1,-1] * VisualizationPlaneSize, IntersectionPlane3)
dev_clear_window ()
dev_set_part (PartRow1, PartColumn1, PartRow2, PartColumn2)* 2.3,顯示樣本 3D 對象與與之相切的切平面
disp_object_model_3d (WindowHandle, [ObjectModel3DReference,IntersectionPlane1,IntersectionPlane2,IntersectionPlane3],VisualizationCamParam,VisualizationPose, ['color_1','color_2','color_3','alpha','alpha_0','disp_pose'], [VisualizationColors,0.75,1,'true'])
Message := 'Reference sample with predefined intersection planes'
* 正則表達式替換
MessageWrapped := regexp_replace(Message + ' ',['(.{0,25})\\s','replace_all'],'$1\n')
disp_message (WindowHandle, MessageWrapped, 'window', 12, 12, 'black', 'true'

顯示效果:

在這里插入圖片描述

3.3,計算 樣本 翼片組的距離均值與角度均值(重點)
* ----------------------Part03,計算 樣本 翼片組的距離與角度,推導出距離與角度的標準值* 3.1,獲取樣本 3D 對象切平面的點云
intersect_plane_object_model_3d (ObjectModel3DReference, PoseIntersectionPlane1, ObjectModel3DIntersection1)
intersect_plane_object_model_3d (ObjectModel3DReference, PoseIntersectionPlane2, ObjectModel3DIntersection2)
intersect_plane_object_model_3d (ObjectModel3DReference, PoseIntersectionPlane3, ObjectModel3DIntersection3)
* 
* 3.2,投影翼片切平面點云獲取切平面XLD輪廓
project_object_model_3d_lines_to_contour_xld (Intersection1, PoseIntersectionPlane1, ObjectModel3DIntersection1)
project_object_model_3d_lines_to_contour_xld (Intersection2, PoseIntersectionPlane2, ObjectModel3DIntersection2)
project_object_model_3d_lines_to_contour_xld (Intersection3, PoseIntersectionPlane3, ObjectModel3DIntersection3)
* 
* Clean up memory
clear_object_model_3d ([ObjectModel3DIntersection1,ObjectModel3DIntersection2,ObjectModel3DIntersection3])
* 
* 3.3,篩選提取旋轉角度為20±15的輪廓
OrientationRef := 20
OrientationTolerance := 15* 3.4,分析計算表示翼片的輪廓之間距離與角度
* Intersection1,投影出來的翼片輪廓; FittedLines1:擬合的翼片上線下線輪廓
analyze_intersection (Intersection1, FittedLines1, OrientationRef, OrientationTolerance, MinDistance1, MaxDistance1, Angle1)
analyze_intersection (Intersection2, FittedLines2, OrientationRef, OrientationTolerance, MinDistance2, MaxDistance2, Angle2)
analyze_intersection (Intersection3, FittedLines3, OrientationRef, OrientationTolerance, MinDistance3, MaxDistance3, Angle3)
* 
* Visualize the object with the intersection planes and the respective
* intersections and measurement results
hom_mat2d_identity (HomMat2DIdentity)* 3.5 ,顯示測量結果
Message := 'Intersections with measurement lines'
MessageWrapped := regexp_replace(Message + ' ',['(.{0,20})\\s','replace_all'],'$1\n')
disp_message (WindowHandle, MessageWrapped, 'window', 12, 330, 'black', 'true')
Message := 'Measurement results'
MessageWrapped := regexp_replace(Message + ' ',['(.{0,20})\\s','replace_all'],'$1\n')
disp_message (WindowHandle, MessageWrapped, 'window', 12, 590, 'black', 'true')* 顯示第1個翼片測量數據
hom_mat2d_translate (HomMat2DIdentity, 350, 390, HomMat2DTranslate1)
* 仿射變化相交的輪廓
affine_trans_contour_xld (Intersection1, Intersection1Vis, HomMat2DTranslate1)
* 仿射變化作為上線與下線的輪廓
affine_trans_contour_xld (FittedLines1, FittedLines1Vis, HomMat2DTranslate1)
dev_set_color (VisualizationColors[0])
dev_set_line_width (5)
dev_display (Intersection1Vis)
dev_set_color ('white')
dev_set_line_width (1)
dev_display (FittedLines1Vis)
Message := 'Angle        = ' + Angle1$'.1f' + ' deg'
Message[1] := 'Min Distance = ' + MinDistance1$'.1f' + ' mm'
Message[2] := 'Max Distance = ' + MaxDistance1$'.1f' + ' mm'
disp_message (WindowHandle, Message, 'window', 310, 600, VisualizationColors[0], 'false')* 顯示第2個翼片測量數據
hom_mat2d_translate (HomMat2DIdentity, 250, 410, HomMat2DTranslate2)
affine_trans_contour_xld (Intersection2, Intersection2Vis, HomMat2DTranslate2)
affine_trans_contour_xld (FittedLines2, FittedLines2Vis, HomMat2DTranslate2)
dev_set_color (VisualizationColors[1])
dev_set_line_width (5)
dev_display (Intersection2Vis)
dev_set_color ('white')
dev_set_line_width (1)
dev_display (FittedLines2Vis)
Message := 'Angle        = ' + Angle2$'.1f' + ' deg'
Message[1] := 'Min Distance = ' + MinDistance2$'.1f' + ' mm'
Message[2] := 'Max Distance = ' + MaxDistance2$'.1f' + ' mm'
disp_message (WindowHandle, Message, 'window', 210, 600, VisualizationColors[1], 'false')* 顯示第3個翼片測量數據
hom_mat2d_translate (HomMat2DIdentity, 150, 430, HomMat2DTranslate3)
affine_trans_contour_xld (Intersection3, Intersection3Vis, HomMat2DTranslate3)
affine_trans_contour_xld (FittedLines3, FittedLines3Vis, HomMat2DTranslate3)
dev_set_color (VisualizationColors[2])
dev_set_line_width (5)
dev_display (Intersection3Vis)
dev_set_color ('white')
dev_set_line_width (1)
dev_display (FittedLines3Vis)
Message := 'Angle        = ' + Angle3$'.1f' + ' deg'
Message[1] := 'Min Distance = ' + MinDistance3$'.1f' + ' mm'
Message[2] := 'Max Distance = ' + MaxDistance3$'.1f' + ' mm'
disp_message (WindowHandle, Message, 'window', 110, 600, VisualizationColors[2], 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* 3.6,根據樣本三個翼片測量結果,推導出的標準參數* ======推導出的翼片標準參數
AngleRef := mean([Angle1,Angle2,Angle3])
* 角度的容差范圍
MaxAngleDev := 2
* 許可的最小角度值
MinAngle := AngleRef - MaxAngleDev
* 許可的最大角度
MaxAngle := AngleRef + MaxAngleDev
* 許可的最大距離
MinDistance := 0.95 * mean([MinDistance1,MinDistance2,MinDistance3])
* 許可的最小距離
MaxDistance := 1.05 * mean([MaxDistance1,MaxDistance2,MaxDistance3])
* Display the nominal dimensions and the tolerance limits
dev_clear_window ()
Message := 'Tolerance limits for the angle and the distance of the mounting tabs, derived from the three measurements on the reference sample:'
MessageWrapped := regexp_replace(Message + ' ',['(.{0,75})\\s','replace_all'],'$1\n')
Message := MessageWrapped
Message[1] := ' '
Message[2] := 'Min Angle    = ' + MinAngle$'.1f' + ' deg'
Message[3] := 'Max Angle    = ' + MaxAngle$'.1f' + ' deg'
Message[4] := ' '
Message[5] := 'Min Distance = ' + MinDistance$'.1f' + ' mm'
Message[6] := 'Max Distance = ' + MaxDistance$'.1f' + ' mm'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*======================

效果圖:

在這里插入圖片描述

在這里插入圖片描述


本地函數:

1,project_object_model_3d_lines_to_contour_xld

作用: 將 3D對象 投影為xld輪廓。

* PoseIntersectionPlane:切平面在世界坐標系的位姿
* PoseInvert:在切平面位置有一個虛擬相機,這個就是這個虛擬相機的位姿(外參)
* 也就是世界坐標系在虛擬相機的相機坐標系的位姿
pose_invert (PoseIntersectionPlane, PoseInvert)* 確保投影平面在虛擬的正前方
* 獲取三維對象模型沿坐標軸對齊的包圍盒的對角線長度,即包圍盒的直徑。
* 因為虛擬相機和切平面點云重合所有為了投影成像需要將該虛擬相機沿z軸進行偏移
get_object_model_3d_params (ObjectModel3DIntersection, 'diameter_axis_aligned_bounding_box', Diameter)PoseInvert[2] := PoseInvert[2] + Diameter* 3,虛擬相機的內參。
*========================
* 相機內參參數組成:*Focus:相機的焦距,如果是遠心相機,則焦距為0*Kappa:畸變系數,初始值可以設置為0*Sx、Sy:單個像元的寬,高(可從相機說明書中獲取)*Cx、Cy:圖像的原點坐標,初始值可認為是圖像的中心點,即坐標分為為圖像的寬度和高度的一半*ImageWidth,ImageHeight:采集圖像的寬和高*===========================
* Focus:=0:表示虛擬相機無透視縮放僅為平行投影
* 虛擬相機不需要畸變所以 Kappa:=0;
*  Sx,Sy:=1,不進行縮放按照原圖大小輸出
* 使用平行投影來實現所需的縮放(默認為1:1)
* CamParam為虛擬相機的內參
Scale := 1
CamParam := [0,0,1.0 / Scale,1.0 / Scale,0,0,512,512]
* 4,投影獲取xld輪廓。
project_object_model_3d (Intersection, ObjectModel3DIntersection, CamParam, PoseInvert, 'data', 'lines')
return ()

釋疑解惑:

為什么需要PoseInvert[2] := PoseInvert[2] + Diameter?

  • 避免物體遮擋投影?
    • 當投影平面與物體位置重疊時,投影結果可能因?物體自身遮擋?而丟失部分幾何信息。例如,若投影平面位于物體內部,部分表面會被遮擋,導致輪廓線殘缺。
    • 通過沿z軸正方向平移投影平面(如代碼中 PoseInvert[2] += Diameter),可使投影平面位于物體包圍盒之外,從而完整捕捉物體的可見邊界。
  • 平行投影的幾何精度保障
    • 平行投影需保持嚴格的比例關系(如默認1:1縮放)。若投影平面與物體距離過近,可能導致?坐標溢出或畸變?,尤其在物體跨越坐標系原點時。
    • 平移后,投影平面與物體間形成安全距離(通常為包圍盒直徑),確保物體所有頂點坐標均位于相機視錐體內,避免裁剪錯誤。
  • ?三維坐標系變換的物理意義
    • 位姿逆變換 pose_invert 將物體從世界坐標系轉換到投影平面坐標系。此時投影平面默認位于新坐標系的?原點?(即原平面位置),可能導致投影平面與物體空間重疊。
    • 沿z軸平移可理解為將投影平面從“觀察者視角的原點”移至“觀察者前方”,符合人類視覺感知習慣。
  • 正交投影的規范化需求?
    • 規范化坐標系要求投影范圍限定在合理區間(如[-1,1])。若投影平面距離過近,物體坐標可能超出該范圍,導致投影結果失真或不可控。
    • 調整z軸位置可對物體坐標進行歸一化處理,滿足圖形API(如OpenGL/Direct3D)的標準化視口要求。

運算獲取的輪廓Intersection示例:

在這里插入圖片描述

2,analyze_intersection

作用: 篩選符合條件的輪廓片段,對符合條件的輪廓片段進行擬合,計算彼此間的距離、角度。

* selected and grouped.
* 
* Cut the contour into segments
segment_contours_xld (Intersection, ContoursSplit, 'lines_circles', 7, 3, 2)
* Select the segments that have approximately the expected orientation
select_shape_xld (ContoursSplit, SelectedXLD, ['orientation_points','orientation_points'], 'or', rad([OrientationRef,OrientationRef - 180]) - rad(OrientationTolerance), rad([OrientationRef,OrientationRef - 180]) + rad(OrientationTolerance))
* Select the three longest segments
length_xld (SelectedXLD, Length)
SelectedId := sort_index(-Length)[0:2] + 1
* 最長的片段
select_obj (SelectedXLD, ObjectSelected1, SelectedId[0])
* 第2長的片段
select_obj (SelectedXLD, ObjectSelected2, SelectedId[1])
* 第3長的片段
select_obj (SelectedXLD, ObjectSelected3, SelectedId[2])
* 計算三個片段的兩兩距離
* to decide, which of them represents the mounting tab
distance_cc_min (ObjectSelected1, ObjectSelected2, 'fast_point_to_segment', DistanceMin12)
distance_cc_min (ObjectSelected1, ObjectSelected3, 'fast_point_to_segment', DistanceMin13)
distance_cc_min (ObjectSelected2, ObjectSelected3, 'fast_point_to_segment', DistanceMin23)
* 兩兩距離最大的 距離索引
LargestDistId := sort_index(-[DistanceMin12,DistanceMin13,DistanceMin23])[0]
switch (LargestDistId)
case 0:* 片段1 與 片段2 的距離是最大時:concat_obj (ObjectSelected1, ObjectSelected2, GroundPlane)copy_obj (ObjectSelected3, MountingTab, 1, 1)break
case 1:* 片段1 與 片段3 的距離是最大時:concat_obj (ObjectSelected1, ObjectSelected3, GroundPlane)copy_obj (ObjectSelected2, MountingTab, 1, 1)break
case 2:*片段2 與 片段3 的距離是最大時:concat_obj (ObjectSelected2, ObjectSelected3, GroundPlane)copy_obj (ObjectSelected1, MountingTab, 1, 1)break
endswitch
* 
* 兩個片段距離最大時,則認為這兩個片段延長線是共線(翼片底線)
union_adjacent_contours_xld (GroundPlane, GroundPlaneUnion, 1000, 50, 'attr_keep')
* 擬合翼片底線
fit_line_contour_xld (GroundPlaneUnion, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
if (ColEnd < ColBegin)* Reverse the orientation of the lineT := ColEndColEnd := ColBeginColBegin := TT := RowEndRowEnd := RowBeginRowBegin := TNr := -NrNc := -Nc
endif
* 計算出的上線
gen_contour_polygon_xld (Contour, [RowBegin,RowEnd], [ColBegin,ColEnd])
*  MoutingTab 是與 另外兩個共線的片段 不共線的片段
fit_line_contour_xld (MountingTab, 'tukey', -1, 0, 5, 2, RowBeginMT, ColBeginMT, RowEndMT, ColEndMT, NrMT, NcMT, DistMT)
if (ColEndMT < ColBeginMT)* Reverse the orientation of the lineT := ColEndMTColEndMT := ColBeginMTColBeginMT := TT := RowEndMTRowEndMT := RowBeginMTRowBeginMT := TNrMT := -NrMTNcMT := -NcMT
endif
* 計算出的下線
gen_contour_polygon_xld (ContourMT, [RowBeginMT,RowEndMT], [ColBeginMT,ColEndMT])
* 連接上線 與 下線
concat_obj (ContourMT, Contour, FittedLines)
* 
* Calculate the opening width and the angle
distance_pl ([RowBeginMT,RowEndMT], [ColBeginMT,ColEndMT], RowBegin, ColBegin, RowEnd, ColEnd, Distances)
MinDistance := min(Distances)
MaxDistance := max(Distances)
* 上線法向量與下線法向量的夾角
angle_ll (0, 0, NrMT, NcMT, 0, 0, Nr, Nc, AngleRad)
Angle := deg(AngleRad)
* Wrap the absolute angle to 90 deg or less
if (Angle < -90)Angle := Angle + 180
elseif (Angle > 90)Angle := Angle - 180
endif
* 
return ()

釋疑解惑:

select_shape_xld算子使用orientationorientation_points作為篩選特征時,有何差異?

  • 計算原理差異?
特征orientation參數orientation_points參數
?幾何基礎?基于等效橢圓主軸方向或外接矩形方向計算基于離散點集擬合主方向(類似點云處理)
?輪廓依賴性?依賴輪廓順序和幾何完整性忽略輪廓順序,僅分析點集分布
?自相交兼容性?僅適用于非自交輪廓支持自相交輪廓
  • 參數行為差異?
    1. ?角度范圍處理?
      • orientation返回-π/2 < Phi ≤ π/2,需通過OrientationRef - 180覆蓋所有方向
      • orientation_points返回-π ≤ Phi < π,直接支持全角度范圍判斷
    2. ?篩選邏輯實現?
    * orientation版本(非自交輪廓適用)
    select_shape_xld(ContoursSplit, SelectedXLD, ['orientation','orientation'], 'or', rad([OrientationRef,OrientationRef-180])-rad(OrientationTolerance),rad([OrientationRef,OrientationRef-180])+rad(OrientationTolerance)) :ml-citation{ref="3" data="citationList"}* orientation_points版本(自交輪廓適用)
    select_shape_xld(ContoursSplit, SelectedXLD, ['orientation_points','orientation_points'], 'or',rad([OrientationRef,OrientationRef-180])-rad(OrientationTolerance),rad([OrientationRef,OrientationRef-180])+rad(OrientationTolerance)) :ml-citation{ref="3" data="citationList"}
    
    注:兩者均通過'or'邏輯合并OrientationRefOrientationRef-180的容忍區間,但底層計算方式不同
  • 應用場景對比?
場景推薦參數原因
?規則幾何體篩選?orientation依賴幾何主軸方向,結果更穩定(如矩形零件方向檢測)
?自交輪廓處理?orientation_points避免因輪廓自交導致方向誤判(如復雜多邊形或點云數據)
?抗噪需求高?orientation_points對離散點噪聲更魯棒(需配合test_self_intersection_xld檢測)
  • 返回值驗證建議?
    1. 使用test_self_intersection_xld檢測輪廓自交性
    2. 自交輪廓優先選擇orientation_points,否則使用orientation
    3. 通過get_shape_xld算子驗證實際返回的角度值范圍是否符合預期

本地函數運行效果:

在這里插入圖片描述

3.4,對被測 3D 對象進行測量
* --------------------------Part 4:對點云對象進行測量
*           
* 
* Inspection loop
NumScenes := 4* 4.1,通過線結構光模型獲取待測的 3D 對象
for SceneIndex := 1 to NumScenes by 1dev_clear_window ()dev_set_part (PartRow1, PartColumn1, PartRow2, PartColumn2)* Reset 線結構光測量模型的 視差圖 ; 所有其他設置都可以重用reset_sheet_of_light_model (SheetOfLightModelID)* * Create the test object by collecting the measured* disparity profiles in a sheet-of-light model and* transforming them to a 3D object modelgen_image_const (DisparityImageVis, 'uint2', DisparityProfileWidth, NumDisparityProfiles)for Index := 0 to NumDisparityProfiles - 1 by 1* Add the next disparity profile to the sheet of light modelread_image (ImageSearch, 'sheet_of_light/metal_part_' + (SceneIndex + 1) + '_disparity_line_' + Index$'03d')set_profile_sheet_of_light (ImageSearch, SheetOfLightModelID, [])* Accumulated profiles for visualizationget_grayval (ImageSearch, gen_tuple_const(DisparityProfileWidth,0), [0:DisparityProfileWidth - 1], Disparities)set_grayval (DisparityImageVis, gen_tuple_const(DisparityProfileWidth,Index), [0:DisparityProfileWidth - 1], Disparities)if (Index % 5 == 4 or Index == (NumDisparityProfiles - 1))dev_display (DisparityImageVis)Message := 'Disparity image of test object ' + SceneIndexMessage[1] := 'Adding disparity profile ' + (Index + 1) + '/' + NumDisparityProfilesdisp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')endifendfor* Get the 3D reconstruction of the test object and eliminate* the background from the respective 3D object modelget_sheet_of_light_result_object_model_3d (SheetOfLightModelID, Scene3DFull)* 4.2,去除被測 3D對像的背景*  最小外接長方體(min_x, min_y, min_z, max_x, max_y, max_z)。此屬性長度為 6。get_object_model_3d_params (Scene3DFull, 'bounding_box1', BoundingBox1)MaxZ := BoundingBox1[5]* 去除背景后的 3D 點云select_points_object_model_3d (Scene3DFull, 'point_coord_z', MinZ, MaxZ, Scene3D)clear_object_model_3d (Scene3DFull)* * Align the intersection planes to the actual position and orientation* of the test object and prepare the test object for the intersectiondev_clear_window ()dev_set_part (PartRow1, PartColumn1, PartRow2, PartColumn2)disp_object_model_3d (WindowHandle, Scene3D, VisualizationCamParam, VisualizationPose, [], [])Message := 'Prepare the 3D object model of the test object'Message[1] := ' - perform surface based matching for alignment'Message[2] := ' - triangulate 3D object model'disp_message (WindowHandle, Message[0], 'window', 12, 12, 'black', 'true')* * Match the test object with the reference sample.* Note that the RelSamplingDistance has been set fairly small.* This is necessary because the object has only little 3D variations* that can be used by the matching process.disp_message (WindowHandle, Message[0:1], 'window', 12, 12, 'black', 'true')* 4.3,表面匹配,查找到參考對象相對于被測對象的位姿find_surface_model (SurfaceModelID, Scene3D, 0.005, 0.2, 0, 'false', [], [], Pose, Score, SurfaceMatchingResultID)* 4.4,將 相交平面 與 測試對象 進行對齊rigid_trans_object_model_3d (IntersectionPlane1, Pose, IntersectionPlane1Aligned)rigid_trans_object_model_3d (IntersectionPlane2, Pose, IntersectionPlane2Aligned)rigid_trans_object_model_3d (IntersectionPlane3, Pose, IntersectionPlane3Aligned)get_object_model_3d_params (IntersectionPlane1Aligned, 'primitive_parameter_pose', IntersectionPlane1AlignedPose)get_object_model_3d_params (IntersectionPlane2Aligned, 'primitive_parameter_pose', IntersectionPlane2AlignedPose)get_object_model_3d_params (IntersectionPlane3Aligned, 'primitive_parameter_pose', IntersectionPlane3AlignedPose)* 三角網格化 3D object modeldisp_message (WindowHandle, Message[0:2], 'window', 12, 12, 'black', 'true')triangulate_object_model_3d (Scene3D, 'greedy', [], [], Scene3DTest, Information)dev_clear_window ()disp_object_model_3d (WindowHandle, [Scene3DTest,IntersectionPlane1Aligned,IntersectionPlane2Aligned,IntersectionPlane3Aligned], VisualizationCamParam, VisualizationPose, ['color_1','color_2','color_3','alpha','alpha_0'], [VisualizationColors,0.75,1])Message := 'Test object ' + SceneIndex + ' with aligned intersection planes'MessageWrapped := regexp_replace(Message + ' ',['(.{0,25})\\s','replace_all'],'$1\n')disp_message (WindowHandle, MessageWrapped, 'window', 12, 12, 'black', 'true')* * 4.5 投影獲取被測 3D 翼片的切平面xld輪廓intersect_plane_object_model_3d (Scene3DTest, IntersectionPlane1AlignedPose, ObjectModel3DIntersection1)intersect_plane_object_model_3d (Scene3DTest, IntersectionPlane2AlignedPose, ObjectModel3DIntersection2)intersect_plane_object_model_3d (Scene3DTest, IntersectionPlane3AlignedPose, ObjectModel3DIntersection3)* * project_object_model_3d_lines_to_contour_xld (Intersection1, IntersectionPlane1AlignedPose, ObjectModel3DIntersection1)project_object_model_3d_lines_to_contour_xld (Intersection2, IntersectionPlane2AlignedPose, ObjectModel3DIntersection2)project_object_model_3d_lines_to_contour_xld (Intersection3, IntersectionPlane3AlignedPose, ObjectModel3DIntersection3)* * Clean up memoryclear_object_model_3d ([ObjectModel3DIntersection1,ObjectModel3DIntersection2,ObjectModel3DIntersection3])clear_object_model_3d ([IntersectionPlane1Aligned,IntersectionPlane2Aligned,IntersectionPlane3Aligned])clear_object_model_3d ([Scene3D,Scene3DTest])* * 4.6,分析擬合計算表示翼片上下線輪廓片段的角度與距離analyze_intersection (Intersection1, FittedLines1, OrientationRef, OrientationTolerance, MinDistance1, MaxDistance1, Angle1)analyze_intersection (Intersection2, FittedLines2, OrientationRef, OrientationTolerance, MinDistance2, MaxDistance2, Angle2)analyze_intersection (Intersection3, FittedLines3, OrientationRef, OrientationTolerance, MinDistance3, MaxDistance3, Angle3)* * 4.7,顯示被測3D 對象的測量結果OverallCheckPassed := trueMessage := 'Intersections with measurement lines'MessageWrapped := regexp_replace(Message + ' ',['(.{0,20})\\s','replace_all'],'$1\n')disp_message (WindowHandle, MessageWrapped, 'window', 12, 310, 'black', 'true')Message := 'Measurement results'MessageWrapped := regexp_replace(Message + ' ',['(.{0,20})\\s','replace_all'],'$1\n')disp_message (WindowHandle, MessageWrapped, 'window', 12, 590, 'black', 'true')* 顯示第1個翼片測量結果affine_trans_contour_xld (Intersection1, Intersection1Vis, HomMat2DTranslate1)affine_trans_contour_xld (FittedLines1, FittedLines1Vis, HomMat2DTranslate1)dev_set_color (VisualizationColors[0])dev_set_line_width (5)dev_display (Intersection1Vis)dev_set_color ('white')dev_set_line_width (1)dev_display (FittedLines1Vis)Message := 'Angle        = ' + Angle1$'.1f' + ' deg'Message[1] := 'Min Distance = ' + MinDistance1$'.1f' + ' mm'Message[2] := 'Max Distance = ' + MaxDistance1$'.1f' + ' mm'disp_message (WindowHandle, Message, 'window', 310, 600, VisualizationColors[0], 'false')ErrorIndicator := gen_tuple_const(3,'OK')ErrorIndicatorColor := gen_tuple_const(3,'dim gray')* 注意[<]與< 的區別:* [<]用于?兩個數組(元組)? 的逐元素比較,返回一個?布爾值數組* < 單個數值比較,返回一個布爾值if (Angle1 [<] MinAngle or Angle1 [>] MaxAngle)ErrorIndicator[0] := 'NOK'ErrorIndicatorColor[0] := 'red'OverallCheckPassed := falseendifif (MinDistance1 [<] MinDistance)ErrorIndicator[1] := 'NOK'ErrorIndicatorColor[1] := 'red'OverallCheckPassed := falseendifif (MaxDistance1 [>] MaxDistance)ErrorIndicator[2] := 'NOK'ErrorIndicatorColor[2] := 'red'OverallCheckPassed := falseendifdisp_message (WindowHandle, ErrorIndicator, 'window', 310, 880, ErrorIndicatorColor, 'false')* 第2個翼片測量數據affine_trans_contour_xld (Intersection2, Intersection2Vis, HomMat2DTranslate2)affine_trans_contour_xld (FittedLines2, FittedLines2Vis, HomMat2DTranslate2)dev_set_color (VisualizationColors[1])dev_set_line_width (5)dev_display (Intersection2Vis)dev_set_color ('white')dev_set_line_width (1)dev_display (FittedLines2Vis)Message := 'Angle        = ' + Angle2$'.1f' + ' deg'Message[1] := 'Min Distance = ' + MinDistance2$'.1f' + ' mm'Message[2] := 'Max Distance = ' + MaxDistance2$'.1f' + ' mm'disp_message (WindowHandle, Message, 'window', 210, 600, VisualizationColors[1], 'false')ErrorIndicator := gen_tuple_const(3,'OK')ErrorIndicatorColor := gen_tuple_const(3,'dim gray')if (Angle2 [<] MinAngle or Angle2 [>] MaxAngle)ErrorIndicator[0] := 'NOK'ErrorIndicatorColor[0] := 'red'OverallCheckPassed := falseendifif (MinDistance2 [<] MinDistance)ErrorIndicator[1] := 'NOK'ErrorIndicatorColor[1] := 'red'OverallCheckPassed := falseendifif (MaxDistance2 [>] MaxDistance)ErrorIndicator[2] := 'NOK'ErrorIndicatorColor[2] := 'red'OverallCheckPassed := falseendifdisp_message (WindowHandle, ErrorIndicator, 'window', 210, 880, ErrorIndicatorColor, 'false')* 第3個翼片測量數據affine_trans_contour_xld (Intersection3, Intersection3Vis, HomMat2DTranslate3)affine_trans_contour_xld (FittedLines3, FittedLines3Vis, HomMat2DTranslate3)dev_set_color (VisualizationColors[2])dev_set_line_width (5)dev_display (Intersection3Vis)dev_set_color ('white')dev_set_line_width (1)dev_display (FittedLines3Vis)Message := 'Angle        = ' + Angle3$'.1f' + ' deg'Message[1] := 'Min Distance = ' + MinDistance3$'.1f' + ' mm'Message[2] := 'Max Distance = ' + MaxDistance3$'.1f' + ' mm'disp_message (WindowHandle, Message, 'window', 110, 600, VisualizationColors[2], 'false')ErrorIndicator := gen_tuple_const(3,'OK')ErrorIndicatorColor := gen_tuple_const(3,'dim gray')if (Angle3 [<] MinAngle or Angle3 [>] MaxAngle)ErrorIndicator[0] := 'NOK'ErrorIndicatorColor[0] := 'red'OverallCheckPassed := falseendifif (MinDistance3 [<] MinDistance)ErrorIndicator[1] := 'NOK'ErrorIndicatorColor[1] := 'red'OverallCheckPassed := falseendifif (MaxDistance3 [>] MaxDistance)ErrorIndicator[2] := 'NOK'ErrorIndicatorColor[2] := 'red'OverallCheckPassed := falseendifdisp_message (WindowHandle, ErrorIndicator, 'window', 110, 880, ErrorIndicatorColor, 'false')* * 4.8,顯示整體測量結果if (OverallCheckPassed)dev_set_color ('green')gen_rectangle1 (Rectangle, 0, WindowWidth - 120, 80, WindowWidth)dev_display (Rectangle)disp_message (WindowHandle, 'OK', 'window', 30, 900, 'black', 'false')elsedev_set_color ('red')gen_rectangle1 (Rectangle, 0, WindowWidth - 120, 80, WindowWidth)dev_display (Rectangle)disp_message (WindowHandle, 'NOK', 'window', 30, 900, 'white', 'false')endifif (SceneIndex < NumScenes)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif
endfor

釋疑解惑:

兩個比較操作 [<] 與 < 有什么區別?

  • 操作對象與返回值差異?

    • ? <(單值比較)
      用于?單個數值?的比較,返回一個?布爾值?(true/false)。
      示例:
    Result := (5 < 10)  // 返回 true
    
    • [<](數組元素級比較)
      用于?兩個數組(元組)? 的逐元素比較,返回一個?布爾值數組?。
      示例:
    A := [1, 2, 3]
    B := [3, 2, 1]
    Result := A [<] B  // 返回 [true, false, false]
    

該部分運行效果:

在這里插入圖片描述
在這里插入圖片描述


4,完整代碼。

* 參考案例庫:inspect_3d_surface_intersections.hdev* 目的:測量三個金屬薄片翅凸起的角度與距離*
* ------------Part01,建立參考 3D 對象樣本* 1.1,配置線性結構光模型。
* 模式為‘calibration’,該模式將生成默認的lightpanelpose與movementpose,如果缺省則這兩個位姿為空
NumDisparityProfiles := 441
read_image (DisparityProfile, 'sheet_of_light/metal_part_1_disparity_line_000')
create_sheet_of_light_model (DisparityProfile, 'calibration', 'offset_scale', SheetOfLightModelID)
* 設置校準方法‘offset_scale’的縮放因子
* 使得重建的三維物體模型近似給出
* 單位毫米
ScaleX := 1
ScaleY := 4
ScaleZ := 0.5
set_sheet_of_light_param (SheetOfLightModelID, 'scale_x', ScaleX)
set_sheet_of_light_param (SheetOfLightModelID, 'scale_y', ScaleY)
set_sheet_of_light_param (SheetOfLightModelID, 'scale_z', ScaleZ)
* 
* 1.2,定義物體可以被分離的背景 z 軸坐標
MinZ := 220
* 
* Initialize display
dev_update_off ()
set_system ('clip_region', 'false')
dev_close_window ()
get_image_size (DisparityProfile, DisparityProfileWidth, DisparityProfileHeight)
WindowEnlargement := 350
WindowWidth := DisparityProfileWidth + WindowEnlargement
WindowHeight := NumDisparityProfiles
dev_open_window (0, 0, WindowWidth, WindowHeight, 'black', WindowHandle)
dev_set_part (0, 0, WindowHeight - 1, WindowWidth - 1)
get_part (WindowHandle, PartRow1, PartColumn1, PartRow2, PartColumn2)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('fill')
* 
* 1.3,定義一些可視化參數
VisualizationPlaneSize := 150
VisualizationCamParam := [0.01,0,6e-6,6e-6,WindowWidth / 2,WindowHeight / 2,WindowWidth,WindowHeight]
VisualizationPose := [-1550,680,5390,122,1,357,0]
VisualizationColors := ['magenta','blue','orange']
* 
* 1.4,通過收集測量值來創建參考樣本
* 通過 線激光測量模型 將視差輪廓轉換為3D對象模型
gen_image_const (DisparityImageVis, 'uint2', DisparityProfileWidth, NumDisparityProfiles)
for Index := 0 to NumDisparityProfiles - 1 by 1* Add the next disparity profile to the sheet of light modelread_image (ImageModel, 'sheet_of_light/metal_part_1_disparity_line_' + Index$'03d')set_profile_sheet_of_light (ImageModel, SheetOfLightModelID, [])* Accumulated profiles for visualizationget_grayval (ImageModel, gen_tuple_const(DisparityProfileWidth,0), [0:DisparityProfileWidth - 1], Disparities)set_grayval (DisparityImageVis, gen_tuple_const(DisparityProfileWidth,Index), [0:DisparityProfileWidth - 1], Disparities)if (Index % 5 == 4)dev_display (DisparityImageVis)Message := 'Disparity image of the reference sample'Message[1] := 'Adding disparity profile ' + (Index + 1) + '/' + NumDisparityProfilesdisp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')endif
endfor* 1.5,顯示引用樣本的視差圖像
dev_display (DisparityImageVis)
stop ()
disp_message (WindowHandle, '引用樣本的視差圖', 'window', 12, 12, 'black', 'true')* 1.6,獲取標定測量的三維對象(參考樣本對象)
get_sheet_of_light_result_object_model_3d (SheetOfLightModelID, Model3DFull)* 最小外接長方體(min_x, min_y, min_z, max_x, max_y, max_z)。此屬性長度為 6。
get_object_model_3d_params (Model3DFull, 'bounding_box1', BoundingBox1)* 1.7,去除背景后的樣本 3D 對象
MaxZ := BoundingBox1[5]
select_points_object_model_3d (Model3DFull, 'point_coord_z', MinZ, MaxZ, Model3D)
clear_object_model_3d (Model3DFull)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Prepare the 3D object model for the intersection with
* the planes and to allow the alignment of the intersection
* planes to the objects to be inspected
dev_clear_window ()
dev_set_part (PartRow1, PartColumn1, PartRow2, PartColumn2)* 1.8,顯示去除背景后的 3D 引用
disp_object_model_3d (WindowHandle, Model3D, VisualizationCamParam, VisualizationPose, [], [])
Message := '準備參考模型'
Message[1] := ' - triangulate 3D object model and'
Message[2] := ' - create surface model for alignment'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')* 1.9,計算 3D 模型的法線,并將法線信息附加到輸入的模型
surface_normals_object_model_3d (Model3D, 'mls', 'mls_force_inwards', 'true', ObjectModel3DNormals)* 1.10,將離散的點數數據轉換為三角網格模型
triangulate_object_model_3d (ObjectModel3DNormals, 'greedy', 'greedy_remove_small_surfaces', 200, ObjectModel3DReference, Information)
clear_object_model_3d (Model3D)
clear_object_model_3d (ObjectModel3DNormals)*---------------------Part02,創建表面匹配模型,翼片的切平面位姿* 2.1,Create a surface model for alignment
create_surface_model (ObjectModel3DReference, 0.03, 'model_invert_normals', 'true', SurfaceModelID)
* 
* 2.2,定義與翼片相切的位姿,平面
create_pose (300, 230, 250, -90, 0, 0, 'Rp+T', 'gba', 'point', PoseIntersectionPlane1)
create_pose (300, 900, 250, -90, 0, 0, 'Rp+T', 'gba', 'point', PoseIntersectionPlane2)
create_pose (300, 1570, 250, -90, 0, 0, 'Rp+T', 'gba', 'point', PoseIntersectionPlane3)
gen_plane_object_model_3d (PoseIntersectionPlane1, [-1,-1,1,1] * VisualizationPlaneSize, [-1,1,1,-1] * VisualizationPlaneSize, IntersectionPlane1)
gen_plane_object_model_3d (PoseIntersectionPlane2, [-1,-1,1,1] * VisualizationPlaneSize, [-1,1,1,-1] * VisualizationPlaneSize, IntersectionPlane2)
gen_plane_object_model_3d (PoseIntersectionPlane3, [-1,-1,1,1] * VisualizationPlaneSize, [-1,1,1,-1] * VisualizationPlaneSize, IntersectionPlane3)
dev_clear_window ()
dev_set_part (PartRow1, PartColumn1, PartRow2, PartColumn2)* 2.3,顯示樣本 3D 對象與與之相切的切平面
disp_object_model_3d (WindowHandle, [ObjectModel3DReference,IntersectionPlane1,IntersectionPlane2,IntersectionPlane3],VisualizationCamParam,VisualizationPose, ['color_1','color_2','color_3','alpha','alpha_0','disp_pose'], [VisualizationColors,0.75,1,'true'])
Message := 'Reference sample with predefined intersection planes'
* 正則表達式替換
MessageWrapped := regexp_replace(Message + ' ',['(.{0,25})\\s','replace_all'],'$1\n')
disp_message (WindowHandle, MessageWrapped, 'window', 12, 12, 'black', 'true')
* * ----------------------Part03,計算 樣本 翼片組的距離與角度,推導出距離與角度的標準值* 3.1,獲取樣本 3D 對象切平面的點云
intersect_plane_object_model_3d (ObjectModel3DReference, PoseIntersectionPlane1, ObjectModel3DIntersection1)
intersect_plane_object_model_3d (ObjectModel3DReference, PoseIntersectionPlane2, ObjectModel3DIntersection2)
intersect_plane_object_model_3d (ObjectModel3DReference, PoseIntersectionPlane3, ObjectModel3DIntersection3)
* 
* 3.2,投影翼片切平面點云獲取切平面XLD輪廓
project_object_model_3d_lines_to_contour_xld (Intersection1, PoseIntersectionPlane1, ObjectModel3DIntersection1)
project_object_model_3d_lines_to_contour_xld (Intersection2, PoseIntersectionPlane2, ObjectModel3DIntersection2)
project_object_model_3d_lines_to_contour_xld (Intersection3, PoseIntersectionPlane3, ObjectModel3DIntersection3)
* 
* Clean up memory
clear_object_model_3d ([ObjectModel3DIntersection1,ObjectModel3DIntersection2,ObjectModel3DIntersection3])
* 
* 3.3,篩選提取旋轉角度為20±15的輪廓
OrientationRef := 20
OrientationTolerance := 15* 3.4,分析計算表示翼片的輪廓之間距離與角度
* Intersection1,投影出來的翼片輪廓; FittedLines1:擬合的翼片上線下線輪廓
analyze_intersection (Intersection1, FittedLines1, OrientationRef, OrientationTolerance, MinDistance1, MaxDistance1, Angle1)
analyze_intersection (Intersection2, FittedLines2, OrientationRef, OrientationTolerance, MinDistance2, MaxDistance2, Angle2)
analyze_intersection (Intersection3, FittedLines3, OrientationRef, OrientationTolerance, MinDistance3, MaxDistance3, Angle3)
* 
* Visualize the object with the intersection planes and the respective
* intersections and measurement results
hom_mat2d_identity (HomMat2DIdentity)* 3.5 ,顯示測量結果
Message := 'Intersections with measurement lines'
MessageWrapped := regexp_replace(Message + ' ',['(.{0,20})\\s','replace_all'],'$1\n')
disp_message (WindowHandle, MessageWrapped, 'window', 12, 330, 'black', 'true')
Message := 'Measurement results'
MessageWrapped := regexp_replace(Message + ' ',['(.{0,20})\\s','replace_all'],'$1\n')
disp_message (WindowHandle, MessageWrapped, 'window', 12, 590, 'black', 'true')* 顯示第1個翼片測量數據
hom_mat2d_translate (HomMat2DIdentity, 350, 390, HomMat2DTranslate1)
* 仿射變化相交的輪廓
affine_trans_contour_xld (Intersection1, Intersection1Vis, HomMat2DTranslate1)
* 仿射變化作為上線與下線的輪廓
affine_trans_contour_xld (FittedLines1, FittedLines1Vis, HomMat2DTranslate1)
dev_set_color (VisualizationColors[0])
dev_set_line_width (5)
dev_display (Intersection1Vis)
dev_set_color ('white')
dev_set_line_width (1)
dev_display (FittedLines1Vis)
Message := 'Angle        = ' + Angle1$'.1f' + ' deg'
Message[1] := 'Min Distance = ' + MinDistance1$'.1f' + ' mm'
Message[2] := 'Max Distance = ' + MaxDistance1$'.1f' + ' mm'
disp_message (WindowHandle, Message, 'window', 310, 600, VisualizationColors[0], 'false')* 顯示第2個翼片測量數據
hom_mat2d_translate (HomMat2DIdentity, 250, 410, HomMat2DTranslate2)
affine_trans_contour_xld (Intersection2, Intersection2Vis, HomMat2DTranslate2)
affine_trans_contour_xld (FittedLines2, FittedLines2Vis, HomMat2DTranslate2)
dev_set_color (VisualizationColors[1])
dev_set_line_width (5)
dev_display (Intersection2Vis)
dev_set_color ('white')
dev_set_line_width (1)
dev_display (FittedLines2Vis)
Message := 'Angle        = ' + Angle2$'.1f' + ' deg'
Message[1] := 'Min Distance = ' + MinDistance2$'.1f' + ' mm'
Message[2] := 'Max Distance = ' + MaxDistance2$'.1f' + ' mm'
disp_message (WindowHandle, Message, 'window', 210, 600, VisualizationColors[1], 'false')* 顯示第3個翼片測量數據
hom_mat2d_translate (HomMat2DIdentity, 150, 430, HomMat2DTranslate3)
affine_trans_contour_xld (Intersection3, Intersection3Vis, HomMat2DTranslate3)
affine_trans_contour_xld (FittedLines3, FittedLines3Vis, HomMat2DTranslate3)
dev_set_color (VisualizationColors[2])
dev_set_line_width (5)
dev_display (Intersection3Vis)
dev_set_color ('white')
dev_set_line_width (1)
dev_display (FittedLines3Vis)
Message := 'Angle        = ' + Angle3$'.1f' + ' deg'
Message[1] := 'Min Distance = ' + MinDistance3$'.1f' + ' mm'
Message[2] := 'Max Distance = ' + MaxDistance3$'.1f' + ' mm'
disp_message (WindowHandle, Message, 'window', 110, 600, VisualizationColors[2], 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* 3.6,根據樣本三個翼片測量結果,推導出的標準參數* ======推導出的翼片標準參數
AngleRef := mean([Angle1,Angle2,Angle3])
* 角度的容差范圍
MaxAngleDev := 2
* 許可的最小角度值
MinAngle := AngleRef - MaxAngleDev
* 許可的最大角度
MaxAngle := AngleRef + MaxAngleDev
* 許可的最大距離
MinDistance := 0.95 * mean([MinDistance1,MinDistance2,MinDistance3])
* 許可的最小距離
MaxDistance := 1.05 * mean([MaxDistance1,MaxDistance2,MaxDistance3])
* Display the nominal dimensions and the tolerance limits
dev_clear_window ()
Message := 'Tolerance limits for the angle and the distance of the mounting tabs, derived from the three measurements on the reference sample:'
MessageWrapped := regexp_replace(Message + ' ',['(.{0,75})\\s','replace_all'],'$1\n')
Message := MessageWrapped
Message[1] := ' '
Message[2] := 'Min Angle    = ' + MinAngle$'.1f' + ' deg'
Message[3] := 'Max Angle    = ' + MaxAngle$'.1f' + ' deg'
Message[4] := ' '
Message[5] := 'Min Distance = ' + MinDistance$'.1f' + ' mm'
Message[6] := 'Max Distance = ' + MaxDistance$'.1f' + ' mm'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*======================
* 
* 
* --------------------------Part 4:對點云對象進行測量
*           
* 
* Inspection loop
NumScenes := 4* 4.1,通過線結構光模型獲取待測的 3D 對象
for SceneIndex := 1 to NumScenes by 1dev_clear_window ()dev_set_part (PartRow1, PartColumn1, PartRow2, PartColumn2)* Reset 線結構光測量模型的 視差圖 ; 所有其他設置都可以重用reset_sheet_of_light_model (SheetOfLightModelID)* * Create the test object by collecting the measured* disparity profiles in a sheet-of-light model and* transforming them to a 3D object modelgen_image_const (DisparityImageVis, 'uint2', DisparityProfileWidth, NumDisparityProfiles)for Index := 0 to NumDisparityProfiles - 1 by 1* Add the next disparity profile to the sheet of light modelread_image (ImageSearch, 'sheet_of_light/metal_part_' + (SceneIndex + 1) + '_disparity_line_' + Index$'03d')set_profile_sheet_of_light (ImageSearch, SheetOfLightModelID, [])* Accumulated profiles for visualizationget_grayval (ImageSearch, gen_tuple_const(DisparityProfileWidth,0), [0:DisparityProfileWidth - 1], Disparities)set_grayval (DisparityImageVis, gen_tuple_const(DisparityProfileWidth,Index), [0:DisparityProfileWidth - 1], Disparities)if (Index % 5 == 4 or Index == (NumDisparityProfiles - 1))dev_display (DisparityImageVis)Message := 'Disparity image of test object ' + SceneIndexMessage[1] := 'Adding disparity profile ' + (Index + 1) + '/' + NumDisparityProfilesdisp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')endifendfor* Get the 3D reconstruction of the test object and eliminate* the background from the respective 3D object modelget_sheet_of_light_result_object_model_3d (SheetOfLightModelID, Scene3DFull)* 4.2,去除被測 3D對像的背景*  最小外接長方體(min_x, min_y, min_z, max_x, max_y, max_z)。此屬性長度為 6。get_object_model_3d_params (Scene3DFull, 'bounding_box1', BoundingBox1)MaxZ := BoundingBox1[5]* 去除背景后的 3D 點云select_points_object_model_3d (Scene3DFull, 'point_coord_z', MinZ, MaxZ, Scene3D)clear_object_model_3d (Scene3DFull)* * Align the intersection planes to the actual position and orientation* of the test object and prepare the test object for the intersectiondev_clear_window ()dev_set_part (PartRow1, PartColumn1, PartRow2, PartColumn2)disp_object_model_3d (WindowHandle, Scene3D, VisualizationCamParam, VisualizationPose, [], [])Message := 'Prepare the 3D object model of the test object'Message[1] := ' - perform surface based matching for alignment'Message[2] := ' - triangulate 3D object model'disp_message (WindowHandle, Message[0], 'window', 12, 12, 'black', 'true')* * Match the test object with the reference sample.* Note that the RelSamplingDistance has been set fairly small.* This is necessary because the object has only little 3D variations* that can be used by the matching process.disp_message (WindowHandle, Message[0:1], 'window', 12, 12, 'black', 'true')* 4.3,表面匹配,查找到參考對象相對于被測對象的位姿find_surface_model (SurfaceModelID, Scene3D, 0.005, 0.2, 0, 'false', [], [], Pose, Score, SurfaceMatchingResultID)* 4.4,將 相交平面 與 測試對象 進行對齊rigid_trans_object_model_3d (IntersectionPlane1, Pose, IntersectionPlane1Aligned)rigid_trans_object_model_3d (IntersectionPlane2, Pose, IntersectionPlane2Aligned)rigid_trans_object_model_3d (IntersectionPlane3, Pose, IntersectionPlane3Aligned)get_object_model_3d_params (IntersectionPlane1Aligned, 'primitive_parameter_pose', IntersectionPlane1AlignedPose)get_object_model_3d_params (IntersectionPlane2Aligned, 'primitive_parameter_pose', IntersectionPlane2AlignedPose)get_object_model_3d_params (IntersectionPlane3Aligned, 'primitive_parameter_pose', IntersectionPlane3AlignedPose)* 三角網格化 3D object modeldisp_message (WindowHandle, Message[0:2], 'window', 12, 12, 'black', 'true')triangulate_object_model_3d (Scene3D, 'greedy', [], [], Scene3DTest, Information)dev_clear_window ()disp_object_model_3d (WindowHandle, [Scene3DTest,IntersectionPlane1Aligned,IntersectionPlane2Aligned,IntersectionPlane3Aligned], VisualizationCamParam, VisualizationPose, ['color_1','color_2','color_3','alpha','alpha_0'], [VisualizationColors,0.75,1])Message := 'Test object ' + SceneIndex + ' with aligned intersection planes'MessageWrapped := regexp_replace(Message + ' ',['(.{0,25})\\s','replace_all'],'$1\n')disp_message (WindowHandle, MessageWrapped, 'window', 12, 12, 'black', 'true')* * 4.5 投影獲取被測 3D 翼片的切平面xld輪廓intersect_plane_object_model_3d (Scene3DTest, IntersectionPlane1AlignedPose, ObjectModel3DIntersection1)intersect_plane_object_model_3d (Scene3DTest, IntersectionPlane2AlignedPose, ObjectModel3DIntersection2)intersect_plane_object_model_3d (Scene3DTest, IntersectionPlane3AlignedPose, ObjectModel3DIntersection3)* * project_object_model_3d_lines_to_contour_xld (Intersection1, IntersectionPlane1AlignedPose, ObjectModel3DIntersection1)project_object_model_3d_lines_to_contour_xld (Intersection2, IntersectionPlane2AlignedPose, ObjectModel3DIntersection2)project_object_model_3d_lines_to_contour_xld (Intersection3, IntersectionPlane3AlignedPose, ObjectModel3DIntersection3)* * Clean up memoryclear_object_model_3d ([ObjectModel3DIntersection1,ObjectModel3DIntersection2,ObjectModel3DIntersection3])clear_object_model_3d ([IntersectionPlane1Aligned,IntersectionPlane2Aligned,IntersectionPlane3Aligned])clear_object_model_3d ([Scene3D,Scene3DTest])* * 4.6,分析擬合計算表示翼片上下線輪廓片段的角度與距離analyze_intersection (Intersection1, FittedLines1, OrientationRef, OrientationTolerance, MinDistance1, MaxDistance1, Angle1)analyze_intersection (Intersection2, FittedLines2, OrientationRef, OrientationTolerance, MinDistance2, MaxDistance2, Angle2)analyze_intersection (Intersection3, FittedLines3, OrientationRef, OrientationTolerance, MinDistance3, MaxDistance3, Angle3)* * 4.7,顯示被測3D 對象的測量結果OverallCheckPassed := trueMessage := 'Intersections with measurement lines'MessageWrapped := regexp_replace(Message + ' ',['(.{0,20})\\s','replace_all'],'$1\n')disp_message (WindowHandle, MessageWrapped, 'window', 12, 310, 'black', 'true')Message := 'Measurement results'MessageWrapped := regexp_replace(Message + ' ',['(.{0,20})\\s','replace_all'],'$1\n')disp_message (WindowHandle, MessageWrapped, 'window', 12, 590, 'black', 'true')* 顯示第1個翼片測量結果affine_trans_contour_xld (Intersection1, Intersection1Vis, HomMat2DTranslate1)affine_trans_contour_xld (FittedLines1, FittedLines1Vis, HomMat2DTranslate1)dev_set_color (VisualizationColors[0])dev_set_line_width (5)dev_display (Intersection1Vis)dev_set_color ('white')dev_set_line_width (1)dev_display (FittedLines1Vis)Message := 'Angle        = ' + Angle1$'.1f' + ' deg'Message[1] := 'Min Distance = ' + MinDistance1$'.1f' + ' mm'Message[2] := 'Max Distance = ' + MaxDistance1$'.1f' + ' mm'disp_message (WindowHandle, Message, 'window', 310, 600, VisualizationColors[0], 'false')ErrorIndicator := gen_tuple_const(3,'OK')ErrorIndicatorColor := gen_tuple_const(3,'dim gray')* 注意[<]與< 的區別:* [<]用于?兩個數組(元組)? 的逐元素比較,返回一個?布爾值數組* < 單個數值比較,返回一個布爾值if (Angle1 [<] MinAngle or Angle1 [>] MaxAngle)ErrorIndicator[0] := 'NOK'ErrorIndicatorColor[0] := 'red'OverallCheckPassed := falseendifif (MinDistance1 [<] MinDistance)ErrorIndicator[1] := 'NOK'ErrorIndicatorColor[1] := 'red'OverallCheckPassed := falseendifif (MaxDistance1 [>] MaxDistance)ErrorIndicator[2] := 'NOK'ErrorIndicatorColor[2] := 'red'OverallCheckPassed := falseendifdisp_message (WindowHandle, ErrorIndicator, 'window', 310, 880, ErrorIndicatorColor, 'false')* 第2個翼片測量數據affine_trans_contour_xld (Intersection2, Intersection2Vis, HomMat2DTranslate2)affine_trans_contour_xld (FittedLines2, FittedLines2Vis, HomMat2DTranslate2)dev_set_color (VisualizationColors[1])dev_set_line_width (5)dev_display (Intersection2Vis)dev_set_color ('white')dev_set_line_width (1)dev_display (FittedLines2Vis)Message := 'Angle        = ' + Angle2$'.1f' + ' deg'Message[1] := 'Min Distance = ' + MinDistance2$'.1f' + ' mm'Message[2] := 'Max Distance = ' + MaxDistance2$'.1f' + ' mm'disp_message (WindowHandle, Message, 'window', 210, 600, VisualizationColors[1], 'false')ErrorIndicator := gen_tuple_const(3,'OK')ErrorIndicatorColor := gen_tuple_const(3,'dim gray')if (Angle2 [<] MinAngle or Angle2 [>] MaxAngle)ErrorIndicator[0] := 'NOK'ErrorIndicatorColor[0] := 'red'OverallCheckPassed := falseendifif (MinDistance2 [<] MinDistance)ErrorIndicator[1] := 'NOK'ErrorIndicatorColor[1] := 'red'OverallCheckPassed := falseendifif (MaxDistance2 [>] MaxDistance)ErrorIndicator[2] := 'NOK'ErrorIndicatorColor[2] := 'red'OverallCheckPassed := falseendifdisp_message (WindowHandle, ErrorIndicator, 'window', 210, 880, ErrorIndicatorColor, 'false')* 第3個翼片測量數據affine_trans_contour_xld (Intersection3, Intersection3Vis, HomMat2DTranslate3)affine_trans_contour_xld (FittedLines3, FittedLines3Vis, HomMat2DTranslate3)dev_set_color (VisualizationColors[2])dev_set_line_width (5)dev_display (Intersection3Vis)dev_set_color ('white')dev_set_line_width (1)dev_display (FittedLines3Vis)Message := 'Angle        = ' + Angle3$'.1f' + ' deg'Message[1] := 'Min Distance = ' + MinDistance3$'.1f' + ' mm'Message[2] := 'Max Distance = ' + MaxDistance3$'.1f' + ' mm'disp_message (WindowHandle, Message, 'window', 110, 600, VisualizationColors[2], 'false')ErrorIndicator := gen_tuple_const(3,'OK')ErrorIndicatorColor := gen_tuple_const(3,'dim gray')if (Angle3 [<] MinAngle or Angle3 [>] MaxAngle)ErrorIndicator[0] := 'NOK'ErrorIndicatorColor[0] := 'red'OverallCheckPassed := falseendifif (MinDistance3 [<] MinDistance)ErrorIndicator[1] := 'NOK'ErrorIndicatorColor[1] := 'red'OverallCheckPassed := falseendifif (MaxDistance3 [>] MaxDistance)ErrorIndicator[2] := 'NOK'ErrorIndicatorColor[2] := 'red'OverallCheckPassed := falseendifdisp_message (WindowHandle, ErrorIndicator, 'window', 110, 880, ErrorIndicatorColor, 'false')* * 4.8,顯示整體測量結果if (OverallCheckPassed)dev_set_color ('green')gen_rectangle1 (Rectangle, 0, WindowWidth - 120, 80, WindowWidth)dev_display (Rectangle)disp_message (WindowHandle, 'OK', 'window', 30, 900, 'black', 'false')elsedev_set_color ('red')gen_rectangle1 (Rectangle, 0, WindowWidth - 120, 80, WindowWidth)dev_display (Rectangle)disp_message (WindowHandle, 'NOK', 'window', 30, 900, 'white', 'false')endifif (SceneIndex < NumScenes)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif
endfor
* Clean up memory
clear_object_model_3d ([ObjectModel3DReference,IntersectionPlane1,IntersectionPlane2,IntersectionPlane3])
clear_sheet_of_light_model (SheetOfLightModelID)
clear_surface_model (SurfaceModelID)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/907761.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907761.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907761.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入理解 SQL 的 JOIN 查詢:從基礎到高級的第一步

在處理數據庫時&#xff0c;我們常常需要從多個表中提取數據。比如想知道一個城市的天氣情況&#xff0c;同時又想知道這個城市的具體位置。這就需要將 weather 表和 cities 表結合起來查詢。這種操作在 SQL 中被稱為 JOIN 查詢。 現在看下兩種表的情況 1.weather 表&#xff…

上傳頭像upload的簡易方法,轉base64調接口的

1.首頁使用el-image顯示數據&#xff0c;用的是轉base64后端返給的 <el-table-column prop"avatar" align"center" label"頭像"><template #default"scope"><el-image style"height: 40px;width: 40px;" :sr…

[AD] CrownJewel-1 Logon 4799+vss-ShadowCopy+NTDS.dit/SYSTEM+$MFT

QA QA攻擊者可以濫用 vssadmin 實用程式來建立卷影快照&#xff0c;然後提取 NTDS.dit 等敏感檔案來繞過安全機制。確定卷影複製服務進入運作狀態的時間。2024-05-14 03:42:16建立卷影快照時&#xff0c;磁碟區複製服務會使用機器帳戶驗證權限並列舉使用者群組。找到卷影複製過…

rtpmixsound:實現音頻混音攻擊!全參數詳細教程!Kali Linux教程!

簡介 一種將預先錄制的音頻與指定目標音頻流中的音頻&#xff08;即 RTP&#xff09;實時混合的工具。 一款用于將預先錄制的音頻與指定目標音頻流中的音頻&#xff08;即 RTP&#xff09;實時混合的工具。該工具創建于 2006 年 8 月至 9 月之間。該工具名為 rtpmixsound。它…

GitHub 趨勢日報 (2025年05月28日)

&#x1f4ca; 由 TrendForge 系統生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日報中的項目描述已自動翻譯為中文 &#x1f4c8; 今日獲星趨勢圖 今日獲星趨勢圖 2379 agenticSeek 1521 computer-science 841 n8n 577 langflow 351 qlib 282 skt…

threejsPBR材質與紋理貼圖

1. PBR材質簡介 本節課沒有具體的代碼&#xff0c;就是給大家科普一下PBR材質&#xff0c;所謂PBR就是&#xff0c;基于物理的渲染(physically-based rendering)。 Three.js提供了兩個PBR材質相關的APIMeshStandardMaterial和MeshPhysicalMaterial,MeshPhysicalMaterial是Mes…

Android 12系統源碼_多屏幕(四)自由窗口模式

一、小窗模式 1.1 小窗功能的開啟方式 開發者模式下開啟小窗功能 adb 手動開啟 adb shell settings put global enable_freeform_support 1 adb shell settings put global force_resizable_activities 11.2 源碼配置 copy file # add for freedom PRODUCT_COPY_FILES …

C# 將HTML文檔、HTML字符串轉換為圖片

在.NET開發中&#xff0c;將HTML內容轉換為圖片的需求廣泛存在于報告生成、郵件內容存檔、網頁快照等場景。Free Spire.Doc for .NET作為一款免費的專業文檔處理庫&#xff0c;無需Microsoft Word依賴&#xff0c;即可輕松實現這一功能。本文將深入解析HTML文檔和字符串轉圖片兩…

【HTML-15.2】HTML表單按鈕全面指南:從基礎到高級實踐

表單按鈕是網頁交互的核心元素&#xff0c;作為用戶提交數據、觸發操作的主要途徑&#xff0c;其重要性不言而喻。本文將系統性地介紹HTML表單按鈕的各種類型、使用場景、最佳實踐以及高級技巧&#xff0c;幫助開發者構建更高效、更易用的表單交互體驗。 1. 基礎按鈕類型 1.1…

吳恩達MCP課程(4):connect_server_mcp_chatbot

目錄 完整代碼代碼解釋1. 導入和初始化2. 類型定義3. MCP_ChatBot 類初始化4. 查詢處理 (process_query)5. 服務器連接管理6. 核心特性總結 示例 完整代碼 原課程代碼是用Anthropic寫的&#xff0c;下面代碼是用OpenAI改寫的&#xff0c;模型則用阿里巴巴的模型做測試 .env 文…

C++內存學習

引入 在實例化對象時&#xff0c;不管是編譯器還是我們自己&#xff0c;會使用構造函數給成員變量一個合適的初始值。 但是經過構造函數之后&#xff0c;我們還不能將其稱為成員變量的初始化&#xff1a; 構造函數中的語句只能稱為賦初值&#xff0c;而不能稱作初始化 因為初…

MySQL 大戰 PostgreSQL

一、底層架構對比 ??維度????MySQL????PostgreSQL????存儲引擎??多引擎支持&#xff08;InnoDB、MyISAM等&#xff09;單一存儲引擎&#xff08;支持擴展如Zheap、Zedstore&#xff09;??事務實現??基于UNDO日志的MVCC基于堆表(Heap)的MVCC??鎖機制??…

基于FPGA的二叉決策樹cart算法verilog實現,訓練環節采用MATLAB仿真

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 5.算法完整程序工程 1.算法運行效果圖預覽 (完整程序運行后無水印) MATLAB訓練結果 上述決策樹判決條件&#xff1a; 分類的決策樹1 if x21<17191.5 then node 2 elseif x21>17191…

【RAG】RAG綜述|一文了解RAG|從零開始(下)

文章目錄 5. RAG的架構5.1 Naive RAG5.2 Advanced RAG5.2.1 檢索前處理和數據索引技術5.2.2 知識分片技術5.2.3 分層索引5.2.4 檢索技術5.2.4.1 優化用戶查詢5.2.4.2 通過假想文檔嵌入修復查詢和文檔不對稱5.2.4.3 Routing5.2.4.5 自查詢檢索5.2.4.6 混合搜索5.2.4.7 圖檢索5.2…

山東大學軟件學院項目實訓-基于大模型的模擬面試系統-面試官和面試記錄的分享功能(2)

本文記錄在發布文章時&#xff0c;可以添加自己創建的面試官和面試記錄到文章中這一功能的實現。 前端 首先是在原本的界面的底部添加了兩個多選框&#xff08;后期需要美化調整&#xff09; 實現的代碼&#xff1a; <el-col style"margin-top: 1rem;"><e…

FPGA純verilog實現MIPI-DSI視頻編碼輸出,提供工程源碼和技術支持

目錄 1、前言工程概述免責聲明 2、相關方案推薦我已有的所有工程源碼總目錄----方便你快速找到自己喜歡的項目我這里已有的 MIPI 編解碼方案 3、設計思路框架工程設計原理框圖FPGA內部彩條RGB數據位寬轉換RGB數據緩存MIPI-DSI協議層編碼MIPI-DPHY物理層串化MIPI-LVDS顯示屏工程…

LXQt修改開始菜單高亮

開始菜單紅色高亮很難看 mkdir -p ~/.local/share/lxqt/palettes/ mkdir -p ~/.local/share/lxqt/themes/ cp /usr/share/lxqt/palettes/Dark ~/.local/share/lxqt/palettes/Darker cp -p /usr/share/lxqt/themes/dark ~/.local/share/lxqt/themes/darker lxqt-panel.qss L…

DeepSeek-R1-0528-Qwen3-8B 本地ollama離線運行使用和llamafactory lora微調

參考: https://huggingface.co/deepseek-ai/DeepSeek-R1-0528-Qwen3-8B 量化版本: https://huggingface.co/unsloth/DeepSeek-R1-0528-Qwen3-8B-GGUF https://docs.unsloth.ai/basics/deepseek-r1-0528-how-to-run-locally 1、ollama運行 升級ollama版本到0.9.0 支持直接…

vue3 + WebSocket + Node 搭建前后端分離項目 開箱即用

[TOC](vue3 WebSocket Node 搭建前后端分離項目) 開箱即用 前言 top1&#xff1a;vue3.5搭建前端H5 top2&#xff1a;Node.js koa搭建后端服務接口 top3&#xff1a;WebSocket 長連接實現用戶在線聊天 top4&#xff1a;接口實現模塊化 Mysql 自定義 top5&#xff1a;文件上…

Vue 前端代碼規范實戰:ESLint v9、Prettier 與 Stylelint 集成指南與最佳實踐

&#x1f680; 作者主頁&#xff1a; 有來技術 &#x1f525; 開源項目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 倉庫主頁&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 歡迎點贊 &#x1f44d; 收藏 ?評論 …