機器視覺6-halcon高級教程

機器視覺6-halcon高級教程

  • 雙目立體視覺原理
    • 視差
    • 外極線幾何
    • 雙目標定
  • 雙目立體視覺之Halcon標定
    • 一.標定結果
    • 二.Halcon標定過程
      • 1.獲取左右相機圖像中標定板的區域;
      • 2.提取左右相機圖像中標定板的MARK點坐標和攝像機外部參數;
      • 3.執行雙目標定;
      • 4.獲取非標準外極線幾何到標準外極線幾何之間的變換矩陣;
      • 5.通過變換矩陣對未校正的圖像進行圖像校正
      • 6.顯示圖像校正后標準外極線幾何時的圖像.
  • 雙目立體視覺測量零件的高度
    • 1.執行雙目標定;
    • 2.獲取非標準外極線幾何到標準外極線幾何之間的變換矩陣;
    • 3.通過變換矩陣對未校正的圖像進行圖像校正
    • 4.計算左右攝像機的視差圖像
    • 5.通過視差計算距離圖像
    • 代碼示例
      • **1. 初始化設置與窗口管理**
      • **2. 圖像讀取與參數定義**
      • **3. 極線校正與圖像映射**
      • **4. 視差與深度計算**
      • **5. 高度測量與結果顯示**
      • **優化**

雙目立體視覺原理

雙目立體視覺是一種基于視差原理的三維信息獲取技術,通過模擬人類雙眼的視覺機制,從不同視角采集圖像并計算對應點的位置差異(視差),從而重建目標物體的三維幾何信息。其核心流程包括圖像采集、相機標定、立體匹配和三維重建,具體原理如下:
雙目攝像機如同人的兩個眼睛
在這里插入圖片描述


視差

  1. 視差與深度關系
    雙目系統通過兩個平行安裝的相機(基線距離為 ( b ))同時拍攝同一場景。同一空間點 ( P ) 在左右圖像中的水平像素坐標差稱為視差 ( d ),深度 ( Z ) 可通過三角測量公式計算:

Z = b ? f d Z = \frac{b \cdot f}{d} Z=db?f?
其中 ( f ) 為相機焦距。視差越大,物體距離越近;視差趨近于0時,物體接近無限遠。
在這里插入圖片描述
坐標系以左相機為準,右相機相對于左相機是簡單的平移,用坐標表示為(Tx,0,0
2. 極線約束與校正
為簡化匹配過程,需對圖像進行極線校正,使對應點在左右圖像中位于同一水平線上。這通過標定相機內外參數并消除畸變實現,確保匹配搜索僅需在水平方向進行,顯著降低計算復雜度。

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

在這里插入圖片描述
在這里插入圖片描述
視差公式
在這里插入圖片描述
在這里插入圖片描述


外極線幾何

非標準外極線幾何圖
在這里插入圖片描述

1.極平面
⒉極線
3.極點
4.極線約束

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

雙目標定

雙目標定技術獲取非標準外極線幾何到標準外極線幾何的變換矩陣,校正兩個相機的圖像。根據兩個相機的相對位姿,從而在標準外極線幾何圖像中獲取物體在另一個相機成像中位置。

一、雙目標定的定義與目的
雙目標定是雙目視覺系統的核心步驟,旨在確定雙目相機的內參(焦距、主點、畸變系數)和外參(兩相機間的旋轉矩陣 ( R ) 和平移向量 ( T )),從而建立三維空間與二維圖像之間的映射關系。其核心目標包括:

  1. 消除畸變:校正鏡頭畸變(徑向畸變、切向畸變)對成像的影響。
  2. 坐標系對齊:通過外參矩陣實現左右相機坐標系的統一,便于后續立體匹配和三維重建。

二、雙目標定流程

  1. 標定板準備
    ? 使用棋盤格標定板(如8×5黑白格),需保證打印精度高、表面平整且無反光,方格尺寸根據相機視場選擇(短焦相機建議20mm,長焦相機建議60mm)。

    ? 標定板應覆蓋圖像1/4至1/2區域,且在不同角度(俯仰、傾斜、平移)下拍攝15-60組圖像以覆蓋全視場。

  2. 圖像采集與角點提取
    ? 左右相機同步拍攝標定板圖像,確保標定板完整且無模糊。常用工具包括OpenCV或MATLAB腳本自動保存圖像。

    ? 使用Canny算子檢測邊緣,結合Zernike矩亞像素提取或橢圓擬合獲取角點坐標,精度可達0.1像素。

  3. 單應性矩陣計算
    ? 通過針孔模型建立世界坐標系與圖像坐標系的線性關系,求解單應性矩陣 ( H ) 描述平面投影變換。

    ? 公式:( s \cdot [u \quad v \quad 1]^T = H \cdot [X \quad Y \quad 1]^T ),其中 ( s ) 為比例因子,( H ) 包含內參和外參信息。

  4. 參數優化
    ? 傳統方法:基于最小二乘法或奇異值分解(SVD)求解初始參數,再通過Levenberg-Marquardt算法優化。

    ? 智能優化算法:如混沌粒子群優化(CPSO),引入動態慣性權重和鄰域混沌搜索,避免局部最優,提升標定精度。

  5. 立體校正
    ? 使用Bouguet算法將左右圖像投影到同一極平面,使極線水平對齊,簡化立體匹配計算。

    ? 變換矩陣 ( R_{rect} ) 構造方式:基于平移向量 ( T ) 方向,使基線與成像平面平行。


三、關鍵技術解析

  1. 內參標定
    ? 焦距 ( f ):通過棋盤格角點計算歸一化焦距 ( f_x, f_y ) 及主點 ( (c_x, c_y) )。

    ? 畸變校正:二階徑向畸變(( k_1, k_2 ))和切向畸變(( p_1, p_2 ))模型,公式:

x c o r r e c t e d = x ( 1 + k 1 r 2 + k 2 r 4 ) + 2 p 1 x y + p 2 ( r 2 + 2 x 2 ) x_{corrected} = x(1 + k_1 r^2 + k_2 r^4) + 2p_1 xy + p_2 (r^2 + 2x^2) xcorrected?=x(1+k1?r2+k2?r4)+2p1?xy+p2?(r2+2x2)
y c o r r e c t e d = y ( 1 + k 1 r 2 + k 2 r 4 ) + p 1 ( r 2 + 2 y 2 ) + 2 p 2 x y y_{corrected} = y(1 + k_1 r^2 + k_2 r^4) + p_1 (r^2 + 2y^2) + 2p_2 xy ycorrected?=y(1+k1?r2+k2?r4)+p1?(r2+2y2)+2p2?xy
其中 r 2 = x 2 + y 2 r^2 = x^2 + y^2 r2=x2+y2

  1. 外參標定
    ? 旋轉矩陣 ( R ):分解為繞X/Y/Z軸旋轉角度 α , β , γ \alpha, \beta, \gamma α,β,γ,通過歐拉角或四元數表示。

    ? 平移向量 ( T ):描述右相機相對于左相機的空間位移,基線長度 b = ∥ T ∥ b = \| T \| b=T 直接影響深度分辨率。

  2. 標定工具與算法
    ? MATLAB工具箱:stereoCameraCalibrator 支持自動角點檢測、參數優化及重投影誤差分析。

    ? OpenCV函數:cv2.stereoCalibrate() 結合張正友平面標定法,適用于實時系統開發。


四、應用場景與優化建議

  1. 典型應用
    ? 機器人導航:結合SLAM技術實現環境三維建模與避障。

    ? 工業檢測:高精度測量零件尺寸(誤差<0.1mm)。

    ? 自動駕駛:通過視差計算障礙物距離,支持路徑規劃。

  2. 優化建議
    ? 標定板多樣性:使用多尺寸標定板適應不同工作距離。

    ? 光照控制:均勻照明避免反光或陰影干擾角點檢測。

    ? 動態標定:在相機移動或變焦后需重新標定。


五、常見問題與解決方案

  1. 重投影誤差過大
    ? 原因:角點提取不準確或標定板姿態單一。

    ? 解決:增加標定圖像數量(建議≥20組),覆蓋更多視角。

  2. 極線未對齊
    ? 原因:外參矩陣 ( R, T ) 計算誤差。

    ? 解決:使用Bouguet校正法強制極線水平化。

  3. 鏡頭畸變殘留
    ? 原因:畸變模型階數不足(如僅使用一階徑向畸變)。

    ? 解決:擴展至二階徑向+切向畸變模型。


總結
雙目標定是雙目視覺系統的基石,其精度直接影響三維重建與測距的可靠性。通過合理設計標定流程、選擇優化算法并嚴格把控拍攝條件,可實現亞毫米級標定精度。未來,結合深度學習的自標定方法有望進一步簡化流程并提升魯棒性。

雙目立體視覺之Halcon標定

一.標定結果

在這里插入圖片描述

二.Halcon標定過程

1.獲取左右相機圖像中標定板的區域;

find_caltab(Image : CalPlate : CalPlateDescr, SizeGauss, MarkThresh, MinDiamMarks :)
參數含義:
Image : 		輸入圖像
CalPlate : 		標定板區域
CalPlateDescr:	標定板描述文件
SizeGauss: 		高斯濾波核;
MarkThresh,       提取mark的閾值
MinDiamMarks :    標定板中MARK圓的最小半徑

2.提取左右相機圖像中標定板的MARK點坐標和攝像機外部參數;

find_marks_and_pose(Image, CalPlateRegion : : CalPlateDescr, StartCamParam, StartThresh, DeltaThresh, MinThresh,Alpha, MinContLength, MaxDiamMarks : RCoord, CCoord, StartPose)
參數含義:
Image:			輸入圖像
CalPlateRegion:	標定板區域
CalPlateDescr:     標定板描述文件
StartCamParam:     攝像機內部參數
DeltaThresh:       提取MARK黑點所需的初始閾值
MinThresh:         提取MARK黑點步進閾值
Alpha:             提取MARK黑點輪廓的濾波參數
MinContLength:     MARK黑點輪廓的最小長度
MaxDiamMarks:      MARK黑點輪廓的最大直徑
RCoord:            探測到MARK黑點的行坐標
CCoord:			探測到MARK黑點的列坐標
StartPose          輸出攝像機外部參數

3.執行雙目標定;

binocular_calibration( : : NX, NY, NZ, NRow1, NCol1, NRow2, NCol2, StartCamParam1, StartCamParam2, NStartPose1,NStartPose2, EstimateParams : CamParam1, CamParam2, NFinalPose1, NFinalPose2, RelPose, Errors)
參數含義:
NX:			標定板MARK點行坐標(經過排序的,單位是米)
NY:			標定板MARK點列坐標(經過排序的,單位是米)
NZ:			標定板MARK點Z坐標(經過排序的,單位是米)
NRow1:        左面相機中標定板提取出的MARK點行坐標(經過排序的,單位是像素)
NCol1:		左面相機中標定板提取出的MARK點列坐標(經過排序的,單位是像素)
NRow2:		右面相機中標定板提取出的MARK點行坐標(經過排序的,單位是像素)
NCol2:		右面相機中標定板提取出的MARK點列坐標(經過排序的,單位是像素)
StartCamParam1:左面相機的攝像機內部參數
StartCamParam2:右面相機的攝像機內部參數
NStartPose1:	 左面相機的攝像機外部參數
NStartPose2:	 右面相機的攝像機外部參數
EstimateParams: 選擇要標定出哪些相機參數,”all”代表所有的參數
CamParam1:     標定后得到的左面相機的攝像機內部參數
CamParam2:     標定后得到的右面相機的攝像機內部參數
NFinalPose1:   標定后得到的左面相機的攝像機外部參數
NFinalPose2:   標定后得到的右面相機的攝像機外部參數
RelPose:		 右邊相機相對于左面相機的位姿
Errors         平均錯誤誤差

4.獲取非標準外極線幾何到標準外極線幾何之間的變換矩陣;

gen_binocular_rectification_map( : Map1, Map2 : CamParam1, CamParam2, RelPose, SubSampling, Method, MapType :CamParamRect1, CamParamRect2, CamPoseRect1, CamPoseRect2, RelPoseRect)
參數含義:
Map1:左面相機校正映射數據
Map2:右面相機校正映射數據
CamParam1:左面相機的攝像機內部參數
CamParam2:右面相機的攝像機內部參數
RelPose:  右相機相對左相機的位姿
SubSampling:采樣因子
Method:    映射校正方法
MapType:   映射校正類型
CamParamRect1: 左面相機校正以后的攝像機內部參數
CamParamRect2: 右面相機校正以后的攝像機內部參數
CamPoseRect1:  校正以后的左面相機相對原始相機的位姿
CamPoseRect2:校正以后的右面相機相對原始相機的位姿
RelPoseRect:校正以后的右面相機相對校正以后的左面相機的位姿關系

5.通過變換矩陣對未校正的圖像進行圖像校正

map_image(Image, Map : ImageMapped : : )
參數含義:
Image:			待校正圖像
Map:  			相機校正映射數據
ImageMapped: 	校正后的圖像

6.顯示圖像校正后標準外極線幾何時的圖像.

check_epipolar_constraint(ImageRectifiedL, ImageRectifiedR : : RectCamParL, RectCamParR, WindowHandle1, WindowHandle2, CaltabFile :EpipolarError)
參數含義:
ImageRectifiedL:左面相機校正以后的圖像
ImageRectifiedR:右面相機校正以后的圖像
RectCamParL:左面相機校正以后的攝像機內部參數
RectCamParR:右面相機校正以后的攝像機內部參數
WindowHandle1:左面攝像機圖像窗口
WindowHandle2:右面攝像機圖像窗口
CaltabFile:標定板文件
EpipolarError:錯誤信息

*設置離線圖像存放的路徑
ImgPath := 'stereo/board/'Index := 1
*讀取左邊相機離線圖像
read_image (ImageL, ImgPath + 'calib_l_' + Index$'02d')*讀取右邊相機離線圖像
read_image (ImageR, ImgPath + 'calib_r_' + Index$'02d')*關閉已經打開的窗口
dev_close_window ()*關閉程序計數器,變量更新,圖像更新窗口
dev_update_off ()*獲取左邊相機圖像大小
get_image_size (ImageL, WidthL, HeightL)*創建左邊的窗口
dev_open_window (0, 0, WidthL, HeightL, 'black', WindowHandle1)*設置區域填充模式為邊緣模式
dev_set_draw ('margin')*設置輸出對象的顏色為綠色
dev_set_color ('green')*設置字體信息
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')*獲取右邊相機圖像大小
get_image_size (ImageR, WidthR, HeightR)*創建右邊的窗口
dev_open_window (0, WidthL + 12, WidthL, HeightL, 'black', WindowHandle2)*設置區域填充模式為邊緣模式
dev_set_draw ('margin')*設置輸出對象的顏色為綠色
dev_set_color ('green')* 校正文件
CaltabFile := 'caltab_30mm.descr'*獲取標定板中所有mark點的中心坐標
caltab_points (CaltabFile, X, Y, Z)* 設置左右兩個相機的攝像機內部參數[Focus,Kappa,SxSy,CxCy,WhithHeight]
StartCamParL := [0.0125,0,1.48e-5,1.48e-5,WidthL / 2.0,HeightL / 2.0,WidthL,HeightL]
StartCamParR := StartCamParL
* Parameter settings for find_caltab and find_marks_and_pose
SizeGauss := 3
MarkThresh := 120
MinDiamMarks := 5
StartThresh := 128
DeltaThresh := 10
MinThresh := 18
Alpha := 0.9
MinContLength := 15
MaxDiamMarks := 100
* Create the tuples in which the image coordinates of the
* calibration marks and the initial poses will be accumulated
RowsL := []
ColsL := []
StartPosesL := []
RowsR := []
ColsR := []
StartPosesR := []
* Start the loop over the calibration images
for Index := 1 to 15 by 1* 讀取左面相機拍照的標定板圖像read_image (ImageL, ImgPath + 'calib_l_' + Index$'02d')* 讀取右面相機拍照的標定板圖像read_image (ImageR, ImgPath + 'calib_r_' + Index$'02d')* 分割左面相機拍照的標定板圖像標定板區域find_caltab (ImageL, CaltabL, CaltabFile, SizeGauss, MarkThresh, MinDiamMarks)* 分割右面相機拍照的標定板圖像標定板區域find_caltab (ImageR, CaltabR, CaltabFile, SizeGauss, MarkThresh, MinDiamMarks)*激活左面的窗口dev_set_window (WindowHandle1)*顯示左面相機拍照的標定板圖像dev_display (ImageL)*顯示左面相機拍照的標定板圖像標定板區域dev_display (CaltabL)*激活右面的窗口dev_set_window (WindowHandle2)*顯示右面相機拍照的標定板圖像dev_display (ImageR)*顯示右面相機拍照的標定板圖像標定板區域dev_display (CaltabR)*提取左面相機拍照的標定板中MARK點坐標和攝像機外部參數find_marks_and_pose (ImageL, CaltabL, CaltabFile, StartCamParL, StartThresh, DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks, RCoordL, CCoordL, StartPoseL)*顯示左面圖像中標定板三維模型disp_caltab (WindowHandle1, CaltabFile, StartCamParL, StartPoseL, 1)*提取右面相機拍照的標定板中MARK點坐標和攝像機外部參數find_marks_and_pose (ImageR, CaltabR, CaltabFile, StartCamParR, StartThresh, DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks, RCoordR, CCoordR, StartPoseR)*顯示右面圖像中標定板三維模型disp_caltab (WindowHandle2, CaltabFile, StartCamParR, StartPoseR, 1)*17張左面相機拍照圖像的MARK點行坐標連接起來RowsL := [RowsL,RCoordL]*17張左面相機拍照圖像的MARK點列坐標連接起來ColsL := [ColsL,CCoordL]*將左面相機的攝像機外部參數連接起來StartPosesL := [StartPosesL,StartPoseL]*17張右面相機拍照圖像的MARK點行坐標連接起來RowsR := [RowsR,RCoordR]*17張右面相機拍照圖像的MARK點列坐標連接起來ColsR := [ColsR,CCoordR]*將右面相機的攝像機外部參數連接起來StartPosesR := [StartPosesR,StartPoseR]
endfor* 執行雙目標定
binocular_calibration (X, Y, Z, RowsL, ColsL, RowsR, ColsR, StartCamParL, StartCamParR, StartPosesL, StartPosesR, 'all', CamParamL, CamParamR, NFinalPoseL, NFinalPoseR, cLPcR, Errors)
* If required, save the results to disk:
* write_cam_par (CamParamL, 'cam_left-125.dat')
* write_cam_par (CamParamR, 'cam_right-125.dat')
* write_pose (cLPcR, 'pos_right2left.dat')* 獲取非標準外極線幾何到標準外極線幾何之間的變換關系
gen_binocular_rectification_map (MapL, MapR, CamParamL, CamParamR, cLPcR, 1, 'geometric', 'bilinear', RectCamParL, RectCamParR, CamPoseRectL, CamPoseRectR, RectLPosRectR)*讀取左相機拍照的一張圖
read_image (ImageL, ImgPath + 'calib_l_01')*讀取右相機拍照的一張圖
read_image (ImageR, ImgPath + 'calib_r_01')*根據上述變換關系,對左相機拍照圖進行校正
map_image (ImageL, MapL, ImageRectifiedL)*根據上述變換關系,對右相機拍照圖進行校正
map_image (ImageR, MapR, ImageRectifiedR)*顯示最后的雙目標定結果,得到標準外極線幾何時的圖像.
check_epipolar_constraint (ImageRectifiedL, ImageRectifiedR, RectCamParL, RectCamParR, WindowHandle1, WindowHandle2, CaltabFile, EpipolarError)

以下是針對提供的HALCON雙目相機標定與校正代碼的逐步解釋和優化建議:

逐步解釋

  1. 初始化設置:
    ? 定義圖像路徑ImgPath,初始化索引Index

    ? 讀取左右相機的第一對標定板圖像(可能用于測試,后續循環處理所有圖像)。

  2. 窗口管理:
    ? 關閉已有窗口,禁用自動更新以提高性能。

    ? 根據左圖像尺寸創建左窗口,設置繪圖參數(邊緣模式、顏色、字體)。

    ? 創建右窗口,位置在左窗口右側,使用左圖像尺寸(假設左右圖像尺寸相同)。

  3. 標定板參數:
    ? 加載標定板描述文件caltab_30mm.descr,獲取標定板點的世界坐標(X, Y, Z)

    ? 初始化左右相機的內部參數(焦距、畸變、像素尺寸、中心點等)。

  4. 參數配置:
    ? 設置find_caltabfind_marks_and_pose的參數(高斯濾波、閾值、標記尺寸等)。

    ? 初始化數組存儲左右相機的圖像坐標和初始位姿。

  5. 循環處理標定圖像:
    ? 遍歷15對圖像,逐對處理:

    ? 讀取左右圖像,檢測標定板區域CaltabL/R并顯示。

    ? 提取標記點坐標(RCoordL/R, CCoordL/R)和初始位姿StartPoseL/R

    ? 顯示標定板3D模型,收集坐標和位姿數據。

  6. 雙目標定:
    ? 使用binocular_calibration優化相機參數和相對位姿,輸出最終參數CamParamL/RcLPcR

  7. 生成校正映射:
    ? 調用gen_binocular_rectification_map生成校正映射MapL/R,將圖像校正為標準極線幾何。

  8. 驗證校正結果:
    ? 讀取并校正一對圖像,使用check_epipolar_constraint檢查極線誤差,驗證校正效果。

優化建議

  1. 窗口尺寸適配:

    * 獲取右圖像實際尺寸
    get_image_size (ImageR, WidthR, HeightR)
    * 創建右窗口時使用實際尺寸
    dev_open_window (0, WidthL + 12, WidthR, HeightR, 'black', WindowHandle2)
    

    確保右窗口尺寸與右圖像匹配,避免顯示不全。

  2. 錯誤處理:

    tryfind_caltab (ImageL, CaltabL, CaltabFile, SizeGauss, MarkThresh, MinDiamMarks)
    catch (Exception)* 處理異常,如打印錯誤信息并跳出循環dev_disp_text ('標定板檢測失敗: ' + Exception, 'window', WindowHandle1, 'left', 'red', 'box')break
    endtry
    

    添加異常捕獲,增強魯棒性。

  3. 字符串格式化修正:

    * 使用正確的格式化語法
    IndexStr := Index$'02d'
    read_image (ImageL, ImgPath + 'calib_l_' + IndexStr)
    

    確保文件名正確生成,避免因格式錯誤導致讀取失敗。

  4. 參數保存:

    * 保存標定結果
    write_cam_par (CamParamL, 'cam_left_final.dat')
    write_cam_par (CamParamR, 'cam_right_final.dat')
    write_pose (cLPcR, 'stereo_pose.dat')
    * 保存校正映射
    write_map (MapL, 'map_left.bin')
    write_map (MapR, 'map_right.bin')
    

    便于后續應用,無需重復標定。

  5. 循環結構優化:

    for Index := 1 to 15 by 1* 統一處理左右圖像process_stereo_pair (Index, ImgPath, WindowHandle1, WindowHandle2, ...)
    endfor
    

    封裝重復操作為函數,提升代碼可讀性和維護性。

  6. 動態參數調整:
    ? 可交互式調整MarkThresh等參數,或通過循環尋找最佳參數組合,確保標定板檢測穩定。

  7. 可視化增強:

    * 在顯示校正結果時疊加極線
    disp_epipolar_line (ImageRectifiedL, ImageRectifiedR, RectCamParL, RectCamParR, WindowHandle1, WindowHandle2)
    

    直觀展示極線對齊效果。

修正后的關鍵代碼片段

* 創建右窗口時使用右圖像尺寸
get_image_size (ImageR, WidthR, HeightR)
dev_open_window (0, WidthL + 12, WidthR, HeightR, 'black', WindowHandle2)* 循環處理中添加錯誤處理
for Index := 1 to 15 by 1tryread_image (ImageL, ImgPath + 'calib_l_' + Index$'02d')read_image (ImageR, ImgPath + 'calib_r_' + Index$'02d')* 檢測標定板find_caltab (ImageL, CaltabL, CaltabFile, SizeGauss, MarkThresh, MinDiamMarks)find_caltab (ImageR, CaltabR, CaltabFile, SizeGauss, MarkThresh, MinDiamMarks)* 提取標記點及位姿find_marks_and_pose (...)* 收集數據...catch (Exception)dev_clear_window ()dev_disp_text ('錯誤: ' + Exception, 'window', WindowHandle1, 'left', 'red', 'box')breakendtry
endfor* 標定后保存參數
write_cam_par (CamParamL, 'cam_left_final.dat')
write_cam_par (CamParamR, 'cam_right_final.dat')
write_pose (cLPcR, 'stereo_pose.dat')

總結

通過修正窗口尺寸、增強錯誤處理、優化參數保存及代碼結構,提升了程序的穩健性和實用性。確保實際應用中左右相機圖像尺寸一致或正確適配,參數文件路徑正確,并根據實際標定場景調整檢測參數,以獲得最佳標定效果。

雙目立體視覺測量零件的高度

在這里插入圖片描述
高度測量步驟:

1.執行雙目標定;

binocular_calibration( : : NX, NY, NZ, NRow1, NCol1, NRow2, NCol2, StartCamParam1, StartCamParam2, NStartPose1,NStartPose2, EstimateParams : CamParam1, CamParam2, NFinalPose1, NFinalPose2, RelPose, Errors)
參數含義:
NX:			標定板MARK點行坐標(經過排序的,單位是米)
NY:			標定板MARK點列坐標(經過排序的,單位是米)
NZ:			標定板MARKZ坐標(經過排序的,單位是米)
NRow1:        左面相機中標定板提取出的MARK點行坐標(經過排序的,單位是像素)
NCol1:		左面相機中標定板提取出的MARK點列坐標(經過排序的,單位是像素)
NRow2:		右面相機中標定板提取出的MARK點行坐標(經過排序的,單位是像素)
NCol2:		右面相機中標定板提取出的MARK點列坐標(經過排序的,單位是像素)
StartCamParam1:左面相機的攝像機內部參數
StartCamParam2:右面相機的攝像機內部參數
NStartPose1:	 左面相機的攝像機外部參數
NStartPose2:	 右面相機的攝像機外部參數
EstimateParams: 選擇要標定出哪些相機參數,all”代表所有的參數
CamParam1:     標定后得到的左面相機的攝像機內部參數
CamParam2:     標定后得到的右面相機的攝像機內部參數
NFinalPose1:   標定后得到的左面相機的攝像機外部參數
NFinalPose2:   標定后得到的右面相機的攝像機外部參數
RelPose:		 右邊相機相對于左面相機的位姿
Errors         平均錯誤誤差

2.獲取非標準外極線幾何到標準外極線幾何之間的變換矩陣;

gen_binocular_rectification_map( : Map1, Map2 : CamParam1, CamParam2, RelPose, SubSampling, Method, MapType :CamParamRect1, CamParamRect2, CamPoseRect1, CamPoseRect2, RelPoseRect)
參數含義:
Map1:左面相機校正映射數據
Map2:右面相機校正映射數據
CamParam1:左面相機的攝像機內部參數
CamParam2:右面相機的攝像機內部參數
RelPose:  右相機相對左相機的位姿
SubSampling:采樣因子
Method:    映射校正方法
MapType:   映射校正類型
CamParamRect1: 左面相機校正以后的攝像機內部參數
CamParamRect2: 右面相機校正以后的攝像機內部參數
CamPoseRect1:  校正以后的左面相機相對原始相機的位姿
CamPoseRect2:校正以后的右面相機相對原始相機的位姿
RelPoseRect:校正以后的右面相機相對校正以后的左面相機的位姿關系

3.通過變換矩陣對未校正的圖像進行圖像校正

map_image(Image, Map : ImageMapped : : )
參數含義:
Image:			待校正圖像
Map:  			相機校正映射數據
ImageMapped: 	校正后的圖像

4.計算左右攝像機的視差圖像

binocular_disparity(ImageRect1, ImageRect2 : Disparity, Score : Method, MaskWidth, MaskHeight, TextureThresh,MinDisparity, MaxDisparity, NumLevels, ScoreThresh, Filter, SubDisparity:)
參數含義:
ImageRect1:左邊相機校正后的圖像
ImageRect2:右邊相機校正后的圖像
Disparity:視差映射圖
Score:視差值得匹配分數
Method:匹配方法
MaskWidth:校正窗口的寬度
MaskHeight:校正窗口的高度
TextureThresh:匹配需要的閾值
MinDisparity:視差的最小值
MaxDisparity:視差的最大值
NumLevels:金字塔層級
ScoreThresh:相關函數的最小分值,保證匹配質量
Filter:增加匹配的魯棒性
SubDisparity :視差圖是否采用亞像素

5.通過視差計算距離圖像

binocular_distance_mg(ImageRect1, ImageRect2 : Distance, Score : CamParamRect1, CamParamRect2, RelPoseRect,GrayConstancy, GradientConstancy, Smoothness, InitialGuess, CalculateScore, MGParamName, MGParamValue : )
參數含義:
ImageRect1:左邊相機校正后的圖像
ImageRect2:右邊相機校正后的圖像
Distance:距離圖像
Score:視差值得匹配分數
CamParamRect1:左邊相機校正后的攝像機內部參數
CamParamRect2:右邊相機校正后的攝像機內部參數
RelPoseRect:校正后的右相機相對左相機的位姿
GrayConstancy:距離圖像中灰度值的權重
GradientConstancy:距離圖像中梯度的權重
Smoothness:圖像濾波權重
InitialGuess:初始的視差
CalculateScore:匹配分數
MGParamName:多重網格算法
MGParamValue :
//多重網格法:求解偏微分問題離散方程的一種快速迭代方法

代碼示例

*關閉圖像窗口更新
dev_update_window ('off')*關閉變量更新
dev_update_var ('off')*關閉程序計數器更新
dev_update_pc ('off')*關閉窗口
dev_close_window ()*打開新窗口
dev_open_window (0, 0, 672, 484, 'black', WindowHandle)*設置字體顯示信息
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')*讀取左面相機采集的圖像
read_image (ImageL, 'stereo/board/board_l_01')*讀取右面相機采集的圖像
read_image (ImageR, 'stereo/board/board_r_01')*獲取圖像的大小
get_image_size (ImageR, Width, Height)*根據雙目立體視覺標定獲取到左右相機的攝像機內部參數和右相機相對左相機的位姿
*左相機的攝像機內部參數
CamParamL := [0.0130507774353,-665.817817207,1.4803417027e-5,1.48e-5,155.89225769,126.70664978,320,240]
*右相機的攝像機內部參數
CamParamR := [0.0131776504517,-731.860636733,1.47997569293e-5,1.48e-5,162.98210144,119.301040649,320,240]
*右相機相對左相機的位姿
RelPose := [0.153573364258,-0.00373362231255,0.0447351264954,0.174289124775,319.843388114,359.894955219,0]*獲取非標準外極限圖像和標準外極限圖像之間的變換矩陣(映射圖像)
gen_binocular_rectification_map (MapL, MapR, CamParamL, CamParamR, RelPose, 1, 'geometric', 'bilinear', RectCamParL, RectCamParR, CamPoseRectL, CamPoseRectR, RectLPosRectR)*根據變換矩陣對左邊相機進行圖像校正
map_image (ImageL, MapL, ImageRectifiedL)*根據變換矩陣對右邊相機進行圖像校正
map_image (ImageR, MapR, ImageRectifiedR)binocular_disparity (ImageRectifiedL, ImageRectifiedR, Disparity, Score1, 'ncc', 17, 17, 5, 0, 60, 1, 0.1, 'none', 'none')
*根據左右相機的校正圖像計算深度信息
binocular_distance_mg (ImageRectifiedL, ImageRectifiedR, Distance, Score, RectCamParL, RectCamParR, RectLPosRectR, 1, 10, 5, 0, 'false', 'default_parameters', 'accurate')*清除窗口內容
dev_clear_window ()*顯示距離圖像
dev_display (Distance)*計算IC的高度
gen_rectangle2 (IC, 107.276, 62.0363, rad(-25.6343), 7.64174, 6.41978)
gen_rectangle2 (PCB, 101.986, 145.771, rad(4.75463), 7.97698, 6.76498)
get_grayval (Distance, 107.276, 62.0363, IC_Grayval)
get_grayval (Distance, 101.986, 145.771, PCB_Grayval)
IC_Height:=(PCB_Grayval-IC_Grayval)*100*顯示結果
dev_display (ImageRectifiedL)
set_tposition (WindowHandle, 103, 54)
write_string (WindowHandle, 'IC零件的高度是:'+IC_Height+'cm')

1. 初始化設置與窗口管理

* 關閉窗口更新、變量更新、程序計數器更新
dev_update_window ('off')
dev_update_var ('off')
dev_update_pc ('off')
* 關閉所有窗口并打開新窗口
dev_close_window ()
dev_open_window (0, 0, 672, 484, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

? 功能:

關閉自動更新以提高性能,創建新窗口并設置字體。
? 關鍵點:

? dev_update_off系列命令用于禁用HDevelop的自動刷新,減少資源占用。

? dev_open_window參數依次為窗口左上角坐標、寬度、高度、背景顏色和窗口句柄。


2. 圖像讀取與參數定義

* 讀取左右相機圖像
read_image (ImageL, 'stereo/board/board_l_01')
read_image (ImageR, 'stereo/board/board_r_01')
get_image_size (ImageR, Width, Height)* 定義相機參數和相對位姿
CamParamL := [0.01305..., ...]  ; 左相機內參
CamParamR := [0.01317..., ...]  ; 右相機內參
RelPose := [0.15357..., ...]    ; 右相機相對于左相機的位姿

? 參數解析:

? 內參:[Focus, Kappa, Sx, Sy, Cx, Cy, Width, Height]

? `Focus`:焦距(單位:米),遠心鏡頭設為0。  ? `Kappa`:畸變系數,通常初始化為0(Division模型)。  ? 問題:用戶代碼中`Kappa`值異常(如-665),需檢查是否誤用參數。  

? 位姿:[Tx, Ty, Tz, RotX, RotY, RotZ, Angle](軸角表示法)。

? 需驗證`RelPose`是否為標定輸出的正確格式(單位是否為弧度)。

3. 極線校正與圖像映射

* 生成校正映射并校正圖像
gen_binocular_rectification_map (MapL, MapR, CamParamL, CamParamR, RelPose, ...)
map_image (ImageL, MapL, ImageRectifiedL)
map_image (ImageR, MapR, ImageRectifiedR)

? 功能:

將原始圖像投影到公共平面,消除極線傾斜,使匹配點位于同一行。
? 參數說明:

? gen_binocular_rectification_map:輸入內參、相對位姿,輸出映射表MapL/R和校正后參數。

? map_image:根據映射表對圖像進行幾何變換。


4. 視差與深度計算

* 計算視差圖
binocular_disparity (ImageRectifiedL, ImageRectifiedR, Disparity, ..., 'ncc', 17, 17, ...)
* 計算深度圖
binocular_distance_mg (..., Distance, ...)

? 算法細節:

? 視差計算:使用歸一化互相關(NCC)方法,窗口大小17x17,適用于紋理豐富場景,但可能降低實時性。

? 深度轉換:基于視差圖與校正參數,通過三角測量生成三維距離圖。


5. 高度測量與結果顯示

* 在距離圖上定義ICPCB區域
gen_rectangle2 (IC, 107.276, 62.0363, rad(-25.6343), 7.64174, 6.41978)
gen_rectangle2 (PCB, 101.986, 145.771, rad(4.75463), 7.97698, 6.76498)
* 獲取灰度值計算高度差
get_grayval (Distance, IC_Grayval, PCB_Grayval)
IC_Height := (PCB_Grayval - IC_Grayval) * 100
* 顯示結果
dev_display (ImageRectifiedL)
write_string (WindowHandle, 'IC高度: ' + IC_Height + 'cm')

? 關鍵點:

? get_grayval:假設Distance圖像的像素值表示實際距離(單位:米/毫米),需確認單位一致性。

? 問題:rad()函數在HALCON中需替換為tuple_rad或直接輸入弧度值,否則可能報錯。

? 結果需格式化輸出,如IC_Height$'.2f',避免字符串拼接錯誤。


優化

  1. 參數驗證:
    ? 檢查CamParamL/R中的畸變系數Kappa是否合理(通常接近0)。

    ? 確認RelPose的旋轉參數單位是否為弧度。

  2. 性能優化:
    ? 縮小視差計算窗口(如9x9)以提升速度。

  3. 異常處理:
    ? 添加try-catch塊捕獲read_image或標定步驟的異常。

  4. 單位與顯示:
    ? 明確Distance的單位,調整高度計算系數(如毫米則無需*100)。


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

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

相關文章

板凳-------Mysql cookbook學習 (六)

2025年Pytorch-gpu版本安裝&#xff08;各種情況適用自己的安裝需求&#xff0c;親測絕對有效&#xff0c;示例安裝torch2.6.0&#xff0c;過程詳細面向小白&#xff09;_torch gpu版本-CSDN博客 https://blog.csdn.net/OpenSeek/article/details/145795127 2.2 查錯 import s…

Spring boot和SSM項目對比

目錄對比 springboot目錄 project├─src│ ├─main│ │ ├─java│ │ │ ├─com.example.demo│ │ │ │ ├─config // 存放SpringBoot的配置類│ │ │ │ ├─controller // 存放控制器類│ │ │ │ ├─entity // 存…

《關于潯川社團退出DevPress社區及內容撤回的聲明》

《關于潯川社團退出DevPress社區及內容撤回的聲明》 尊敬的DevPress社區及讀者&#xff1a; 經潯川社團內部決議&#xff0c;我社決定自**2025年5月26日**起正式退出DevPress社區&#xff0c;并撤回所有由我社成員在該平臺發布的原創文章。相關事項聲明如下&#xff1a; …

Python性能優化利器:__slots__的深度解析與避坑指南

核心場景&#xff1a;當需要創建數百萬個屬性固定的對象時&#xff0c;默認的__dict__字典存儲會造成巨大內存浪費。此時__slots__能通過元組結構取代字典&#xff0c;顯著提升內存效率&#xff08;實測節省58%內存&#xff09;&#xff01; 底層原理&#xff1a;為何能節省內…

Go 語言中的 Struct Tag 的用法詳解

在 Go 語言中&#xff0c;結構體字段標簽&#xff08;Struct Tag&#xff09; 是一種用于給字段添加元信息&#xff08;metadata&#xff09;的機制&#xff0c;常用于序列化&#xff08;如 JSON、XML&#xff09;、ORM 映射、驗證等場景。你在開發 Web 應用或處理數據交互時&a…

微軟正式發布 SQL Server 2025 公開預覽版,深度集成AI功能

微軟在今年的 Build 2025 大會上正式發布了 SQL Server 2025 公開預覽版&#xff0c;標志著這一經典數據庫產品在 AI 集成、安全性、性能及開發者工具方面的全面升級。 AI 深度集成與創新 原生向量搜索&#xff1a;SQL Server 2025 首次將 AI 功能直接嵌入數據庫引擎&#xff…

React從基礎入門到高級實戰:React 基礎入門 - React 的工作原理:虛擬 DOM 與 Diff 算法

React 的工作原理&#xff1a;虛擬 DOM 與 Diff 算法 引言 React 是現代前端開發的明星框架&#xff0c;它的出現徹底改變了我們構建用戶界面的方式。無論是動態的 Web 應用還是復雜的單頁應用&#xff08;SPA&#xff09;&#xff0c;React 都能以高效的渲染機制和簡潔的組件…

解釋一下NGINX的反向代理和正向代理的區別?

大家好&#xff0c;我是鋒哥。今天分享關于【解釋一下NGINX的反向代理和正向代理的區別?】面試題。希望對大家有幫助&#xff1b; 解釋一下NGINX的反向代理和正向代理的區別? NGINX的反向代理和正向代理的區別主要體現在它們的功能和使用場景上。下面我會詳細解釋它們的定義…

Python學習——執行python時,鍵盤按下ctrl+c,退出程序

在 Python 中&#xff0c;當用戶按下 CtrlC 時&#xff0c;程序默認會觸發 KeyboardInterrupt 異常并終止。 1. 捕獲 KeyboardInterrupt 異常&#xff08;推薦&#xff09; 使用 try-except 塊直接捕獲 KeyboardInterrupt 異常&#xff0c;適用于簡單場景。 示例代碼&#xff…

C++ 反向迭代器(Reverse Iterator)實現詳解

目錄 1. 反向迭代器概述 2. 代碼實現分析 3. 關鍵點解析 3.1 模板參數設計 3.2 核心操作實現 4. 使用示例 1. 反向迭代器概述 反向迭代器是STL中一種重要的適配器&#xff0c;它允許我們以相反的順序遍歷容器。本文將詳細講解如何實現一個自定義的反向迭代器模板類。 2.…

動態DNS管理:【etcd+CoreDNS】 vs【BIND9】便捷性對比

對比 BIND9 集群和 etcdCoreDNS 集群在便捷性方面&#xff0c;通常情況下&#xff0c;對于需要動態、頻繁變更 DNS 記錄以及追求云原生和自動化集成的場景&#xff0c;etcdCoreDNS 方案更加便捷。 然而&#xff0c;“便捷性”也取決于具體的應用場景、團隊的技術棧和運維習慣。…

基于大模型的短暫性腦缺血發作預測與干預全流程系統技術方案大綱

目錄 一、系統概述二、系統架構(一)數據采集層(二)大模型核心層(三)應用服務層(四)數據存儲與管理層三、全流程技術方案(一)術前階段(二)術中階段(三)術后階段(四)并發癥風險預測(五)手術方案制定(六)麻醉方案制定(七)術后護理(八)統計分析(九)技術驗…

MSP430通用電機控制代碼(Motor)設計與實現

一、代碼結構概覽 // Motor.h // Motor.h #ifndef __MOTOR_H_ #define __MOTOR_H_#include "A_include.h"void Motor_Init(void); // 初始化函數 void PWM_SET(int duty0, int duty1); // PWM設置函數#endif// Motor.c // Motor.c #include "Motor.h"…

25年軟考架構師真題(回憶更新中)

論文題: 系統負載均衡設計方法事件驅動架構多模型數據庫應用軟件測試架構案例分析: 必選題:1.1填寫質量屬性的質量屬性名 1.2解釋器風格架構的組成圖填空,以及解釋為什么該模型適用解釋器風格 選做題1redis2.1全量復制的流程圖 <

優化用戶體驗:攔截瀏覽器前進后退、刷新、關閉、路由跳轉等用戶行為并彈窗提示

&#x1f9d1;?&#x1f4bb; 寫在開頭 點贊 收藏 學會&#x1f923;&#x1f923;&#x1f923; 需求 首先列舉一下需要攔截的行為&#xff0c;接下來我們逐個實現。 瀏覽器前進后退標簽頁刷新和關閉路由跳轉 1、攔截瀏覽器前進后退 這里的實現是核心&#xff0c;涉及到大…

Docker:容器化技術

引言 傳統部署環境逐漸不適應現在的企業開發&#xff0c;為了追求更加輕量&#xff0c;更加容易管理項目&#xff0c;引入了docker容器化技術去實現更加高效的部署環境。 一.docker風光下的內核功能和常用命令 1.docker容器和虛擬機的區別 我們在底層和應用層之間引入了一層do…

ping命令常用參數以及traceout命令

在網絡故障排查和性能分析中&#xff0c;ping和 traceroute&#xff08;Windows中通常稱為 tracert&#xff09;是兩個極為重要的工具。它們幫助診斷網絡連接問題&#xff0c;了解數據在網絡中的傳輸路徑。下面將詳細介紹這兩個命令的常用參數及其應用。 ping命令 ping命令用…

SpringBoot開發——Spring Boot異常處理全攻略:五大方案實戰對比

文章目錄 一、血淚教訓:異常處理的代價二、五大異常處理方案詳解2.1 全局異常處理(推薦方案)2.2 控制器級處理2.3 HTTP狀態碼注解2.4 ResponseEntity精細控制2.5 自定義異常體系(企業級方案)三、五大方案對比決策表四、四大避坑指南4.1 異常吞噬陷阱4.2 循環依賴問題4.3 異…

CodeBuddy 實現圖片轉素描手繪工具

本文所使用的 CodeBuddy 免費下載鏈接&#xff1a;騰訊云代碼助手 CodeBuddy - AI 時代的智能編程伙伴 前言 最近在社交媒體上&#xff0c;各種素描風格的圖片火得一塌糊涂&#xff0c;身邊不少朋友都在分享自己的 “素描照”&#xff0c;看著那些黑白線條勾勒出的獨特韻味&a…

2025.05.21華為暑期實習機考真題解析第二題

?? 點擊直達筆試專欄 ??《大廠筆試突圍》 ?? 春秋招筆試突圍在線OJ ?? 筆試突圍OJ 02. 災區物資調度路徑規劃 問題描述 在一次嚴重的自然災害后,LYA負責協調救援物資的配送工作。救援區域包含多個受災鄉鎮和一個物資集結點,各個地點之間的道路狀況各異,有些甚至…