[原創]移動相機九點標定工具原理及實現(包涵部分原始碼)

2022-07-22 18:01:35

1. 移動相機標定與固定相機的標定有什麼差異?

  • 書接上文 [原創]一種自動化九點標定工具原理(包涵部分原始碼)
  • 移動相機(眼在手上):相機安裝在龍門架的Z軸上
  • 相機拍照得出來來的位置與當前龍門架實際點位有關係,有什麼關係呢?答案:平移關係,只比固定相機多了一個平移關係
  • 怎麼理解呢?假如以相機中心點作為座標系T1原點,座標系T1和龍門架座標系G1只有平移關係。 而座標系T1內的影象座標系C1與龍門架座標系G1存在一個固定的仿射變換矩陣

2. 解決辦法?

  • 假如龍門架在G1點位,在此點位使用相機拍到一個mark點的影象座標為P1;放射變換矩陣為M1,而此mark點對應的真實龍門架座標為R1
  • 四者之間的關係為R1=P1*M1+G1
  • 通過上一篇文章描述方法,同樣利用旋轉方式獲取P1,只是操作方式稍微不同。

3. 詳細操作步驟?

  • 龍門架先吸取標定板到R1位置,放下標定板
  • 龍門架到達G1位置,拍照獲取到mark點位置P1.1
  • 龍門架再次到R1位置,吸取標定板,旋轉180度後放下標定板
  • 龍門架再次到達G1位置,拍照獲取到mark點位置P1.2
  • P1的影象座標為P1.1和P1.2的中心點
  • 到此,公式R1=P1*M1+G1的引數已經拿到R1,P1,G1。按照上述方式操作9次就可以計算出仿射變換矩陣M1了

4. 適用範圍

  • 此標定方式只適合類似於龍門架的頭部相機標定,不適合機械手裝置的頭部相機標定
  • 機械手頭部相機的標定除了平移關係外,還有旋轉關係。具體標定方式見下回分解

5. 原始碼

        private void updatePoiMatrix(Position pcbPoi,Position poi1, Position poi2,Position takePhotoPoi)
        {
            //更新對應的陣列
            imagePoiList.Add(new Position() { X = (poi1.X + poi2.X) / 2, Y = (poi1.Y + poi2.Y) / 2 });
            System.Windows.Point p1=new System.Windows.Point();
            p1.X = pcbPoi.X - takePhotoPoi.X;
            p1.Y = pcbPoi.Y - takePhotoPoi.Y;

            Position newDstPoi = new Position();
            newDstPoi.X = p1.X;
            newDstPoi.Y = p1.Y;
            robotPoiList.Add(newDstPoi);
        }
        private void btnSaveCalibration_Click(object sender, EventArgs e)
        {
            try
            {
                NcHelper.GetInstance().SaveMat(imagePoiList, robotPoiList, this.matPath);
            }
            catch (Exception ex)
            {
                this.printException(ex);
            }
        }
        
        public void SaveMat(List<Position> imageList, List<Position> robotPoiList, string path)
        {
            HTuple imageXList = new HTuple(), imageYList = new HTuple();
            HTuple robotXList = new HTuple(), robotYList = new HTuple();

            for (int i = 0; i < imageList.Count; i++)
            {
                imageXList[i] = imageList[i].X;
                imageYList[i] = imageList[i].Y;
                robotXList[i] = robotPoiList[i].X;
                robotYList[i] = robotPoiList[i].Y;
            }

            HTuple hv_HomMat2D = new HTuple(), hv_SerializedItemHandle = new HTuple();
            HTuple hv_FileHandle = new HTuple();
            ////標定
            hv_HomMat2D.Dispose();
            HOperatorSet.VectorToHomMat2d(imageXList, imageYList, robotXList, robotYList, out hv_HomMat2D);

            //儲存變換矩陣
            hv_SerializedItemHandle.Dispose();
            HOperatorSet.SerializeHomMat2d(hv_HomMat2D, out hv_SerializedItemHandle);
            hv_FileHandle.Dispose();
            HOperatorSet.OpenFile(path, "output_binary", out hv_FileHandle);
            HOperatorSet.FwriteSerializedItem(hv_FileHandle, hv_SerializedItemHandle);
            HOperatorSet.CloseFile(hv_FileHandle);

            imageXList.Dispose();
            imageYList.Dispose();
            robotXList.Dispose();
            robotYList.Dispose();
            hv_HomMat2D.Dispose();
            hv_SerializedItemHandle.Dispose();
            hv_FileHandle.Dispose();
        }

6. 後續計劃[敬請期待],如需完整程式碼請微信聯絡

  • 機械手頭部相機標定工具
  • 下相機定位演演算法
  • 基於頭部相機的載具定位演演算法
  • 基於頂部相機的塑盤取料演演算法
  • 基於頭部相機的檢測演演算法實現
  • 一種面向介面介面、依賴注入的運控框架的總體介紹及分層實現