Esempio n. 1
0
        private void setAngleRelativeToCameraForward(ref PlaneResult io_PlaneResult)
        {
            // angle relative to the real surface which is not true when the camera is at an angle
            Vector3 n = io_PlaneResult.P.Normal;

            io_PlaneResult.Angle = (float)(Math.Acos(Math.Abs(n.Z)) / Math.PI * 180);
            var cam = new Vector3(0, 0, 1f);
            var dot = Vector3.Dot(n, cam);
            var u   = cam - n * dot;

            io_PlaneResult.AngleX = u.X;
            io_PlaneResult.AngleY = u.Y;
        }
Esempio n. 2
0
        private bool isPlaneValid(PlaneResult i_Plane)
        {
            Vector3[]    p      = { i_Plane.PlaneCorners[0], i_Plane.PlaneCorners[1], i_Plane.PlaneCorners[2], i_Plane.PlaneCorners[3] };
            List <float> angles = new List <float>();
            bool         res    = false;

            for (int i = 0; i < p.Length; i++)
            {
                Vector3 p1 = p[i];
                Vector3 p2 = p[(i + 1) % p.Length];

                if ((p2 - p1).Length() < 1e-3)
                {
                    break;
                }

                p1 = Vector3.Normalize(p1);
                p2 = Vector3.Normalize(p2);

                angles.Add((float)Math.Acos(Vector3.Dot(p1, p2) / Math.Sqrt(p1.Length() * p2.Length())));
            }

            int minuses = 0, pluses = 0;

            for (int i = 0; i < angles.Count; i++)
            {
                if (angles[i] < 0)
                {
                    minuses++;
                }
                else if (angles[i] > 0)
                {
                    pluses++;
                }
            }

            if (minuses == 4 || pluses == 4)
            {
                res = true;
            }

            return(res);
        }
Esempio n. 3
0
 private void OnRes(PlaneResult i_Result)
 {
     MediatorResultFunc?.Invoke(i_Result);
 }
Esempio n. 4
0
        private void AnalyzeDepthImage()
        {
            while (m_IsRunning)
            {
                if (m_Queue != null)
                {
                    DepthFrame f;

                    if (m_Queue.Dequeue(out f))
                    {
                        using (f)
                        {
                            var o_Result = new PlaneResult();
                            o_Result.IsPlaneReconstructed = true;
                            var profile      = f.GetProfile();
                            var streamType   = profile.Stream;
                            var streamFormat = profile.Format;

                            if (streamType == Stream.Depth && streamFormat == Format.Z16)
                            {
                                m_Intrinsics = profile.GetIntrinsics();
                                m_Roi        = setROI();
                                var data   = f.Data;
                                int width  = f.Width;
                                int height = f.Height;
                                var pixels = f.Pixels; //new short[width * height];
                                                       //System.Runtime.InteropServices.Marshal.Copy(data, pixels, 0, width * height);

                                List <Vector3> roiPixels = new List <Vector3>();

                                // converting pixels to point in 3d space
                                for (int y = m_Roi.MinY; y < m_Roi.MaxY; y++)
                                {
                                    for (int x = m_Roi.MinX; x < m_Roi.MaxX; x++)
                                    {
                                        ushort depthRaw = (ushort)pixels[y * width + x];

                                        // depthRaw if 0 means there's no depth, the pixel is at depth zero just like any other pixel in a photo
                                        if (depthRaw != 0)
                                        {
                                            float[] pixel    = { x, y };
                                            Vector3 point    = new Vector3();
                                            var     distance = depthRaw * m_Units;

                                            projectPixelToPoint(ref point, m_Intrinsics, pixel, distance);

                                            roiPixels.Add(new Vector3(point.X, -point.Y, point.Z));
                                        }
                                    }
                                }

                                if (roiPixels.Count < 3)
                                {
                                    continue;
                                }

                                roiPixels.Reverse();

                                var plane = planeFromPoints(roiPixels);

                                // The points in RoI don't span a valid plane which is kind of useless
                                if (plane == new Plane(0, 0, 0, 0))
                                {
                                    continue;
                                }

                                // Vector3 planeFitPivot = approximateIntersection(plane, m_Intrinsics.width / 2f, m_Intrinsics.height / 2f, 0f, 1000f);
                                Vector3[] planeCorners = new Vector3[4];

                                planeCorners[0] = approximateIntersection(plane, m_Roi.MinX, m_Roi.MinY, 0f, 1000f);
                                planeCorners[1] = approximateIntersection(plane, m_Roi.MaxX, m_Roi.MinY, 0f, 1000f);
                                planeCorners[2] = approximateIntersection(plane, m_Roi.MaxX, m_Roi.MaxY, 0f, 1000f);
                                planeCorners[3] = approximateIntersection(plane, m_Roi.MinX, m_Roi.MaxY, 0f, 1000f);

                                o_Result.P            = plane;
                                o_Result.PlaneCorners = planeCorners;

                                if (!isPlaneValid(o_Result))
                                {
                                    o_Result.PlaneCorners         = null;
                                    o_Result.IsPlaneReconstructed = false;
                                }
                                else
                                {
                                    setAngleRelativeToCameraForward(ref o_Result);
                                }

                                // Resulting plance distance from the camera
                                o_Result.Distance = -plane.D * 1000;

                                OnRes?.Invoke(o_Result);
                            }
                        }
                    }
                    else
                    {
                        Thread.Sleep(4);
                    }
                }
            }
        }