//在UnityEditor中显示射线,Hololens上验证成功 public void AddRay(YoloBoundingBox box, Vector2 pixelPosition, uint boxWidth, uint boxHeight, int ImageWidth, int ImageHeight, Matrix4x4 projectionMatrix, Matrix4x4 cameraToWorldMatrix) { //Image的xy两轴取值范围均为-1 to +1,需要将像素坐标转化为该范围内。 Vector2 ImagePosZeroToOne = new Vector2(pixelPosition.x / ImageWidth, 1 - (pixelPosition.y / ImageHeight)); Vector2 ImagePosProjected = ((ImagePosZeroToOne * 2.0f) - new Vector2(1.0f, 1.0f)); Vector3 CameraSpacePos = UnProjectVector(projectionMatrix, new Vector3(ImagePosProjected.x, ImagePosProjected.y, 1)); //worldSpaceRayPoint1就是cameraPosition,相当于Ray的起点,而worldSpaceRayPoint2相当于Ray的终点。 Vector3 worldSpaceRayPoint1 = cameraToWorldMatrix.MultiplyPoint(Vector3.zero); Vector3 worldSpaceRayPoint2 = cameraToWorldMatrix.MultiplyPoint(CameraSpacePos); UnityEngine.Debug.Log("The Value of RayPosition: " + worldSpaceRayPoint2); //增加Ray并画出。 rays.Add(new RayPoints() { origin = worldSpaceRayPoint1, direction = worldSpaceRayPoint2 - worldSpaceRayPoint1 }); UnityEngine.Debug.DrawRay(rays[0].origin, rays[0].direction, Color.red, 100); UnityEngine.Debug.Log("DrawRay Succeed !"); //调用该方法,找到Ray与真实场景的碰撞点,即目标实物所在位置,并实例化标注框。 PlaceBoundingBox(box, worldSpaceRayPoint1, worldSpaceRayPoint2, boxWidth, boxHeight); }
/// <summary> /// Display markers of detected object. /// </summary> /// <param name="box"><see cref="YoloBoundingBox"/></param> /// <param name="overlayCanvas"><see cref="Canvas"/></param> public void DrawYoloBoundingBox(YoloBoundingBox box, Canvas overlayCanvas) { // process output boxes var x = (uint)Math.Max(box.X, 0); var y = (uint)Math.Max(box.Y, 0); var w = (uint)Math.Min(overlayCanvas.ActualWidth - x, box.Width); var h = (uint)Math.Min(overlayCanvas.ActualHeight - y, box.Height); // fit to current canvas and webcam size x = _yoloCanvasActualWidth * x / TinyYoloEvaluatorFor1803.EvaluateWidth; y = _yoloCanvasActualHeight * y / TinyYoloEvaluatorFor1803.EvaluateHeight; w = _yoloCanvasActualWidth * w / TinyYoloEvaluatorFor1803.EvaluateWidth; h = _yoloCanvasActualHeight * h / TinyYoloEvaluatorFor1803.EvaluateHeight; var rectStroke = box.Label == "person" ? _lineBrushGreen : _lineBrushYellow; var r = new Rectangle { Tag = box, Width = w, Height = h, Fill = _fillBrush, Stroke = rectStroke, StrokeThickness = _lineThickness, Margin = new Thickness(x, y, 0, 0) }; var tb = new TextBlock { Margin = new Thickness(x + 4, y + 4, 0, 0), Text = $"{box.Label} ({Math.Round(box.Confidence, 4)})", FontWeight = FontWeights.Bold, Width = 126, Height = 21, HorizontalTextAlignment = TextAlignment.Center }; var textBack = new Rectangle { Width = 134, Height = 29, Fill = rectStroke, Margin = new Thickness(x, y, 0, 0) }; overlayCanvas.Children.Add(textBack); overlayCanvas.Children.Add(tb); overlayCanvas.Children.Add(r); }
private void PlaceBoundingBox(YoloBoundingBox box, Vector3 worldSpaceRayPoint1, Vector3 worldSpaceRayPoint2, uint boxWidth, uint boxHeight) { RaycastHit hitInfo; UnityEngine.Debug.Log("Place Bounding Box Method Start."); //注:在Unity中,LayerMask用到移位符号,1是开启,0是关闭。可以过滤射线碰撞事件,移位符号左侧为0的表示被射线忽略。 //UserLayer31即为SpatialMapping层 try { //检测与真实场景的碰撞 if (Physics.Raycast(worldSpaceRayPoint1, worldSpaceRayPoint2 - worldSpaceRayPoint1, out hitInfo, 8.0f, 1 << 31)) { UnityEngine.Debug.Log("Physics Raycast Succeed! "); BoundingBoxPosition = hitInfo.point; GameObject label = Instantiate <GameObject>(labelTextHolder) as GameObject; label.transform.position = BoundingBoxPosition; label.transform.rotation = Camera.main.transform.rotation; TextMesh labelText = label.GetComponent <TextMesh>(); labelText.text = box.Label + " Confidence: " + box.Confidence.ToString("0.##"); labelText.font = labelFont; labelText.color = Color.green; labelText.anchor = TextAnchor.MiddleCenter; UnityEngine.Debug.Log("The Position of Label Text is : " + label.transform.position + ". The Position of BOunding Box is :" + BoundingBoxPosition); } else { UnityEngine.Debug.Log("Physics Raycast Failed! "); objectsCount--; } } catch (Exception e) { Debug.LogFormat("Exception occour in the placing bounding box method : {0}", e.Message); } this.gameObject.GetComponentInChildren <TextMesh>().color = Color.green; }
public async Task AddPhoto() { // Arrange string seed = Guid.NewGuid().ToString(); string expectedFilePath = string.Format("1_{0}.jpg", seed); var photoUploadService = new Mock <IPhotoUploadService>(); photoUploadService.Setup(m => m.UploadPhoto(It.IsAny <IFormFile>(), It.IsAny <string>())) .ReturnsAsync(expectedFilePath); int expectedWidth = new Random().Next(1, 5000); int expectedHeight = new Random().Next(1, 5000); var mockPhotoRepository = new Mock <IPhotoRepository>(); mockPhotoRepository.Setup(m => m.GetImageDimensions(It.IsAny <IFormFile>())) .ReturnsAsync((expectedHeight, expectedWidth)); var mockCommentRepository = new Mock <ICommentRepository>(); var mockHost = new Mock <IWebHostEnvironment>(); string expectedWebRootPath = seed; mockHost.SetupGet(m => m.WebRootPath).Returns(expectedWebRootPath); IDictionary <string, IList <YoloBoundingBox> > expectedObjectsDict = new Dictionary <string, IList <YoloBoundingBox> >(); string expectedLabel = string.Format("bird_{0}", seed); YoloBoundingBox expectedBoundingBox = new YoloBoundingBox() { Label = expectedLabel }; string expectedKey = Path.Combine(expectedWebRootPath, "uploads", expectedFilePath); expectedObjectsDict.Add(expectedKey, new List <YoloBoundingBox>() { expectedBoundingBox }); var mockObjectDetectionService = new Mock <IObjectDetectionService>(); mockObjectDetectionService.Setup(m => m.DetectObjectsFromImages(It.IsAny <List <string> >(), It.IsAny <string>(), It.IsAny <string>())) .Returns(expectedObjectsDict); var mockCategoryRepository = new Mock <ICategoryRepository>(); Category expectedCategory = new Category() { Name = expectedLabel }; mockCategoryRepository.Setup(m => m.GetByNames(new List <string>() { expectedLabel })) .Returns(new List <Category>() { expectedCategory }); string expectedUserName = string.Format("test_{0}@gmail.com", seed); ControllerContext controllerContext = Utilities.SetupCurrentUserForController(expectedUserName); var mockUserRepository = new Mock <IUserRepository>(); User expectedUser = new User() { Id = seed, UserName = expectedUserName }; mockUserRepository.Setup(m => m.GetOrAdd(It.IsAny <User>())).Returns(expectedUser); var mockAlbumRepository = new Mock <IAlbumRepository>(); var mockUnitOfWork = new Mock <IUnitOfWork>(); PhotosController controller = new PhotosController(this._mapper, mockPhotoRepository.Object, mockCategoryRepository.Object, mockUserRepository.Object, mockCommentRepository.Object, mockAlbumRepository.Object, mockUnitOfWork.Object, photoUploadService.Object, mockHost.Object, mockObjectDetectionService.Object); controller.ControllerContext = controllerContext; PhotoResource originalResource = new PhotoResource() { Id = new Random().Next(1, 100), FileToUpload = new Mock <IFormFile>().Object, Name = seed, LocLng = new Random().Next(1, 100), LocLat = new Random().Next(1, 100), CenterLng = new Random().Next(1, 100), CenterLat = new Random().Next(1, 100), MapZoom = new Random().Next(1, 100), FilePath = expectedFilePath, Width = expectedWidth, Height = expectedHeight, PhotoCategories = new List <CategoryResource>() { new CategoryResource() { Name = expectedLabel } }, Author = new UserResource() { UserName = expectedUserName } }; // Act var result = await controller.CreatePhoto(originalResource); // Assert Assert.IsType <OkObjectResult>(result); Assert.IsType <PhotoResource>(((OkObjectResult)result).Value); PhotoResource returnedPhotoResource = (PhotoResource)((OkObjectResult)result).Value; Assert.True(returnedPhotoResource.Equals(originalResource)); }