機械手相機9點坐標標定-基於C#+EmguCV


        很多初學者,都對標定概念模糊不清,分不清坐標系之間的關系,搞不清相機標定和機械手相機標定有什么關系,想當初自己也是一個人摸索了很久,本文將盡量給大家解釋。

         我們通常所說的相機標定分為兩種,一種是相機參數的標定,這一般用到張氏標定法標定的作用是校正相機自身的畸變,利用校正得到的參數對圖形進行處理后再呈現出來。關於這方面的資料,網上大把,我也不再此說明。一般的機械手定位也不會進行這個標定,因為現在的相機畸變還是很小的,精度可以滿足大多數要求。

        本文要介紹的是第二種,相機和機械手之間的標定,作用:建立相機坐標系和機械手坐標系之間的關系,即給機械手裝上眼睛,讓它去哪就去哪。

         常用的方法是9點標定,所用到函數是EstimateRigidTransform,網上關於 estimateRigidTransform 的詳細說明很少,Emgucv的幾乎沒有。當時找了N久,一度以為opencv沒有坐標系轉換的算法,差點就投奔halcon去了,不得不說,opencv在機器視覺方面的應用是完全不如halcon的。EstimateRigidTransform有兩個方法。

           方法一:Mat EstimateRigidTransform(PointF[] sourcePoints, PointF[] destinationPoints, bool fullAffine);返回的是一個2*3的double的矩陣 。

第一個參數sourcePoints:換之前圖像上的點(相機坐標系下的點)

第二個參數destinationPoints:換之后圖像上的點(機械手坐標系下的點)

第三個參數fullAffine:  TRUE(全仿射變換,包括:rotation, translation, scaling,shearing,reflection)

                                      FALSE(帶有約束的仿射變換) 

           方法二:Mat EstimateRigidTransform(IInputArray src, IInputArray dst, bool fullAffine);   //返回的是圖像

第一個參數src:變換之前的圖像

第二個參數dst:變換之前的圖像

第三個參數fullAffine:  TRUE(全仿射變換,包括:rotation, translation, scaling,shearing,reflection)

                                      FALSE(帶有約束的仿射變換) 

        因為我們需要的是坐標點,所以選用第一個函數。采用9點標定是因為點數越多越精確,但也不是越多越好,因為點數越多標定也會越麻煩,所選取的9個點在相機中間不要太靠近邊緣,能夠照顧到要定位的點即可。最少需要機械手和相機系下各2組點。

標定步驟:

0.准備工作:相機位置,機械手位置全部固定好,標定針固定在機械手上,固定好后不能夠再移動。標定針的位置一定要與夾手或吸盤之內的工具同一位置高度。

1.制作標定板,條件不行的,用普通的紙繪制9個圓,打印出來就行。

2.將標定板放到相機下方,位置區域要與機械手工作的區域一樣,包括高度必須盡量一致,這是標定准確度的關鍵。

3.調整好相機焦距,拍照,然后識別9個點的坐標,關於如何找圓,opecv的霍夫變換找圓非常容易誤判,比較好的方法是采用輪廓找圓法。這個我也想寫篇博客講一講。

4.將機械手依次移動到9的圓的中心,記下機械手坐標

5.將機械手坐標destinationPoints與相機坐標sourcePoints代入方法EstimateRigidTransform,即可算出一個2*3的矩陣。

private void CalRobot()
{    
   Mat warpMat;
   warpMat = CvInvoke.EstimateRigidTransform(points_camera, points_robot, true);
   Image<Gray, float> img = warpMat.ToImage<Gray, float>();
   A = img.Data[0, 0, 0];
   B = img.Data[0, 1, 0];
   C = img.Data[0, 2, 0];
   D = img.Data[1, 0, 0];
   E = img.Data[1, 1, 0];
   F = img.Data[1, 2, 0];
}

6.根據所得到的標定參數,可將圖像下的所有坐標轉換為機器人的坐標,機器人即可移動到圖像上指定的位置。

 坐標轉換方法:

 public PointF TransformPoint(PointF pPoint)
 {
    //********************************************            
     // x = x'k*cost-y'k* sint+x0,
    // y = x'k*sint+y'k* cost+y0.
    //A = k*cost,B =-k* sint,C
    //D = k*sint,E = k* cost,F
    //********************************************* 
    PointF tPoint = new PointF();
    tPoint.X = Convert.ToSingle(A * pPoint.X + B * pPoint.Y + C);
    tPoint.Y = Convert.ToSingle(D * pPoint.X + E * pPoint.Y + F);
    return tPoint;
}

至此,標定結束,可以隨意玩耍機械手,對着物體拍張照,定位要夾取的點,然后根據以上標定得到的參數將換算為機械手坐標系下的坐標,然后將坐標通過通信協議傳送給機械手,就大功告成了!

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM