예제 #1
0
        public BottleDetectionUseCases(CompositeDisposable disposables)
            : base(disposables)
        {
            photoCamera = new PhotoCamera();
            client      = new CustomVisionClient();

            CanTakePhoto = Observable.CombineLatest(photoCamera.CanTakePhoto, client.CanPost)
                           .Select(x => !x.Contains(false))
                           .ToReactiveProperty();

            PhotoCamera.ShootingPlan plan = null;
            byte[] imageData = null;
            photoCamera.OnPhotoCaptured
            .Do(b =>
            {
                plan      = photoCamera.Plan;
                imageData = b;
            })
            .SelectMany(x => client.Post(x))
            .Do(res =>
            {
                var positions = client.Convert(plan, imageData, res);
                var status    = new DetectedStatus
                {
                    Plan      = plan,
                    Positions = positions,
                };
                onBottleDetected.OnNext(status);
            })
            .Subscribe()
            .AddTo(disposables);
        }
예제 #2
0
        private List <Vector3> ConvertToPosition(PhotoCamera.ShootingPlan plan, byte[] imageData, CustomVisionResponse res)
        {
            const string tag = "Irohasu";


            var resolutionHeight  = plan.Resolution.height;
            var resolutionWidth   = plan.Resolution.width;
            var reproducedObjects = new List <Vector3>();

            foreach (var result in res.predictions.Where(x => probabilityThreshold < x.probability))
            {
                if (result.tagName == tag)
                {
                    // 画像から矩形を切りとる
                    // 左下原点
                    var rect   = result.boundingBox;
                    var height = rect.height * resolutionHeight;
                    var width  = rect.width * resolutionWidth;
                    var top    = rect.top * resolutionHeight;
                    var left   = rect.left * resolutionWidth;

                    // ワールド座標はpixelから変換
                    // 中央原点に再計算
                    top  = -((top + height / 2) / resolutionHeight - .5f);
                    left = (left + width / 2) / resolutionWidth - .5f;

                    // 距離に応じて補正
                    var frustumWidthFactor = 2.0f * Mathf.Tan(67 * 0.5f * Mathf.Deg2Rad);
                    left = left * frustumWidthFactor;
                    top  = top * frustumWidthFactor;

                    // サイズ、向きの調整
                    var cameraMatrix = plan.PixelToCamera.MultiplyPoint3x4(new Vector3(left, top, 0));
                    Debug.Log("#cameraMatrix" + cameraMatrix);

                    var targetPosition = plan.CameraToWorld.MultiplyPoint3x4(cameraMatrix);
                    Debug.Log("#worldMatrix:" + targetPosition);

                    reproducedObjects.Add(targetPosition);
                }
            }

            if (reproducedObjects.Count < 1)
            {
                Debug.Log("Target object not found.");
            }

            return(reproducedObjects);
        }
예제 #3
0
        public Vector3[] Convert(PhotoCamera.ShootingPlan plan, byte[] imageData, CustomVisionResponse response)
        {
            var node = response.predictions.OrderByDescending(x => x.probability).FirstOrDefault();

            if (node != null)
            {
                Debug.Log("Item detect finished...");
                return(ConvertToPosition(plan, imageData, response).ToArray());
            }
            else
            {
                Debug.LogError("No Item detected...");
                return(new Vector3[0]);
            }
        }