Skip to content

Commit 6cfe752

Browse files
committed
Changed to use "HololensCameraStream" asset.
1 parent 7a1c365 commit 6cfe752

26 files changed

+1785
-415
lines changed

Assets/HoloLensWithOpenCVForUnityExample/HoloLensArUcoExample/HoloLensArUcoExample.cs

Lines changed: 150 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace HoloLensWithOpenCVForUnityExample
1818
/// An example of marker based AR using OpenCVForUnity on Hololens.
1919
/// Referring to https://github.com/opencv/opencv_contrib/blob/master/modules/aruco/samples/detect_markers.cpp.
2020
/// </summary>
21-
[RequireComponent(typeof(WebCamTextureToMatHelper))]
21+
[RequireComponent(typeof(HololensCameraStreamToMatHelper))]
2222
public class HoloLensArUcoExample : MonoBehaviour
2323
{
2424
[HeaderAttribute ("Preview")]
@@ -54,12 +54,6 @@ public class HoloLensArUcoExample : MonoBehaviour
5454
/// </summary>
5555
public bool applyEstimationPose = true;
5656

57-
/// <summary>
58-
/// The downscale ratio.
59-
/// </summary>
60-
[TooltipAttribute("Factor by which the image will be scaled down before detection.")]
61-
public float downscaleRatio = 3;
62-
6357
/// <summary>
6458
/// The dictionary identifier.
6559
/// </summary>
@@ -153,8 +147,12 @@ public class HoloLensArUcoExample : MonoBehaviour
153147
/// <summary>
154148
/// The webcam texture to mat helper.
155149
/// </summary>
156-
WebCamTextureToMatHelper webCamTextureToMatHelper;
150+
HololensCameraStreamToMatHelper webCamTextureToMatHelper;
157151

152+
/// <summary>
153+
/// The image optimization helper.
154+
/// </summary>
155+
ImageOptimizationHelper imageOptimizationHelper;
158156

159157
Mat grayMat;
160158
Mat rgbMat4preview;
@@ -175,12 +173,9 @@ public class HoloLensArUcoExample : MonoBehaviour
175173
double distCoeffs4 = 0.0;//tangential distortion coefficient p2.
176174
double distCoeffs5 = -0.2388065;//radial distortion coefficient k3.
177175

178-
bool isDetecting = false;
179-
bool hasUpdatedARTransformMatrix = false;
180176
readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
181177
System.Object sync = new System.Object ();
182-
Mat rgbaMat4Thread;
183-
Mat downScaleRgbaMat;
178+
Mat downScaleFrameMat;
184179

185180
bool _isThreadRunning = false;
186181
bool isThreadRunning {
@@ -190,15 +185,33 @@ bool isThreadRunning {
190185
_isThreadRunning = value; }
191186
}
192187

188+
bool _isDetecting = false;
189+
bool isDetecting {
190+
get { lock (sync)
191+
return _isDetecting; }
192+
set { lock (sync)
193+
_isDetecting = value; }
194+
}
195+
196+
bool _hasUpdatedARTransformMatrix = false;
197+
bool hasUpdatedARTransformMatrix {
198+
get { lock (sync)
199+
return _hasUpdatedARTransformMatrix; }
200+
set { lock (sync)
201+
_hasUpdatedARTransformMatrix = value; }
202+
}
203+
193204
// Use this for initialization
194205
void Start ()
195206
{
196-
if (downscaleRatio < 1)
197-
downscaleRatio = 1;
198-
199207
displayCameraPreviewToggle.isOn = displayCameraPreview;
200208

201-
webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper> ();
209+
imageOptimizationHelper = gameObject.GetComponent<ImageOptimizationHelper> ();
210+
webCamTextureToMatHelper = gameObject.GetComponent<HololensCameraStreamToMatHelper> ();
211+
#if NETFX_CORE
212+
webCamTextureToMatHelper.frameMatAcquired += OnFrameMatAcquired;
213+
#endif
214+
202215
webCamTextureToMatHelper.Initialize ();
203216
}
204217

@@ -209,22 +222,23 @@ public void OnWebCamTextureToMatHelperInitialized ()
209222
{
210223
Debug.Log ("OnWebCamTextureToMatHelperInitialized");
211224

212-
Mat webCamTextureMat = webCamTextureToMatHelper.GetMat ();
225+
Mat webCamTextureMat = imageOptimizationHelper.GetDownScaleMat(webCamTextureToMatHelper.GetMat ());
213226

214227
Debug.Log ("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
215228

216-
float width = Mathf.Round(webCamTextureMat.width() / downscaleRatio);
217-
float height = Mathf.Round(webCamTextureMat.height() / downscaleRatio);
229+
float width = webCamTextureMat.width();
230+
float height = webCamTextureMat.height();
218231

219232
texture = new Texture2D ((int)width, (int)height, TextureFormat.RGB24, false);
233+
220234
previewQuad.GetComponent<MeshRenderer>().material.mainTexture = texture;
221235
previewQuad.transform.localScale = new Vector3 (1, height/width, 1);
222236
previewQuad.SetActive (displayCameraPreview);
223237

224238
double fx = this.fx;
225239
double fy = this.fy;
226-
double cx = this.cx / downscaleRatio;
227-
double cy = this.cy / downscaleRatio;
240+
double cx = this.cx / imageOptimizationHelper.downscaleRatio;
241+
double cy = this.cy / imageOptimizationHelper.downscaleRatio;
228242

229243
camMatrix = new Mat (3, 3, CvType.CV_64FC1);
230244
camMatrix.put (0, 0, fx);
@@ -263,7 +277,7 @@ public void OnWebCamTextureToMatHelperInitialized ()
263277
Debug.Log ("aspectratio " + aspectratio [0]);
264278

265279

266-
grayMat = new Mat (webCamTextureMat.rows (), webCamTextureMat.cols (), CvType.CV_8UC3);
280+
grayMat = new Mat ();
267281
ids = new Mat ();
268282
corners = new List<Mat> ();
269283
rejected = new List<Mat> ();
@@ -288,9 +302,8 @@ public void OnWebCamTextureToMatHelperInitialized ()
288302
if (webCamTextureToMatHelper.GetWebCamDevice ().isFrontFacing) {
289303
webCamTextureToMatHelper.flipHorizontal = true;
290304
}
291-
292-
rgbaMat4Thread = new Mat ();
293-
downScaleRgbaMat = new Mat ();
305+
306+
downScaleFrameMat = new Mat ((int)height, (int)width, CvType.CV_8UC4);
294307
rgbMat4preview = new Mat ();
295308
}
296309

@@ -301,7 +314,12 @@ public void OnWebCamTextureToMatHelperDisposed ()
301314
{
302315
Debug.Log ("OnWebCamTextureToMatHelperDisposed");
303316

317+
#if !NETFX_CORE
304318
StopThread ();
319+
lock (sync) {
320+
ExecuteOnMainThread.Clear ();
321+
}
322+
#endif
305323

306324
if (grayMat != null)
307325
grayMat.Dispose ();
@@ -322,9 +340,6 @@ public void OnWebCamTextureToMatHelperDisposed ()
322340
if (rotMat != null)
323341
rotMat.Dispose ();
324342

325-
if (rgbaMat4Thread != null)
326-
rgbaMat4Thread.Dispose ();
327-
328343
if (rgbMat4preview != null)
329344
rgbMat4preview.Dispose ();
330345
}
@@ -337,6 +352,104 @@ public void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.Err
337352
Debug.Log ("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
338353
}
339354

355+
#if NETFX_CORE
356+
public void OnFrameMatAcquired (Mat bgraMat, Matrix4x4 projectionMatrix, Matrix4x4 cameraToWorldMatrix)
357+
{
358+
downScaleFrameMat = imageOptimizationHelper.GetDownScaleMat (bgraMat);
359+
360+
if (enableDetection ) {
361+
362+
Imgproc.cvtColor (downScaleFrameMat, grayMat, Imgproc.COLOR_BGRA2GRAY);
363+
364+
// Detect markers and estimate Pose
365+
Aruco.detectMarkers (grayMat, dictionary, corners, ids, detectorParams, rejected, camMatrix, distCoeffs);
366+
367+
if (applyEstimationPose && ids.total () > 0){
368+
Aruco.estimatePoseSingleMarkers (corners, markerLength, camMatrix, distCoeffs, rvecs, tvecs);
369+
370+
for (int i = 0; i < ids.total (); i++) {
371+
372+
//This example can display ARObject on only first detected marker.
373+
if (i == 0) {
374+
375+
// Position
376+
double[] tvec = tvecs.get (i, 0);
377+
378+
// Rotation
379+
double[] rv = rvecs.get (i, 0);
380+
Mat rvec = new Mat (3, 1, CvType.CV_64FC1);
381+
rvec.put (0, 0, rv [0]);
382+
rvec.put (1, 0, rv [1]);
383+
rvec.put (2, 0, rv [2]);
384+
Calib3d.Rodrigues (rvec, rotMat);
385+
386+
transformationM.SetRow (0, new Vector4 ((float)rotMat.get (0, 0) [0], (float)rotMat.get (0, 1) [0], (float)rotMat.get (0, 2) [0], (float)tvec [0]));
387+
transformationM.SetRow (1, new Vector4 ((float)rotMat.get (1, 0) [0], (float)rotMat.get (1, 1) [0], (float)rotMat.get (1, 2) [0], (float)tvec [1]));
388+
transformationM.SetRow (2, new Vector4 ((float)rotMat.get (2, 0) [0], (float)rotMat.get (2, 1) [0], (float)rotMat.get (2, 2) [0], (float)(tvec [2] / imageOptimizationHelper.downscaleRatio)));
389+
390+
transformationM.SetRow (3, new Vector4 (0, 0, 0, 1));
391+
392+
lock (sync){
393+
// Right-handed coordinates system (OpenCV) to left-handed one (Unity)
394+
ARM = invertYM * transformationM;
395+
396+
// Apply Z axis inverted matrix.
397+
ARM = ARM * invertZM;
398+
}
399+
400+
hasUpdatedARTransformMatrix = true;
401+
402+
break;
403+
}
404+
}
405+
}
406+
}
407+
408+
Mat rgbMat4preview = null;
409+
if (displayCameraPreview) {
410+
rgbMat4preview = new Mat ();
411+
Imgproc.cvtColor (downScaleFrameMat, rgbMat4preview, Imgproc.COLOR_BGRA2RGB);
412+
413+
if (ids.total () > 0) {
414+
Aruco.drawDetectedMarkers (rgbMat4preview, corners, ids, new Scalar (255, 0, 0));
415+
416+
for (int i = 0; i < ids.total (); i++) {
417+
Aruco.drawAxis (rgbMat4preview, camMatrix, distCoeffs, rvecs, tvecs, markerLength * 0.5f);
418+
}
419+
}
420+
}
421+
422+
423+
UnityEngine.WSA.Application.InvokeOnAppThread(() => {
424+
425+
if (!webCamTextureToMatHelper.IsPlaying ()) return;
426+
427+
if (displayCameraPreview) {
428+
OpenCVForUnity.Utils.fastMatToTexture2D (rgbMat4preview, texture);
429+
}
430+
431+
if (applyEstimationPose) {
432+
if (hasUpdatedARTransformMatrix) {
433+
hasUpdatedARTransformMatrix = false;
434+
435+
lock (sync){
436+
// Apply camera transform matrix.
437+
ARM = arCamera.transform.localToWorldMatrix * ARM;
438+
ARUtils.SetTransformFromMatrix (arGameObject.transform, ref ARM);
439+
}
440+
}
441+
}
442+
443+
bgraMat.Dispose ();
444+
if (rgbMat4preview != null){
445+
rgbMat4preview.Dispose();
446+
}
447+
448+
}, false);
449+
}
450+
451+
#else
452+
340453
// Update is called once per frame
341454
void Update ()
342455
{
@@ -351,7 +464,7 @@ void Update ()
351464
if (enableDetection && !isDetecting ) {
352465
isDetecting = true;
353466

354-
rgbaMat4Thread = webCamTextureToMatHelper.GetMat ();
467+
downScaleFrameMat = imageOptimizationHelper.GetDownScaleMat (webCamTextureToMatHelper.GetMat ());
355468

356469
StartThread (ThreadWorker);
357470
}
@@ -398,12 +511,7 @@ private void ThreadWorker()
398511

399512
private void DetectARUcoMarker()
400513
{
401-
if (downscaleRatio == 1) {
402-
downScaleRgbaMat = rgbaMat4Thread;
403-
} else {
404-
Imgproc.resize (rgbaMat4Thread, downScaleRgbaMat, new Size (), 1.0 / downscaleRatio, 1.0 / downscaleRatio, Imgproc.INTER_LINEAR);
405-
}
406-
Imgproc.cvtColor (downScaleRgbaMat, grayMat, Imgproc.COLOR_RGBA2GRAY);
514+
Imgproc.cvtColor (downScaleFrameMat, grayMat, Imgproc.COLOR_RGBA2GRAY);
407515

408516
// Detect markers and estimate Pose
409517
Aruco.detectMarkers (grayMat, dictionary, corners, ids, detectorParams, rejected, camMatrix, distCoeffs);
@@ -429,7 +537,7 @@ private void DetectARUcoMarker()
429537

430538
transformationM.SetRow (0, new Vector4 ((float)rotMat.get (0, 0) [0], (float)rotMat.get (0, 1) [0], (float)rotMat.get (0, 2) [0], (float)tvec [0]));
431539
transformationM.SetRow (1, new Vector4 ((float)rotMat.get (1, 0) [0], (float)rotMat.get (1, 1) [0], (float)rotMat.get (1, 2) [0], (float)tvec [1]));
432-
transformationM.SetRow (2, new Vector4 ((float)rotMat.get (2, 0) [0], (float)rotMat.get (2, 1) [0], (float)rotMat.get (2, 2) [0], (float)(tvec [2] / downscaleRatio)));
540+
transformationM.SetRow (2, new Vector4 ((float)rotMat.get (2, 0) [0], (float)rotMat.get (2, 1) [0], (float)rotMat.get (2, 2) [0], (float)(tvec [2] / imageOptimizationHelper.downscaleRatio)));
433541

434542
transformationM.SetRow (3, new Vector4 (0, 0, 0, 1));
435543

@@ -450,7 +558,7 @@ private void DetectARUcoMarker()
450558
private void OnDetectionDone()
451559
{
452560
if (displayCameraPreview) {
453-
Imgproc.cvtColor (downScaleRgbaMat, rgbMat4preview, Imgproc.COLOR_RGBA2RGB);
561+
Imgproc.cvtColor (downScaleFrameMat, rgbMat4preview, Imgproc.COLOR_RGBA2RGB);
454562

455563
if (ids.total () > 0) {
456564
Aruco.drawDetectedMarkers (rgbMat4preview, corners, ids, new Scalar (255, 0, 0));
@@ -475,12 +583,17 @@ private void OnDetectionDone()
475583

476584
isDetecting = false;
477585
}
586+
#endif
478587

479588
/// <summary>
480589
/// Raises the destroy event.
481590
/// </summary>
482591
void OnDestroy ()
483592
{
593+
imageOptimizationHelper.Dispose ();
594+
#if NETFX_CORE
595+
webCamTextureToMatHelper.frameMatAcquired -= OnFrameMatAcquired;
596+
#endif
484597
webCamTextureToMatHelper.Dispose ();
485598
}
486599

0 commit comments

Comments
 (0)