PythonでOpenCVを䜿甚したKinect v2キャリブレヌション

少し前に、レンゞチャネルを備えた光孊システムを必芁ずするいく぀かのプロゞェクトを開始し、そのためにKinect v2を䜿甚するこずにしたした。 プロゞェクトはPythonで実装されおいるため、最初にKinectをPythonで動䜜させおから調敎する必芁がありたした。



それ以前は、コンピュヌタヌビゞョン、OpenCV、Kinectを扱ったこずがありたせんでした。 たた、このすべおの経枈をどのように扱うかに぀いおの包括的な指瀺を芋぀けるこずができなかったため、最終的には秩序をいじらなければなりたせんでした。 そしお、この蚘事で埗た経隓を䜓系化するこずは間違いではないず刀断したした。 おそらく、それは䞀郚の患者にずっお有甚であるこずが刀明するでしょう。たた、レポヌト䜜成の目盛りずしお人気のある蚘事も必芁です。



画像



最小システム芁件 Windows 8以降、Kinect SDK 2.0、USB 3.0。



è¡šI. Kinect v2の機胜

解像床RGBカメラ、pix。 1920 x 1080
解像床赀倖線IRカメラ、pix。 512 x 424
RGBカメラの芖野角、º 84.1 x 53.8
IRカメラの芖野角、º 70.6 x 60.0
範囲の枬定範囲、m。 0.6-8.0 1
RGBカメラの撮圱呚波数、Hz 30
IRカメラの撮圱呚波数、Hz 30


1
情報は゜ヌスごずに異なりたす。 ここで圌らは玄0.5-4.5mず蚀っおいたすが、実際、私は玄0.6-8.0mを受け取りたした。



したがっお、次のタスクがありたした。



  1. PythonでKinectを取埗したす。
  2. RGBおよびIRカメラを范正したす。
  3. RGBフレヌムずIRフレヌムを組み合わせる機胜を実珟したす。
  4. 深床チャネルを范正したす。


次に、各ポむントに぀いお詳しく説明したす。



1. Kinect v2およびPython



前にも蚀ったように、私はコンピュヌタヌビゞョンを扱うビゞネスはありたせんでしたが、OpenCVラむブラリがなければどこにも存圚しないずいう噂がありたした。 たた、カメラのキャリブレヌション甚のモゞュヌル党䜓を備えおいるため、最初に行ったのは、Windows 8.1でPython 3をサポヌトするOpenCVをビルドするこずでした。 通垞、Windowsでのオヌプン゜ヌスプロゞェクトのアセンブリに䌎うトラブルはありたせんでしたが、開発者からの指瀺の䞀郚ずしお、すべおが特別な驚きなしで行われたした。

Kinectでは、もう少しいじらなければなりたせんでした。 公匏SDKは、C、C ++、およびJavaScriptのむンタヌフェむスのみをサポヌトしおいたす。 反察偎から行くず、OpenCVが3Dカメラからの入力をサポヌトしおいるこずがわかりたすが、カメラはOpenNIラむブラリず互換性がある必芁がありたす。 OpenNIはKinectをサポヌトしおいたすが、比范的最近のKinect v2はサポヌトしおいたせん。 しかし、芪切な人々がOpenNIでKinect v2のドラむバヌを䜜成したした。 動䜜し、NiViewerのデバむスのチャンネルからビデオを鑑賞するこずもできたすが、OpenCVで䜿甚するず゚ラヌが発生しおクラッシュしたす。 ただし、他の優秀な人々は、公匏SDKのPythonラッパヌを䜜成したした。 止たった。



2.カメラのキャリブレヌション



カメラは完璧ではなく、画像を歪め、キャリブレヌションが必芁です。 Kinectを枬定に䜿甚するには、RGBカメラず深床センサヌの䞡方でこれらの幟䜕孊的な歪みを陀去するずよいでしょう。 IRカメラは深床センサヌの受信機でもあるため、キャリブレヌションにIRフレヌムを䜿甚し、キャリブレヌション結果を䜿甚しお深床フレヌムから歪みを陀去できたす。



カメラのキャリブレヌションは、カメラの内郚パラメヌタヌ、぀たりカメラマトリックスず歪み係数を芋぀けるために実行されたす。



画像



カメラ行列は、次の圢匏の行列です。



どこで



 with u 、c v -䞻点の座暙光軞ず画像平面ずの亀点、理想的なカメラでは、画像の䞭心に正確に配眮されたすが、実際には䞭心からわずかにオフセットされたす;



f u 、f v-焊点距離f 、ピクセルの幅ず高さで枬定。



歪みには、攟射状歪みず接線歪みの2぀の䞻な皮類がありたす。



攟射状の歪み -レンズの攟物線圢状の䞍完党性の結果ずしおの画像の歪み。 攟射状の歪みによっお匕き起こされる歪みは、センサヌの光孊䞭心で0であり、端に向かっお増加したす。 通垞、攟射状の歪みは、画像の歪みに最も寄䞎したす。



接線方向の歪み -レンズの取り付けにおける゚ラヌが画像平面に平行に発生するこずによる画像の歪み。







歪みをなくすために、次の匏を䜿甚しおピクセルの座暙をカりントできたす。







ここで、 u、v は初期ピクセル䜍眮です。

 u 修正 、v 修正 -幟䜕孊的歪みを陀去した埌のピクセルの䜍眮、

k 1 、k 2 、k 3-攟射状歪み係数、

p 1 、p 2-接線歪み係数、

r 2 = u 2 + v 2 。



カメラパラメヌタヌ歪み係数、カメラマトリックスの枬定粟床は、再投圱誀差 ReEr、再投圱誀差 の平均倀によっお決たりたす。 ReErは、オブゞェクトの衚面䞊の点Pの画像平面䞊の投圱P 'ず、カメラパラメヌタヌを䜿甚しお歪みを陀去した埌に構築される同じ点Pの投圱P' 'ずの間の距離ピクセル単䜍です。



画像



暙準のカメラキャリブレヌション手順は、次の手順で構成されたす。



1チェス盀の既知のゞオメトリを䜿甚しお 、 オブゞェクトの異なる䜍眮で20〜30枚の写真を撮りたす。



画像



2画像内のオブゞェクトのキヌポむントを決定したす。



found, corners = cv2.findChessboardCorners(img, # PATTERN_SIZE,#  ,    6x8 flags)#  
      
      









3 ReErを最小化するような歪み係数を芋぀けたす。



 ReEr, camera_matrix, dist_coefs, rvecs, tvecs = cv2.calibrateCamera(obj_points,#       #(', y', z'=0) img_points,#    (u,v) (w, h),#  None,#      None, #      criteria = criteria,#   ReEr flags = flags)#     
      
      





この堎合、RGBカメラの平均ReEr倀は0.3ピクセルで、IRカメラの平均は0.15です。 歪み陀去の結果



 img = cv2.undistort(img, camera_matrix, dist_coefs)
      
      









3. 2台のカメラのフレヌムを結合する









ピクセルの深床Z座暙ず色の䞡方を取埗するには、たず深床フレヌムのピクセル座暙からIRカメラの3次元座暙に切り替える必芁がありたす[2]







ここで、 x 1 、y 1 、z 1 は、IRカメラの座暙系のポむントの座暙です。

z 1は深床センサヌから返された結果です。

 u 1 、v 1 -フレヌム深床䞊のピクセルの座暙、

c 1、u 、c 1、v -IRカメラの光孊䞭心の座暙、

f 1、u 、f 1、v -IRカメラの焊点距離の投圱。



次に、IRカメラの座暙系からRGBカメラの座暙系に移動する必芁がありたす。 これを行うには、䌝達ベクトルTを䜿甚しお原点を移動し、回転行列Rを䜿甚しお座暙系を回転する必芁がありたす。







次に、RGBカメラの3次元座暙系からRGBフレヌムのピクセル座暙に移動する必芁がありたす。







したがっお、これらすべおの倉換の埌、深床フレヌムのピクセル u 1 、v 1 に察しお、RGBフレヌム u 2 、v 2 の察応するピクセルのカラヌ倀を取埗できたす。







結果の画像でわかるように、画像は堎所によっお2倍になりたす。 公匏SDKのCoordinateMapperクラスを䜿甚するず、同じ効果が芋られたす。 ただし、画像に関心があるのが人物だけの堎合は、 bodyIndexFrame どのピクセルが人物に属し、どのピクセルが背景にあるかを知るKinectストリヌムを䜿甚しお、関心領域を匷調衚瀺し、ゎヌストを陀去できたす。







回転行列Rず䌝達ベクトルTを決定するには、2぀のチャンバヌのゞョむントキャリブレヌションを実行する必芁がありたす。 これを行うには、RGBカメラずIRカメラの䞡方の異なる䜍眮で既知のゞオメトリを持぀オブゞェクトの20から30枚の写真を撮る必芁がありたす。異なるカメラによる撮圱フレヌム間での倉䜍の可胜性を排陀するために、オブゞェクトを手に持たない方が良いです。 次に、OpenCVラむブラリのstereoCalibrate関数を䜿甚する必芁がありたす。 この関数は、キャリブレヌションオブゞェクトに察する各カメラの䜍眮を決定し、ReErを最小化する最初のカメラの座暙系から2番目のカメラの座暙系ぞの倉換を怜出したす。



 retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F = cv2.stereoCalibrate(pattern_points, #  #     (', y', z'=0) ir_img_points,#     (u1, v1) rgb_img_points, #   RGB  (u2, v2) irCamera['camera_matrix'],#   (  calibrateCamera), irCamera['dist_coefs'], #. .   (  calibrateCamera) rgbCamera['camera_matrix'], # RGB  (  calibrateCamera) rgbCamera['dist_coefs'], #. . RGB  (  calibrateCamera) image_size) #    ( )
      
      





そしお最終的に、 ReEr = 0.23になりたした。



4.深床チャネルのキャリブレヌション



Kinect深床センサヌは、深床぀たり、深床ではなく、距離ではなくZ座暙をmmで返したす。 しかし、これらの倀はどれほど正確ですか 出版物[2]から刀断するず、誀差は距離に応じお0.5〜3 cmになる可胜性があるため、深床チャネルを范正するこずは理にかなっおいたす。



この手順は、オブゞェクトたでの距離に応じお、Kinectのシステマティック゚ラヌ基準深床ずセンサヌによっお生成された深床の差を芋぀けるこずです。 このためには、参照深床を知る必芁がありたす。 最も明癜な方法は、カメラの平面に平行に平らなオブゞェクトを配眮し、定芏でその距離を枬定するこずです。 オブゞェクトを埐々に移動し、各距離で䞀連の枬定を行うこずにより、各距離の平均誀差を芋぀けるこずができたす。 しかし、第䞀に、それはあたり䟿利ではなく、第二に、䞀芋するず思われるよりも、比范的倧きなサむズの完党に平らなオブゞェクトを芋぀けお、カメラの平面に平行にするこずを保蚌するこずがより困難です。 したがっお、゚ラヌの蚈算基準ずしお、オブゞェクトの既知のゞオメトリによっお決定される深さを取るこずにしたした。



オブゞェクトのゞオメトリチェス盀のセルのサむズなどを把握し、カメラの平面に厳密に平行に配眮するず、次のようにオブゞェクトの深さを決定できたす。







ここで、 fは焊点距離

dは、カメラマトリックス䞊のキヌポむントの投圱間の距離です。

Dはオブゞェクトのキヌポむント間の距離です。

Zは、カメラの投圱の䞭心からオブゞェクトたでの距離です。







オブゞェクトが厳密に平行ではなく、カメラの平面に察しお特定の角床で配眮されおいる堎合、奥行きは、遠近法n点PnP問題の解に基づいお決定できたす[3]。 OpenCVラむブラリに実装されおいる倚くのアルゎリズムは、この問題の解決に専念しおいたす。これにより、倉換を芋぀けるこずができたす。 R、T | キャリブレヌションオブゞェクトの座暙系ずカメラ座暙系の間で、したがっお、カメラパラメヌタヌに正確な深床を決定したす。



 retval, R, T = cv2.solvePnP(obj_points[:, [0, 5, 42, 47]],#     img_points[:, [0, 5, 42, 47]], #     rgbCameraMatrix,#  rgbDistortion,#  flags= cv2.SOLVEPNP_UPNP)#  PnP R, jacobian = cv2.Rodrigues(R)#       for j in range(0, numberOfPoints): #     point = numpy.dot(rgb_obj_points[j], RT) + TT # !       , #      , ,      computedDistance[j] = point[0][2] * 1000 # Z-  
      
      





深床チャネルをキャリブレヌションするために、キャリブレヌションオブゞェクトの䞀連の調査を、〜7 cmのステップで〜0.7-2.6 mの距離で実行したした。 キャリブレヌションオブゞェクトは、可胜な限り「目で」カメラの平面に平行なフレヌムの䞭心に配眮されたした。 各距離で、RGBカメラで1ショット、深床センサヌで100ショットを撮圱したした。 センサヌからのデヌタは平均化され、RGBフレヌムに基づいおオブゞェクトのゞオメトリによっお決定される距離が暙準ずしお採甚されたした。 特定の距離でKinectセンサヌの深さを決定する際の平均誀差は、次のように決定されたした。







ここで、 z i RGBはゞオメトリのi番目のキヌポむントたでの距離です。

z i 深床 -深床センサヌに埓っお、i番目のキヌポむントたでの100フレヌムで平均化された距離、

Nは、オブゞェクト䞊のキヌポむントの数ですこの䟋では48。



次に、結果を補間するこずにより、距離から誀差関数を埗たした。







以䞋の図は、キャリブレヌションフレヌムの修正前埌の誀差の分垃を瀺しおいたす。 合蚈120,000の枬定倀が取埗されたした25の距離、それぞれに100の深床フレヌム、オブゞェクト䞊の48のキヌポむント。 修正前の誀差は17±9.95 mm平均±暙準偏差であり、-0.45±8.16 mmの埌でした。







次に、さたざたな䜍眮でのキャリブレヌションオブゞェクトの25のテストフレヌムRGBおよび深床が䜜成されたした。 合蚈1200の枬定25フレヌム、それぞれに48のキヌポむント。 修正前の誀差は7.41±6.32 mm平均±暙準偏差で、-3.12±5.50 mmの埌でした。 次の図は、テストフレヌムの修正前埌の゚ラヌの分垃を瀺しおいたす。







おわりに



したがっお、RGBカメラず深床センサヌの幟䜕孊的な歪みを陀去し、フレヌムを組み合わせる方法を孊び、深床を決定する粟床を改善したした。 このプロゞェクトのコヌドはこちらにありたす 。 私はそれが有甚であるこずが刀明するこずを願っおいたす。



この研究は、ロシア科孊財団プロゞェクト番号15-19-30012からの助成金で実斜されたした



゜ヌスのリスト



1. Kramer J. Hacking the Kinect / Apress。 2012. P. 130

2. Lachat E. et al。 近距離3DモデリングのためのKinect V2センサヌの最初の経隓//写真枬量、リモヌトセンシング、および空間情報科孊の囜際アヌカむブ。 2015幎。

3. Gao XS et al。 芖点3点問題の完党な゜リュヌション分類//パタヌン分析ずマシンむンテリゞェンスに関するIEEEトランザクション。 å·» 25. N 8.2003。P.930-943。



All Articles