机器视觉标定(calibration)关键尝试(标定的重要意义度量衡)(A)
learning opencv開篇便談視覺病態畸變的問題,我們人類世界的進步和度量衡有莫大的關系,而工業自動化以及人工智能(AI)的度量衡又是什么呢?那就是標定,其意義是非凡的,也可以說是偉大的,人工智能對度量衡要求低的很,而識別是重頭戲,但是沒有度量衡的工業自動化,那是不可想象的,這就是標定,沒有標定度量,一切都是扯淡(蛋?),更就談不上準確度了。可以這樣毫不遜色的說,標定是工業自動化技術應用的基礎。你想一想,在年輕的AI面前,自動化已經走了很久了。但是AI給自動化識別也帶來了強勁的動力,自動化的識別逐漸在向AI識別演變。
? ? ? ? 舉一個和標定相關的例子,有很多人用過激光打字(標)在銘牌上,一般人都不會感到標定的存在,原因是,這樣的工作對精度要求不高,我搞過一段時間自動化控制激光應用,正是這樣的經歷更加確認了我對標定的熱情,研究是這樣的,在偏離激光鏡頭中心一定距離的地方,有一個九宮格,里邊有九個圓,你讓激光去填充這九個圓,你會發現,越遠偏差越大,每列都不一樣,當你給每列嘗試補償一個固定偏差,漸漸這個值穩定后,激光填充的圓也就飽滿了,想說明什么呢?當你把整個鏡頭(場鏡頭)下整個能打標填充的區域的固定偏差都做出來,那么你想要的激光打標準確度全都有了,這是我最初發現標定最笨的方法,但是他解決了激光鏡頭給精度帶來的偏差,我也發現了標定原來是這么一回事。搞激光的,通常使用矯正鏡頭(標定)的方法是,平面上放上一張白紙,讓激光去打一個矩形,剛開始肯定是桶狀的,很像電視機的桶狀失真,然后你去調整激光的參數,直至打標一個ok的矩形,那么在矩形區域內,你打標,至少是線性的。(下圖為九宮格測試激光畸變)
? ? ? ? 用習慣了機器視覺的標定,你會很驚詫激光的標定,世間變化真神奇,變個樣,就不認識了,這能叫學會了嗎?當你要求更高精度的標定時,你就會用機器視覺的相機標定去要求激光,標定到底是什么?實質就是校正失真的鏡頭,相機的,激光的,那么有沒有比剛才標定激光好一些的方法,有,這就是泰勒級數(多項式逼近)上場的時候了。
? ? ? 因為鏡頭基本都是中心對稱的,參考learning opencv的標定,泰勒級數f(r)=a0+a1*r+a2*r*r+...,r以鏡頭中心為圓的半徑,f(0)=0,所以a0=0;因為f(-r)=f(r),所以f(r)實質等于a2*r^2+a4*r^4+...,也就是說,泰勒級數的偶數項有意義,,?以上泰勒級數描述的鏡頭畸變被定義為徑向畸變(可不可以這樣理解?過圓心(鏡頭中心)的直徑上的畸變),我們的標定也只談徑向畸變,起拋磚引玉的作用。所以learning opencv給出這樣的計算公式:xc=x*(1+k1*r^2+k2*r^2*r^2+...),k1和k2為徑向畸變參數。而我令z=(1+k1*r^2+k2*r^2*r^2+...),在xc和x已知情況下z=xc/x(z顯然是大于1的,故桶形畸變中xc是亞像素角點,即畸變點,x為標準點,參考點),程序中我只求z,不求k1,k2.
以下是C#代碼,我們這里直接使用hariss亞像素角點提供的結果,這個已講過,此處不再重復,另外這里使用黑白棋盤格標定片。(棋盤格見下圖)
? ? ? ? ? ? int cx = 1024 / 2; int cy = 768 / 2;//此處舉例為1024*768相機,即80萬像素。
? ? ? ? ? ? double A = 0; double B = 0; double C = 0; double D = 0;
? ? ? ? ? ? List<Point> correct=new List<Point>();
? ? ? ? ? ? correct.Add(new Point(15,11));//以下只示范了左上角16個亞像素角點來求徑向畸變參數
? ? ? ? ? ? ?correct.Add(new Point(75,11));//
? ? ? ? ? ? ?correct.Add(new Point(135,11));//
? ? ? ? ? ? ?correct.Add(new Point(195,11));//
? ? ? ? ? ? ?correct.Add(new Point(15,71));//? ? ? ? ?15? 75? 135? 195
? ? ? ? ? ? ?correct.Add(new Point(75,71));//? ? 11? 一? 二? ?三? ? ?四
? ? ? ? ? ? ?correct.Add(new Point(135,71));//? 71? 五? ?六? 七? ? ?八
? ? ? ? ? ? ?correct.Add(new Point(195,71));//130? 九? ?十? ?11? ?12
? ? ? ? ? ? ?correct.Add(new Point(15,130));//189? 十3? 14? 15? ?16
? ? ? ? ? ? ?correct.Add(new Point(75,130));
? ? ? ? ? ? ?correct.Add(new Point(135,130));
? ? ? ? ? ? ?correct.Add(new Point(195,130));
? ? ? ? ? ? ?correct.Add(new Point(15,189));
? ? ? ? ? ? ?correct.Add(new Point(75,189));
? ? ? ? ? ? ?correct.Add(new Point(135,189));
? ? ? ? ? ? ?correct.Add(new Point(195,189));
? ? ? ? ? ? ?for (int m = 0; m < jibianyong1.Count; m++)// jibianyong1.Count=16
? ? ? ? ? ? ?{//correct為x//jibianyong1為亞像素角點為xc
? ? ? ? ? ? ? ? ?A += (jibianyong1[m].X - cx) * (correct[m].X - cx);
? ? ? ? ? ? ? ? ?B += (correct[m].X - cx) * (correct[m].X - cx);
? ? ? ? ? ? ? ? ?C += (jibianyong1[m].Y - cy) * (correct[m].Y - cy);
? ? ? ? ? ? ? ? ?D += (correct[m].Y - cy) * (correct[m].Y - cy);
? ? ? ? ? ? ?}
? ? ? ? ? ? double 徑向參數 = A / B;//xc*x/(x*x)如此處理,不會出現負號
? ? ? ? ? ? double 徑向參數1 = C/ D;//這里使用了兩次求平均值的方法,改進版本用最小二乘法
? ? ? ? ? ? double pingjun = (徑向參數?+徑向參數1) / 2;
? ? ? ? ? ? byte[] buffer24 = new byte[1024*768*3];
? ? ? ? ? ? for (int j = 0; j < 768; j++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? for (int i = 0; i < 1024; i = i + 1)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? int xcorrect = 0, ycorrect = 0;
? ? ? ? ? ? ? ? ? ? xcorrect = cx + (int)((i - cx) / pingjun);
? ? ? ? ? ? ? ? ? ? ycorrect = cy + (int)((j - cy) / pingjun);
? ? ? ? ? ? ? ? ? ? //2,再賦值
? ? ? ? ? ? ? ? ? ? buffer24[ycorrect * 1024 * 3 + xcorrect * 3] = rgbValues[j * 1024 * 3 + i * 3];
? ? ? ? ? ? ? ? ? ? buffer24[ycorrect * 1024 * 3 + xcorrect * 3 + 1] = rgbValues[j * 1024 * 3 + i * 3 + 1];
? ? ? ? ? ? ? ? ? ? buffer24[ycorrect * 1024 * 3 + xcorrect * 3 + 2] = rgbValues[j * 1024 * 3 + i * 3 + 2];
? ? ? ? ? ? ? ? }//完成圖像校正
? ? ? ? ? ? }//注釋,如果不說明,所有圖像均以buffer【y*w+x】代替
機器視覺中,標定板一般有兩種,另外一種標定板是九宮格上的'十'字交叉全部換成圓(我們給他個名字吧,就叫象棋標定板(以此紀念青騷年時對象棋的熱愛),是否與棋盤格很對稱?),我們可以使用前面講過的方法來找到圓心,方法一,找斑的方法,方法二,使用找圓工具匹配的方法,有了圓心(相當以上亞像素角點),就可以用上面相同的方法求徑向畸變參數,然后來校正圖像。在工業上,標定通常使用自動化方式,手動也可以(像激光那樣),但是會太麻煩。
標定一般為工程提供三項便利:1,坐標系;2,比例尺;3,圖像校正(鏡頭校正)。提個問題?我們的眼睛看到的世界是真的?還是畸變的?顯然,眼睛中心看到的是真實的,而,其他就不可靠。
讓你再一次驚詫機器視覺標定與learning opencv計算機視覺標定(數學設想推理復雜度)的巨大差別。你可以看到工業機器視覺極大的標準化帶來的便利(基本消除病態視覺)。什么是工業機器視覺極大的標準化?有必要解釋一下:只要你做過機器視覺項目,你會發現,標定幾乎可以忽略,但并不是說沒有標定,只是你沒發覺,他在你所有的硬件選型中已經被消化掉了,一般我們選的鏡頭,幾乎工作在無畸變狀態,在這里你就可以看到別人制定工業機器視覺標準的用苦良心,不是隨便一個相機鏡頭就可以在工業上用,這里邊的心血以價格的溢出而體現,這也是用苦良心的回報。這也是機器視覺大面積應用的基礎,計算機視覺以learning opencv的方式展現,看是美好的未來AI世界,卻是舉步維艱,當你習慣了機器視覺的簡單,要改變,必須挖掘這種簡單習慣(簡單,只是有人負重前行,消除了復雜度,簡單沒那么簡單,當你負重前行的時候)。所有的隱形,并非能掩蓋標定度量衡的偉大意義。
待續(慢慢來!...........)每天一點小改變?
我的郵箱liuganggang_1978@163.com;734523623@qq.com
總結
以上是生活随笔為你收集整理的机器视觉标定(calibration)关键尝试(标定的重要意义度量衡)(A)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 离散小波变换公式_一维离散小波
- 下一篇: 职场小白做短视频,用好了这些辅助工具,每