halcon相機標定及圖像矯正(代碼)

侵刪

1 halcon相機標定和圖像矯正

對于相機采集的圖片,會由于相機本身和透鏡的影響產生形變,通常需要對相機進行標定,獲取相機的內參或內外參,然后矯正其畸變。相機畸變主要分為徑向畸變和切向畸變,其中徑向畸變是由透鏡造成的,切向畸變是由成像儀與相機透鏡的不平行造成的。

針孔模型是理想透鏡的成像模型,但是實際中相機的透鏡不可能是理想的模型,透鏡形狀的非理想特征造成像點會沿徑向發生畸變。一個像點沿徑向內縮叫負畸變,或桶形畸變沿徑向外延叫正畸變,或枕形畸變。這種崎變相對于光軸嚴格對稱的,也是畸變的主要分量。

圖1徑向畸變 ??????????????????????????圖2切向畸變

相機標定模型公式,

?

? ? ? ? ? ? ? ? ? Or ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? (1-1)

其中,(X,Y,Z)為世界坐標系中的實際點坐標,(u,v)為圖像坐標系統的像素坐標,A為相機內參,f像素單元的焦距,c圖像像素中心點。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? (1-2)

?

圖3相機成像模型

1.1?halcon相機標定

1.1.1標定助手及相機參數設置

打開halcon標定助手,加載標定板文件,選擇相機類型,設置相機參數,然后加載相機采集的標定圖像,如下圖所示,圖像中全部標定點能夠檢測出,即采集的相機已經設置好,然后生成代碼。

?

圖4 halcon標定助手

標定板生成:

標定板文件的生成分為.descr和.cpd的文件,不同格式文件需使用不同函數進行生成。如,

*生成的是27*31,標定點直徑0.0075mm的.cpd標定板(精度高標定板)

create_caltab (27, 31, 0.0075, [13, 6, 6, 20, 20], [15, 6, 24, 6, 24], 'light_on_dark', 'D:/calplate.cpd', 'caltab.ps')

*生成的是7*7,標定點之間距離0.1m,直徑0.5的.descr標定板

gen_caltab( 7, 7, 0.1, 0.5, 'D:/caltab.descr', 'caltab.ps')

加載標定圖像:

?

圖5加載標定圖像

如圖5所示,加載標定圖像后,狀態為確定時,表示標定圖像可用于進行標定,然后通過標定助手直接生成標定代碼即可。

? ? 如圖6所示,加載標定圖像后,狀態為檢測出品質問題,此原因大多是照片質量問題,例如光照、對焦、曝光等,需按照halcon標定注意事項的內容拍攝照片。一般照片檢測出品質問題也可以進行相機標定。

加載標定板圖像會出現“標志點提取失敗”,出現此原因的需要根據標定界面下的狀態欄查找halcon錯誤信息,例”inconsistent....(image mirrored? )”,則需要查找相應原因(實際標定板(透明)與標定板文件圖片的可能有鏡像區別,將實際標定板翻轉即可,多試)。此不可進行相機標定。

? ? ? ? ? ? ? ? ? ? ? ? ? ??

圖6 相機標定問題

相機初始參數設置:

例如,

*(f, k, cell width, cell height, cx, cy, width, height)k為畸變系數

StartParameters := [0.029,0,4.3e-006,4.3e-006,2592,1728,5184,3456]

*(f, k1, k2, k3, p1, p2, cell width, cell height, cx, cy, width, height)k1,k2,k3徑向畸變, p1,p2為切向畸變

StartParameters := [0.029,0,0,0,0,0,4.3e-006,4.3e-006,2592,1728,5184,3456]

其中,相機初始參數根據相機模型的不同而不同,若相機模型為area(division),則相機參數為7個,若area(多項式),則相機參數12個。

1.1.2?標定程序

利用標定助手生成代碼,然后執行結果,分析其正確性,若需要將其生成為C/C++程序,可通過halcon界面的‘文件’項‘導出’成.cpp文件。

?

圖7 halcon生成C程序

Halcon標定程序

*Calibration 01: Code generated by Calibration 01

*讀入某個文件夾下的所有標定圖像

list_files ('D:/halconvc/img', ['files','follow_links'], ImageFiles)

tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm

|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)

*初始標定參數設置及定義標定板文件

TmpCtrl_ReferenceIndex := 0

TmpCtrl_PlateDescription := 'D:/calib/calplate.cpd'

StartParameters := [0.029,0,0,0,0,0,4.3e-006,4.3e-006,2592,1728,5184,3456]

TmpCtrl_FindCalObjParNames := 'sigma'

TmpCtrl_FindCalObjParValues := 1

?

* Calibration 01: Create calibration model for managing calibration data

create_calib_data ('calibration_object', 1, 1, CalibHandle)

set_calib_data_cam_param(CalibHandle,0,'area_scan_polynomial', StartParameters)

set_calib_data_calib_object (CalibHandle, 0, TmpCtrl_PlateDescription)

* Calibration 01: Collect mark positions and estimated poses for all plates

gen_empty_obj (Images)

for Index := 0 to |ImageFiles|-1 by 1

????read_image (Image, ImageFiles[Index])

????concat_obj(Images,Image,Images)

*提取圖像Images中標定板上的圓形標志來確定標定板的有效區域

????find_calib_object (Image, CalibHandle, 0, 0, Index, TmpCtrl_FindCalObjParNames, TmpCtrl_FindCalObjParValues)

endfor

* Calibration 01: Perform the actual calibration

calibrate_cameras (CalibHandle, TmpCtrl_Errors)

get_calib_data (CalibHandle, 'camera', 0, 'params', CameraParam)

?

???*將內外參保存到磁盤

write_cam_par(CameraParam,'D:/halconvc/campar.dat')

get_calib_data (CalibHandle, 'calib_obj_pose', [0, TmpCtrl_ReferenceIndex], 'pose', CameraPose)

set_origin_pose (CameraPose, 0, 0, 0.01, CameraPose)

write_pose(CameraPose,'D:/halconvc/campos.dat')

stop()

?

*另外讀取內外參文件的函數

read_cam_par ('D:/halconvc/campar.dat', CameraParam)

read_pose ('D:/halconvc/campos.dat', CameraPose)

1.2圖像矯正

Halcon中圖像矯正,接上述程序,以下介紹兩種方法。

使用內外參,即相機內參和位資

* ?goal: rectify images

* ?first determine parameters such that the entire image content is visible

* ?-> transform image boundary into world plane, determine smallest

* ????rectangle around it

*當設備固定后,位資是唯一的

select_obj(images,image,1)

get_image_pointer1(Image, Pointer, Type, Width, Height)

gen_rectangle1 (ImageRect, 0, 0, Height-1, Width-1)

gen_contour_region_xld (ImageRect, ImageBorder, 'border')

contour_to_world_plane_xld(ImageBorder, ImageBorderWCS, CameraParam,

CameraPose, 1)

smallest_rectangle1_xld (ImageBorderWCS, MinY, MinX, MaxY, MaxX)

set_origin_pose(CameraPose, MinX, MinY, 0.01, PoseForEntireImage)

image_points_to_world_plane(CameraParam,PoseForEntireImage,[Height/2, Height/2, Height/2+1], [Width/2, Width/2+1, Width/2], 1, WorldPixelX, WorldPixelY)

distance_pp(WorldPixelY[0], WorldPixelX[0], WorldPixelY[1], WorldPixelX[1],

????????????WorldLength1)

distance_pp(WorldPixelY[0], WorldPixelX[0], WorldPixelY[2], WorldPixelX[2],

????????????WorldLength2)

ScaleForSimilarPixelSize := (WorldLength1+WorldLength2)/2

* ?-> determine output image size such that entire input image fits into it

ExtentX := MaxX-MinX

ExtentY := MaxY-MinY

WidthRectifiedImage := ExtentX/ScaleForSimilarPixelSize

HeightRectifiedImage := ExtentY/ScaleForSimilarPixelSize

* ?create mapping with the determined parachuangjia

*創建一個投射圖,其描述圖像平面與坐標軸系統中平面Z為零之間的映射

gen_image_to_world_plane_map(Map, CameraParam, PoseForEntireImage, Width, Height, WidthRectifiedImage, HeightRectifiedImage, \

?????????????????????????????ScaleForSimilarPixelSize, 'bilinear')

clear_calib_data (CalibHandle)

?

* Map the images

for I := ?1 to |ImageFiles| by 1

??select_obj (Images, Img, I)

??map_image (Img, Map, ImageMapped)

??write_image (ImageMapped, 'jpg', 0, 'D:/halconvc/picture/'+I)

Endfor

②僅使用內參

read_image (Image,'D:/halconvc/img/IMG_00.JPG')

read_cam_par('D:/halconvc/campar.dat',CameraParam)

CarParamVirtualFixed:=CameraParam

*對于area(diversion)相機模型(7個參數)

change_radial_distortion_cam_par('adaptive',CameraParam,0,CarParamVirtualFixed)

*對于area(多項式)相機模型(12個參數)

change_radial_distortion_cam_par('adaptive',CameraParam,[0,0,0,0,0],CarParamVirtualFixed)


*上述相機模型選一種后進行下面的map_image

*創建一個投射圖,其描述圖像與其相應正在改變的徑向畸變,而對于12個參數的畸變包括徑向和切向畸變

gen_radial_distortion_map(Map,CameraParam,CarParamVirtualFixed,'bilinear')

map_image(Image,Map,ImageMapped)

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

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

相關文章

找尋一個郵箱

import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern;public class zhengze {public static void main(String[] args) { //1.創建一個正則表達式對象Pattern pPattern.compile("[0-9]{6}"); //2.獲得匹配器 String s…

先弄個XML解析器代碼抄一抄 慢慢研究 O(∩_∩)O哈哈~

出處:http://bbs.csdn.net/topics/390229172 已經自我放逐好幾年了.打算去上班得了.在最后的自由日子里,做點有意義的事吧... 先來下載地址 http://www.kuaipan.cn/file/id_12470514853353274.htm 已經在很多正式,非正式的場合…

紫書 例題8-10 UVa 714 (二分答案)

這道題讓最大值最小, 顯然是二分答案當題目求的是最大值最小, 最小值最大, 這個時候就要想到二分答案為什么可以二分答案呢, 因為這個時候解是單調性的, 如果簡單粗暴一點就全部枚舉一遍, 驗證答案。但是因…

was not declared in this scope

“was not declared in this scope”是一個錯誤信息,在編譯的時候會遇到。其含義為標識符在其出現的地方是未被定義的。 出現該錯誤的時候,會同時把未定義的變量名顯示出來。比如如下程序: int main(){ printf("%d",i);//這個i是…

函數參數的傳遞問題(一級指針和二級指針)

函數參數的傳遞問題(一級指針和二級指針) [轉]原以為自己對指針掌握了,卻還是對這個問題不太明白。請教! 程序1: void myMalloc(char *s) //我想在函數中分配內存,再返回 { s(char *) malloc(100); } void …

Win7下使用U盤安裝linux Ubuntu16.04雙系統圖文教程

Win7下使用U盤安裝linux Ubuntu16.04雙系統圖文教程 Ubuntu(友幫拓、優般圖、烏班圖)是一個以桌面應用為主的開源GNU/Linux操作系統,Ubuntu 是基于DebianGNU/Linux,支持x86、amd64(即x64)和ppc架構&#xf…

SynchronizationContext

SendOrPostCallback xxx vg > { Text "內部: "vg.ToString(); };dynamic vx new { a SynchronizationContext.Current, b xxx };Thread td new Thread(x >{dynamic tmp x;// SynchronizationContext ds x as SynchronizationContext;for (in…

CoDeSys的前世今生

工作以及網上看到不少人說,CoDeSys和西門子step7,在德國都屬于標準過程,牛逼的小朋友都可以用其編程,不知真假,相信無風不起浪,多少有些依據,看看國內清一色的日系編程…

UVALive 7324 ASCII Addition (模擬)

ASCII Addition題目鏈接: http://acm.hust.edu.cn/vjudge/contest/127407#problem/A Description Nowadays, there are smartphone applications that instantly translate text and even solve math problems if you just point your phone’s camera at them. You…

Eclipse中執行Ant腳本出現Could not find the main class的問題及解

試過了:https://blog.csdn.net/bookroader/article/details/2300337 但是不管用,偶然看到這篇沒有直接關系的 https://blog.csdn.net/jiuyueguang/article/details/9350753 聯想了一下。項目是JDK1.5,Eclipse是JDK1.8啟動,所以在R…

獲得變量的名稱獲得傳入參數的參數類型與堆棧中的函數名獲得變量的名稱

獲得變量的名稱 獲得變量的名稱函數 public static string GetVarName(Expression<Func<變量類型, 變量類型>> exp) public static string GetVarName_Int(Expression<Func<int, int>> exp){return ((MemberExpression)exp.Body).Member.Name;}使用時…

視頻通話研究002

還是關于視頻質量。經測試&#xff0c;在公網server使用SQCIF(128x98)進行視頻通話。2個client都是這個設置&#xff0c;感覺不出馬賽克&#xff0c;模糊嚴重&#xff0c;在一個手機client抓包&#xff0c;例如以下&#xff1a; 第1,2行是client發到server的數據&#xff1b;第…

實力打臉: 量子隱形傳輸與 “瞬間移動” 毫無關系

有兩個團隊已經在量子隱形傳輸研究領域創造了新的傳輸記錄&#xff1a;利用深不可測的量子力學知識將一個粒子的量子態迅速從一個位置遷移到另一個位置的粒子上。其中一個團隊采用這種方法&#xff0c;運用一種光學纖維將一個光子的量子態穿越加拿大西南部的一個城市&#xff0…

Android初級教程:使用xml序列器

之前備份短信的時候生成xml都是手動拼寫的&#xff0c;有一個問題&#xff1a;當短信里面存在</body>這樣的標簽的時候&#xff0c;最后結果就不是完整的xml文件&#xff0c;顯然出錯。但是&#xff0c;今天使用序列化器的方式&#xff0c;就能有效的解決上邊遇到的問題。…

架構師之我見

架構師之我見 2009-08-06 架構師是一個項目組的靈魂人物&#xff0c;他決定著整個系統的技術選型、整體架構以及模塊劃分&#xff0c;同時還可能擔當與領導層的溝通角色&#xff0c;從某種意義上來說&#xff0c;架構師在很大程度上決定著項目的成敗與否&#xff0c;正所謂火車…

KUKA 聲明變量時的幾點注意

臨時變量&#xff1a; 1、src文件中定義的局部變量&#xff0c;該種變量存在于內存中的棧上。子程序調用時&#xff0c;變量在棧上動態生成。調用結束后從棧中自動銷毀。 因為存在于棧上的原因&#xff0c;訪問該變量需要棧指針&#xff0c;所以該種變量無法在機器人程序運行時…

三個點擬合圓形的函數C#

三個點擬合圓形的函數 函數說明 public void FitCircleFromThreePoints(double 點1X, double 點1Y, double 點2X, double 點2Y, double 點3X, double 點3Y, out double 圓心X坐標, out double 圓心Y坐標, out double 圓形半徑大小)public void FitCircleFromThreePoints(doub…

poj3264Balanced Lineup(倍增ST表)

Balanced LineupTime Limit: 5000MS Memory Limit: 65536KTotal Submissions: 52328 Accepted: 24551Case Time Limit: 2000MSDescription For the daily milking, Farmer Johns N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to …

LightOJ1283 Shelving Books(DP)

題目 Source http://www.lightoj.com/volume_showproblem.php?problem1283 Description You are a librarian. You keep the books in a well organized form such that it becomes simpler for you to find a book and even they look better in the shelves. One day you ge…

量子傳輸技術轉移一個人需要4500萬億年

看過《星際迷航》的朋友一定不會忘記這句經典的臺詞&#xff1a;斯科蒂&#xff0c;將我傳輸過去&#xff01;其中涉及到量子隱形傳輸的技術&#xff0c;可以把物體從三維時空一處傳輸到另一處。但可惜的是&#xff0c;這種看著非常炫的技術或許根本無法實現。 到目前為止&…