halcon學習筆記(12)——相機實踐標定及二維碼
阿新 • • 發佈:2019-01-26
最近某寶上買了一個工業相機和鏡頭,簡單的做了一下實驗;
1)相機是需要驅動的按照商家的操作安裝好驅動,這樣電腦才能識別到;
2)開啟halcon的-助手-Image Acquisition-影象獲取介面-檢測-連線-點選實時即可看到相機輸出;
3)標定,先列印標定板,看我前面筆記操作,具體助手-Callibration-安裝選擇描述檔案caltab_30mm.descr-標定-影象採集助手-然後把標定板放到相機範圍內-點選採集-警告級別稍微低點不然不好識別,標定前把有問題的圖片刪除,過程如下:
完成上面開始做了一個簡單二維碼識別的例子,例子是網友的,我只是加入了標定程式碼,複製時,記得修改標定量,不然影象會扭曲,一起學習一下,程式碼如下:
- * 2D Code generated by Image Acquisition 01
- * QR Code
- dev_close_window ()
- dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
- *先關閉活動圖形視窗,再開啟這個視窗,識別符號為WindowHandle;
- *相對於介面左上角第0行、第0列,大小是我相機的拍照比例,顏色為黑色。
-
*open_framegrabber ('DirectShow', 1, 1, 0, 0, 0, 0, 'default', 8, 'gray', -1, 'false', 'default', ' Camera MV-U130RC#FACF216B-1', 0, -1, AcqHandle)
- open_framegrabber ('MindVision11', 1, 1, 0, 0, 0, 0, 'progressive', 8, 'Gray', -1, 'false', 'auto', 'Camera MV-U130RC#C17D8221-3', 0, -1, AcqHandle)
- *DirectShow是筆記本攝像頭或者其他DirectShow的攝像頭,MindVision11是我相機的攝像頭;
- * 注意攝像頭的名稱,可以用工具欄中的“助手”——開啟新的Image Acquisition獲取攝像頭及插入程式碼
-
grab_image_start (AcqHandle, -1)
- while (true)
- grab_image_async (Image, AcqHandle, -1)
- * Calibration 01: Code generated by Calibration 01
- CamParOriginal:= [0.01629,-2024.24,8.30436e-006,8.3e-006,710.402,361.975,1280,960]
- CameraPose := [-0.0236413,0.0135896,0.152813,16.2821,3.05758,76.5791,0]
- *上面是我相機的標定量,二維碼識別時候不加也可以,halcon演算法很先進,相機扭曲也可以識別二維碼;
- CamParVirtualFixed:=CamParOriginal
- CamParVirtualFixed[1]:=0
- *上面是標定時候的引數設定
- gen_radial_distortion_map(MapFixed,CamParOriginal,CamParVirtualFixed,'bilinear')
- *生產徑向畸變對映圖,
- *mapfixed是輸出,
- *CamParOriginal是標定後的引數,
- *CamParVirtualFixed也是輸出的引數,
- *'bilinear'對映型別
- map_image(Image,MapFixed,ImageRectifiedFixed)
- *利用對映,消除影象畸變運算元
- create_data_code_2d_model ('QR Code', [], [], DataCodeHandle)
- * 二維碼的建立開頭的運算元,clear為結束清除的運算元,見下。
- set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
- dev_set_color ('forest green')
- dev_set_draw ('margin')
- dev_set_line_width (3)
- set_data_code_2d_param (DataCodeHandle, 'default_parameters', 'enhanced_recognition')
- * 設定選定引數的二維資料模型,引數詳見這個運算元
- find_data_code_2d (ImageRectifiedFixed, SymbolXLDs, DataCodeHandle, [], [], ResultHandles, DecodedDataStrings)
- * 檢測和讀取二維程式碼符號,也支援讀取二維資料模型的序列,引數詳見這個運算元
- for i := 0 to |ResultHandles| - 1 by 1
- select_obj (SymbolXLDs, SymbolXLD, i+1)
- get_contour_xld (SymbolXLD, Row, Col)
- get_string_extents (WindowHandle, DecodedDataStrings[i], Ascent, Descent, TxtWidth, TxtHeight)
- disp_message (WindowHandle, DecodedDataStrings[i], 'image', max(Row-50), max([min(Col+30)-TxtWidth/2,1]), 'black', 'true')
- area_center_xld (SymbolXLD, Area, Row1, Column, PointOrder)
- elliptic_axis_xld (SymbolXLD, Ra, Rb, Phi)
- dev_set_line_width (3)
- dev_set_draw ('margin')
- dev_set_color ('blue')
- Length := 80
- disp_arrow (WindowHandle, Row1[0], Column[0], Row1[0] - Length * sin(Phi[0]), Column[0] + Length * cos(Phi[0]), 4)
- disp_message (WindowHandle, deg(Phi[0])$'3.1f' + ' deg', 'image', Row1[0], Column[0] - 100, 'black', 'false')
- endfor
- *這段for迴圈語句的目的是讓解碼到的字串(二維碼的內容)顯示到二維碼深綠色(forest green上面定義)的解碼區域框的行列位置。
- *disp_message (WindowHandle, DecodedDataStrings, 'window', 12, 12, 'black', 'true')
- *如果不需要設定顯示到區域框中間的位置,而是顯示到窗體的上方或其他位置,那麼不需要上面那段for語句,只需這段資訊顯示的語句即可顯示到窗體相應位置。
- if (|DecodedDataStrings|>0)
- disp_continue_message (WindowHandle, 'black', 'true')
- stop()
- endif
- * if語句,當解碼一個(大於0,可設定多個)二維碼就暫停攝像頭獲取影象,直至按F5.
- clear_data_code_2d_model (DataCodeHandle)
- endwhile
- close_framegrabber (AcqHandle)
識別的效果如下: