public override List<TableObject> DetectRotation(List<TableObject> ObjectList)
        {
            DateTime start = DateTime.Now;

            //No bitmaps -> no rotation detection
            if (ObjectList.Where(o => o.ExtractedBitmap != null).Count() == 0)
                return ObjectList;

            List<TableObject> ObjectsWithBitmap = ObjectList.Where(o => o.ExtractedBitmap != null).ToList();
            int objects = ObjectsWithBitmap.Count();
            int index = 0;

            int _threadcount = 0;
            ManualResetEvent[] resetEvents;

            //Start 4 threads, only if >= 4 threads
            if (objects >= 4)
            {
                _threadcount = 4;
                resetEvents = new ManualResetEvent[4];

                for (int i=4; i > 0; i--)
                {
                    Thread t1 = new Thread(new ParameterizedThreadStart(Work));
                    t1.Name = "ObjectTable RotationDetection Thread #" + i.ToString();
                    //Copy 1/i*objectcount of the objects to the new thread
                    int amount = (int) Math.Round((1.0/i)*objects);
                    TableObject[] threadobjects = new TableObject[amount];
                    ObjectsWithBitmap.CopyTo(index, threadobjects, 0, amount);
                    objects -= amount;
                    index += amount;

                    resetEvents[i-1] = new ManualResetEvent(false);
                    t1.Start(new object[] {threadobjects,resetEvents[i-1]});
                }

                WaitHandle.WaitAll(resetEvents);
            }
            else
            {
                //Single thread
                _threadcount = 1;

                ManualResetEvent manualReset = new ManualResetEvent(false);

                Thread t = new Thread(new ParameterizedThreadStart(Work));
                t.Name = "ObjectTable RotationDetection Thread -";
                t.Start(new object[] {ObjectsWithBitmap.ToArray(),manualReset});

                manualReset.WaitOne();
            }

            //Performance
            this.RotationDetectionDuration = (int) Math.Round((DateTime.Now - start).TotalMilliseconds);
            return ObjectList;
        }
        private void CalculateRotation(TableObject obj)
        {
            TPoint rPoint = null, bPoint = null;
            //calculate the average values
            int x = 0, y = 0;
            int avRed=0, avGreen=0, avBlue=0;
            for (x = 0; x < obj.ExtractedBitmap.Width - 2; x++)
            {
                for (y = 0; y < obj.ExtractedBitmap.Height - 2; y++)
                {
                    Color c = obj.ExtractedBitmap.GetPixel(x, y);
                    avRed += c.R;
                    avGreen += c.G;
                    avBlue += c.B;
                }
            }
            int Pixels = obj.ExtractedBitmap.Height*obj.ExtractedBitmap.Width;
            avRed = (int) Math.Round((double)avRed / Pixels);
            avGreen = (int)Math.Round((double)avGreen / Pixels);
            avBlue = (int)Math.Round((double)avBlue / Pixels);

            //check for every suitable point, whether the point itself and at least 7 direct neighbours are red
            x = 1;
            y = 1;

            //The Points at the border have not enought direct neighbours
            for (x = 1; x < obj.ExtractedBitmap.Width-2; x++)
            {
                for (y = 1; y < obj.ExtractedBitmap.Height - 2; y++ )
                {
                    if (rPoint == null)
                    {
                        bool red = true;
                        int count = CountPOints(obj, red, y, x,avRed,avBlue,avGreen);
                        if (count >= 7)
                            rPoint = new TPoint(x, y, TPoint.PointCreationType.screen);
                    }
                }
            }

            //Same for blue point
            for (x = 1; x < obj.ExtractedBitmap.Width - 2; x++)
            {
                for (y = 1; y < obj.ExtractedBitmap.Height - 2; y++)
                {
                    if (bPoint == null)
                    {
                        bool red = false;
                        int count = CountPOints(obj, red, y, x, avRed, avBlue, avGreen);
                        if (count >= 7)
                            bPoint = new TPoint(x, y, TPoint.PointCreationType.screen);
                    }
                }
            }

            //Were two points recognized?
            if ((rPoint == null) || (bPoint == null))
                return;

            //Calculate the vector
            x = rPoint.ScreenX - bPoint.ScreenX;
            y = rPoint.ScreenY - bPoint.ScreenY;
            obj.DirectionVector = new System.Windows.Vector(x, y);
            obj.RotationDefined = true;
        }
        private int CountPOints(TableObject obj, bool red, int y, int x, int avRed, int avBlue, int avGreen)
        {
            int count = 0;
            Color c;

            //Check 9 points (1 point and 8 neighbours)
            c = obj.ExtractedBitmap.GetPixel(x, y);
            if (CheckThreshold(c, red,avRed,avBlue,avGreen))
                count++;

            c = obj.ExtractedBitmap.GetPixel(x + 1, y);
            if (CheckThreshold(c, red, avRed, avBlue, avGreen))
                count++;

            c = obj.ExtractedBitmap.GetPixel(x - 1, y);
            if (CheckThreshold(c, red, avRed, avBlue, avGreen))
                count++;

            c = obj.ExtractedBitmap.GetPixel(x, y + 1);
            if (CheckThreshold(c, red, avRed, avBlue, avGreen))
                count++;

            c = obj.ExtractedBitmap.GetPixel(x, y - 1);
            if (CheckThreshold(c, red, avRed, avBlue, avGreen))
                count++;

            c = obj.ExtractedBitmap.GetPixel(x - 1, y - 1);
            if (CheckThreshold(c, red, avRed, avBlue, avGreen))
                count++;

            c = obj.ExtractedBitmap.GetPixel(x + 1, y + 1);
            if (CheckThreshold(c, red, avRed, avBlue, avGreen))
                count++;

            c = obj.ExtractedBitmap.GetPixel(x - 1, y + 1);
            if (CheckThreshold(c, red, avRed, avBlue, avGreen))
                count++;

            c = obj.ExtractedBitmap.GetPixel(x + 1, y - 1);
            if (CheckThreshold(c, red, avRed, avBlue, avGreen))
                count++;
            return count;
        }
 private static void SaveDebugBitmap(int thresholdBlack, short[,] greyArray, int thresholdWhite, TableObject obj)
 {
     int x,y;
     Bitmap bmp = new Bitmap(obj.ExtractedBitmap.Width, obj.ExtractedBitmap.Height);
     for (x = 0; x < bmp.Width; x++)
     {
         for (y = 0; y < bmp.Width; y++)
         {
             if (greyArray[x, y] >= thresholdWhite)
                 bmp.SetPixel(x, y, Color.White);
             else if (greyArray[x, y] <= thresholdBlack)
                 bmp.SetPixel(x, y, Color.Black);
             else
                 bmp.SetPixel(x, y, Color.Lime);
         }
     }
     bmp.Save("bwrotation_" + obj.ObjectID.ToString() + ".bmp");
 }
Beispiel #5
0
 public object Clone()
 {
     TableObject obj = new TableObject();
     if (Center != null)
         obj.Center = Center.Clone();
     obj.CenterDefined = CenterDefined;
     if (ExtractedBitmap != null)
         obj.ExtractedBitmap = (Bitmap)ExtractedBitmap.Clone();
     obj.Height = Height;
     obj.ObjectID = ObjectID;
     obj.Radius = Radius;
     obj.DirectionVector = DirectionVector;
     obj.RotationDefined = RotationDefined;
     obj.TrackingStatus = TrackingStatus;
     obj.TrackingFrameExistence = TrackingFrameExistence;
     return obj;
 }
Beispiel #6
0
 /// <summary>
 /// Checks wheter the object is on a Menu field. Returns false, too, when the object is on a empty menu field
 /// </summary>
 /// <param name="obj"></param>
 /// <returns></returns>
 public bool IsOnMenuField(TableObject obj)
 {
     //Check for proper initialisation: if not, reinitialize
     if (_b1 == null)
     {
         GetRegions(out _b4, out _b3, out _b2, out _b1);
     }
     if (_b1.IsInRegion(obj.Center))
     {
         if (_objectList.Count > 0)
             return true;
     }
     else if (_b2.IsInRegion(obj.Center))
     {
         if (_objectList.Count > 1)
             return true;
     }
     else if (_b3.IsInRegion(obj.Center))
     {
         if (_objectList.Count > 2)
             return true;
     }
     else if (_b4.IsInRegion(obj.Center))
     {
         if (_objectList.Count > 3)
             return true;
     }
     return false;
 }
 private static short[,] ConvertToGreyArray(TableObject obj, out int average)
 {
     short[,] greyArray = new short[obj.ExtractedBitmap.Width,obj.ExtractedBitmap.Height];
     average = 0;
     int x, y;
     for (x = 0; x < obj.ExtractedBitmap.Width; x++)
     {
         for (y = 0; y < obj.ExtractedBitmap.Height; y++)
         {
             Color c = obj.ExtractedBitmap.GetPixel(x, y);
             greyArray[x, y] = (short) Math.Round(0.299*c.R + 0.587*c.G + 0.144*c.B);
             average += (short) Math.Round(0.299*c.R + 0.587*c.G + 0.144*c.B);
         }
     }
     return greyArray;
 }
Beispiel #8
0
        public Type GetSimObjectType(TableObject obj)
        {
            if (!IsOnMenuField(obj))
                return null;

            //On which menu field
            int m = GetMenueField(obj);
            MenuObject mobj = _objectList[_index + m];
            //return type
            return mobj.type;
        }
Beispiel #9
0
 /// <summary>
 /// Returns the number of the menu field (0-3). -1 if the object isnt on a menue filed
 /// </summary>
 /// <param name="obj"></param>
 /// <returns></returns>
 public int GetMenueField(TableObject obj)
 {
     if (_b1.IsInRegion(obj.Center))
     {
         if (_objectList.Count > 0)
             return 0;
     }
     else if (_b2.IsInRegion(obj.Center))
     {
         if (_objectList.Count > 1)
             return 1;
     }
     else if (_b3.IsInRegion(obj.Center))
     {
         if (_objectList.Count > 2)
             return 2;
     }
     else if (_b4.IsInRegion(obj.Center))
     {
         if (_objectList.Count > 3)
             return 3;
     }
     return -1;
 }
Beispiel #10
0
        private List<TableObject> GenerateTableObjects(List<ObjectPoint> pointlist, DepthImage image)
        {
            List<TableObject> tableobjects = new List<TableObject>();

            foreach (ObjectPoint op in pointlist)
            {
                TableObject tobj = new TableObject();

                tobj.Center = new TPoint(op.X, op.Y, TPoint.PointCreationType.depth);
                tobj.CenterDefined = true;
                tobj.Radius = op.RectSize;
                tobj.Height = image.Data[op.X, op.Y];

                tableobjects.Add(tobj);
            }

            return tableobjects;
        }
Beispiel #11
0
        private void MatchObjects(ref List<TrackObject> TrackObjList, TableObject.ETrackingStatus TrackStatusFilter, double CertainityThreshold, TableObject.ETrackingStatus AssignedStatus = TableObject.ETrackingStatus.NotTracked)
        {
            //Calculate the certainity for the selected objects
            List<int> UsedIDs = CalculateCertainity(ref TrackObjList, TrackStatusFilter);

            /*//For objects with a very good certainity value, assign objectid
            foreach (TrackObject to in TrackObjList.Where(obj => obj.TrackCertainity >= CertainityThreshold))
            {
                to.ObjReference.ObjectID = to.BestCertainityWithID;
                to.ObjReference.TrackingStatus = TrackStatusFilter;
                //If the assigned TrackStatus is defined, use it
                if (AssignedStatus != TableObject.ETrackingStatus.NotTracked)
                    to.ObjReference.TrackingStatus = AssignedStatus;
            }*/

            //There might be several objects with the same proposed ID. For each ObjectID, take the object with the best Certainity
            foreach (int checkID in UsedIDs)
            {
                TrackObject maxCertainityRef = null;
                double maxCertainity = 0.0;

                //Gett all proposed objs for this ID, and with the minimum required threshold
                foreach(TrackObject tobj in TrackObjList.Where(obj => obj.BestCertainityWithID == checkID).Where(obj => obj.TrackCertainity >= CertainityThreshold))
                {
                    //Take the object with the best Certainity
                    if (tobj.TrackCertainity > maxCertainity)
                    {
                        maxCertainity = tobj.TrackCertainity;
                        maxCertainityRef = tobj;
                    }
                }

                //Assign ID to the "best" object
                if (maxCertainityRef != null)
                {
                    maxCertainityRef.ObjReference.ObjectID = maxCertainityRef.BestCertainityWithID;
                    maxCertainityRef.ObjReference.TrackingStatus = TrackStatusFilter;
                    //If the assigned TrackStatus is defined, use it
                    if (AssignedStatus != TableObject.ETrackingStatus.NotTracked)
                        maxCertainityRef.ObjReference.TrackingStatus = AssignedStatus;
                }
            }
        }
Beispiel #12
0
        private List<int> CalculateCertainity(ref List<TrackObject> newFrameObjects, TableObject.ETrackingStatus filter)
        {
            //Get only the desired objects
            List<TableObject> recentObjects =
                _historyTrackList.GetLastFrame().ObjectList.Where(obj => obj.TrackingStatus == filter).ToList();

            //Dont track old objects that are already assigned to new ones (ID)
            List<int> AlreadyAssignedIDs = new List<int>();
            foreach (TrackObject obj in newFrameObjects)
            {
                if (obj.ObjReference.ObjectID != 0)
                    AlreadyAssignedIDs.Add(obj.ObjReference.ObjectID);
            }

            //Create a List with each ID that will be used
            List<int> UsedIDs = new List<int>();

            //Calculate certainity for each object that isn't tracked
            foreach (TrackObject to in newFrameObjects.Where(obj =>obj.ObjReference.TrackingStatus == TableObject.ETrackingStatus.NotTracked))
            {
                foreach(TableObject proposedObject in recentObjects)
                {
                    //Compare each object from the last frame
                    //and calculate the Certainity in % (value from 0 to 1)

                    //distance between objects
                    double distance = proposedObject.Center.DistanceTo(to.ObjReference.Center,TPoint.PointCreationType.depth);

                    //The negative percentage (distance / max distance) is the certainity
                    double certainity = 1 - (distance/MaxDistance);

                    //if this certainity value is better than the saved one, store the new values an the object id for later
                    //but only if the stored object isn't assigned to another object
                    if ((to.TrackCertainity < certainity) && (!AlreadyAssignedIDs.Contains(proposedObject.ObjectID)))
                    {
                        to.TrackCertainity = certainity;
                        to.BestCertainityWithID = proposedObject.ObjectID;
                        if (!UsedIDs.Contains(proposedObject.ObjectID))
                            UsedIDs.Add(proposedObject.ObjectID);
                    }
                }
            }

            return UsedIDs;
        }