22
33using NrealLightWithOpenCVForUnity . UnityUtils . Helper ;
44using NRKernal ;
5- using OpenCVForUnity . ArucoModule ;
65using OpenCVForUnity . Calib3dModule ;
76using OpenCVForUnity . CoreModule ;
87using OpenCVForUnity . ImgprocModule ;
98using OpenCVForUnity . UnityUtils ;
109using OpenCVForUnity . UnityUtils . Helper ;
10+ using OpenCVForUnity . ObjdetectModule ;
1111using System ;
1212using System . Collections . Generic ;
1313using UnityEngine ;
@@ -70,7 +70,7 @@ public class NrealArUcoExample : MonoBehaviour
7070 /// <summary>
7171 /// The dictionary identifier.
7272 /// </summary>
73- public int dictionaryId = Aruco . DICT_6X6_250 ;
73+ public int dictionaryId = Objdetect . DICT_6X6_250 ;
7474
7575 /// <summary>
7676 /// The length of the markers' side. Normally, unit is meters.
@@ -126,55 +126,25 @@ public class NrealArUcoExample : MonoBehaviour
126126 Matrix4x4 ARM ;
127127
128128 /// <summary>
129- /// The identifiers .
129+ /// The webcam texture to mat helper .
130130 /// </summary>
131- Mat ids ;
131+ NRCamTextureToMatHelper webCamTextureToMatHelper ;
132132
133133 /// <summary>
134- /// The corners .
134+ /// The image optimization helper .
135135 /// </summary>
136- List < Mat > corners ;
136+ ImageOptimizationHelper imageOptimizationHelper ;
137137
138- /// <summary>
139- /// The rejected corners.
140- /// </summary>
138+ // for CanonicalMarker.
139+ Mat ids ;
140+ List < Mat > corners ;
141141 List < Mat > rejectedCorners ;
142+ Dictionary dictionary ;
143+ ArucoDetector arucoDetector ;
142144
143- /// <summary>
144- /// The rvecs.
145- /// </summary>
146145 Mat rvecs ;
147-
148- /// <summary>
149- /// The tvecs.
150- /// </summary>
151146 Mat tvecs ;
152147
153- /// <summary>
154- /// The rot mat.
155- /// </summary>
156- Mat rotMat ;
157-
158- /// <summary>
159- /// The detector parameters.
160- /// </summary>
161- DetectorParameters detectorParams ;
162-
163- /// <summary>
164- /// The dictionary.
165- /// </summary>
166- Dictionary dictionary ;
167-
168- /// <summary>
169- /// The webcam texture to mat helper.
170- /// </summary>
171- NRCamTextureToMatHelper webCamTextureToMatHelper ;
172-
173- /// <summary>
174- /// The image optimization helper.
175- /// </summary>
176- ImageOptimizationHelper imageOptimizationHelper ;
177-
178148 Mat rgbMat4preview ;
179149 Texture2D texture ;
180150
@@ -349,12 +319,18 @@ public void OnWebCamTextureToMatHelperInitialized()
349319 Debug . Log ( "principalPoint " + principalPoint . ToString ( ) ) ;
350320 Debug . Log ( "aspectratio " + aspectratio [ 0 ] ) ;
351321
322+
352323 ids = new Mat ( ) ;
353324 corners = new List < Mat > ( ) ;
354325 rejectedCorners = new List < Mat > ( ) ;
355- rvecs = new Mat ( ) ;
356- tvecs = new Mat ( ) ;
357- rotMat = new Mat ( 3 , 3 , CvType . CV_64FC1 ) ;
326+ rvecs = new Mat ( 1 , 10 , CvType . CV_64FC3 ) ;
327+ tvecs = new Mat ( 1 , 10 , CvType . CV_64FC3 ) ;
328+ dictionary = Objdetect . getPredefinedDictionary ( dictionaryId ) ;
329+
330+ DetectorParameters detectorParams = new DetectorParameters ( ) ;
331+ detectorParams . set_useAruco3Detection ( true ) ;
332+ RefineParameters refineParameters = new RefineParameters ( 10f , 3f , true ) ;
333+ arucoDetector = new ArucoDetector ( dictionary , detectorParams , refineParameters ) ;
358334
359335
360336 transformationM = new Matrix4x4 ( ) ;
@@ -365,10 +341,6 @@ public void OnWebCamTextureToMatHelperInitialized()
365341 invertZM = Matrix4x4 . TRS ( Vector3 . zero , Quaternion . identity , new Vector3 ( 1 , 1 , - 1 ) ) ;
366342 //Debug.Log("invertZM " + invertZM.ToString());
367343
368- detectorParams = DetectorParameters . create ( ) ;
369- dictionary = Aruco . getPredefinedDictionary ( dictionaryId ) ;
370-
371-
372344 rgbMat4preview = new Mat ( ) ;
373345 }
374346
@@ -395,6 +367,10 @@ public void OnWebCamTextureToMatHelperDisposed()
395367
396368 hasUpdatedARTransformMatrix = false ;
397369
370+
371+ if ( arucoDetector != null )
372+ arucoDetector . Dispose ( ) ;
373+
398374 if ( ids != null )
399375 ids . Dispose ( ) ;
400376 foreach ( var item in corners )
@@ -411,8 +387,6 @@ public void OnWebCamTextureToMatHelperDisposed()
411387 rvecs . Dispose ( ) ;
412388 if ( tvecs != null )
413389 tvecs . Dispose ( ) ;
414- if ( rotMat != null )
415- rotMat . Dispose ( ) ;
416390
417391 if ( rgbMat4preview != null )
418392 rgbMat4preview . Dispose ( ) ;
@@ -503,40 +477,59 @@ private void ThreadWorker()
503477 private void DetectARUcoMarker ( )
504478 {
505479 // Detect markers and estimate Pose
506- // undistort image.
507480 Calib3d . undistort ( downScaleMat , downScaleMat , camMatrix , distCoeffs ) ;
508- // detect markers.
509- Aruco . detectMarkers ( downScaleMat , dictionary , corners , ids , detectorParams , rejectedCorners ) ;
481+ arucoDetector . detectMarkers ( downScaleMat , corners , ids , rejectedCorners ) ;
510482
511483 if ( applyEstimationPose && ids . total ( ) > 0 )
512484 {
513- Aruco . estimatePoseSingleMarkers ( corners , markerLength , camMatrix , distCoeffs , rvecs , tvecs ) ;
514-
515- for ( int i = 0 ; i < ids . total ( ) ; i ++ )
485+ if ( rvecs . cols ( ) < ids . total ( ) )
486+ rvecs . create ( 1 , ( int ) ids . total ( ) , CvType . CV_64FC3 ) ;
487+ if ( tvecs . cols ( ) < ids . total ( ) )
488+ tvecs . create ( 1 , ( int ) ids . total ( ) , CvType . CV_64FC3 ) ;
489+
490+ using ( MatOfPoint3f objPoints = new MatOfPoint3f (
491+ new Point3 ( - markerLength / 2f , markerLength / 2f , 0 ) ,
492+ new Point3 ( markerLength / 2f , markerLength / 2f , 0 ) ,
493+ new Point3 ( markerLength / 2f , - markerLength / 2f , 0 ) ,
494+ new Point3 ( - markerLength / 2f , - markerLength / 2f , 0 )
495+ ) )
516496 {
517- //This example can display ARObject on only first detected marker.
518- if ( i == 0 )
497+ for ( int i = 0 ; i < ids . total ( ) ; i ++ )
519498 {
520- // Convert to unity pose data.
521- double [ ] rvecArr = new double [ 3 ] ;
522- rvecs . get ( 0 , 0 , rvecArr ) ;
523- double [ ] tvecArr = new double [ 3 ] ;
524- tvecs . get ( 0 , 0 , tvecArr ) ;
525- PoseData poseData = ARUtils . ConvertRvecTvecToPoseData ( rvecArr , tvecArr ) ;
499+ using ( Mat rvec = new Mat ( 3 , 1 , CvType . CV_64FC1 ) )
500+ using ( Mat tvec = new Mat ( 3 , 1 , CvType . CV_64FC1 ) )
501+ using ( Mat corner_4x1 = corners [ i ] . reshape ( 2 , 4 ) ) // 1*4*CV_32FC2 => 4*1*CV_32FC2
502+ using ( MatOfPoint2f imagePoints = new MatOfPoint2f ( corner_4x1 ) )
503+ {
504+ // Calculate pose for each marker
505+ Calib3d . solvePnP ( objPoints , imagePoints , camMatrix , distCoeffs , rvec , tvec ) ;
506+
507+ rvec . reshape ( 3 , 1 ) . copyTo ( new Mat ( rvecs , new OpenCVForUnity . CoreModule . Rect ( 0 , i , 1 , 1 ) ) ) ;
508+ tvec . reshape ( 3 , 1 ) . copyTo ( new Mat ( tvecs , new OpenCVForUnity . CoreModule . Rect ( 0 , i , 1 , 1 ) ) ) ;
526509
527- // Create transform matrix.
528- transformationM = Matrix4x4 . TRS ( poseData . pos , poseData . rot , Vector3 . one ) ;
510+ // This example can display the ARObject on only first detected marker.
511+ if ( i == 0 )
512+ {
513+ // Convert to unity pose data.
514+ double [ ] rvecArr = new double [ 3 ] ;
515+ rvec . get ( 0 , 0 , rvecArr ) ;
516+ double [ ] tvecArr = new double [ 3 ] ;
517+ tvec . get ( 0 , 0 , tvecArr ) ;
518+ PoseData poseData = ARUtils . ConvertRvecTvecToPoseData ( rvecArr , tvecArr ) ;
529519
530- // Right-handed coordinates system (OpenCV) to left-handed one (Unity)
531- // https://stackoverflow.com/questions/30234945/change-handedness-of-a-row-major-4x4-transformation-matrix
532- ARM = invertYM * transformationM * invertYM ;
520+ // Create transform matrix.
521+ transformationM = Matrix4x4 . TRS ( poseData . pos , poseData . rot , Vector3 . one ) ;
533522
534- // Apply Y-axis and Z-axis refletion matrix. (Adjust the posture of the AR object)
535- ARM = ARM * invertYM * invertZM ;
523+ // Right-handed coordinates system (OpenCV) to left-handed one (Unity)
524+ // https://stackoverflow.com/questions/30234945/change-handedness-of-a-row-major-4x4-transformation-matrix
525+ ARM = invertYM * transformationM * invertYM ;
536526
537- hasUpdatedARTransformMatrix = true ;
527+ // Apply Y-axis and Z-axis refletion matrix. (Adjust the posture of the AR object)
528+ ARM = ARM * invertYM * invertZM ;
538529
539- break ;
530+ hasUpdatedARTransformMatrix = true ;
531+ }
532+ }
540533 }
541534 }
542535 }
@@ -550,7 +543,7 @@ private void OnDetectionDone()
550543
551544 if ( ids . total ( ) > 0 )
552545 {
553- Aruco . drawDetectedMarkers ( rgbMat4preview , corners , ids , new Scalar ( 0 , 255 , 0 ) ) ;
546+ Objdetect . drawDetectedMarkers ( rgbMat4preview , corners , ids , new Scalar ( 0 , 255 , 0 ) ) ;
554547
555548 if ( applyEstimationPose )
556549 {
@@ -661,7 +654,7 @@ public void OnStopButtonClick()
661654 /// </summary>
662655 public void OnChangeCameraButtonClick ( )
663656 {
664- webCamTextureToMatHelper . requestedIsFrontFacing = ! webCamTextureToMatHelper . IsFrontFacing ( ) ;
657+ webCamTextureToMatHelper . requestedIsFrontFacing = ! webCamTextureToMatHelper . requestedIsFrontFacing ;
665658 }
666659
667660 /// <summary>
0 commit comments