Example #1
0
        private IdentifiedObject IdentifyObject(Contour <Point> contour, double ContourAccuracy)
        {
            //PointF center;

            //int boundingWidth = contour.BoundingRectangle.Width;
            //double dx = Double.Parse (boundingWidth.ToString ());

//			// horizontal coordinates of center point of area
//			dx = dx * 0.5;
//			dx = dx + contour.BoundingRectangle.X;
            //int boundingHeight = contour.BoundingRectangle.Height;
            bool circ = false;

            string strheight = contour.GetMinAreaRect().size.Height.ToString();
            string strwidth  = contour.GetMinAreaRect().size.Width.ToString();

            // set accuracy for shape detection, since it depends on contouracc, we'll do it as follows
            //int boundaries = 6;
//			if (ContourAccuracy >= 0.005) {
//				boundaries = 8;
//			}


            // Example: the bounding box can be 90 degrees rotated from the bounding area square
            // to make sure the right edges are compared the ratio is used to widen the range when needed
            // the following values resulted in a 99.9% true negative when fully detected, and some colours 100% true positive
            double ratio = double.Parse(strheight) / double.Parse(strwidth);

            if (ratio < 1)
            {
                ratio = 1 / ratio;
            }
            ratio = ratio * ratio * 1.05;
            double rectHeight = (double)contour.BoundingRectangle.Height;
            double rectWidth  = (double)contour.BoundingRectangle.Width;

            // old: if (double.Parse(strheight) <= contour.BoundingRectangle.Height + 2 && int.Parse(strheight) >= contour.BoundingRectangle.Height - boundaries)
            if (double.Parse(strheight) <= rectHeight * ratio && double.Parse(strheight) >= rectHeight / ratio)
            {
                if (double.Parse(strwidth) <= rectWidth * ratio && double.Parse(strwidth) >= rectWidth / ratio)
                {
//								// is it non-elliptical?
                    if (double.Parse(strwidth) * 0.9 < double.Parse(strheight) && (double.Parse(strwidth) * 1.1 > double.Parse(strheight)))
                    {
                        circ = true;
                        //Console.WriteLine (contour.GetMinAreaRect ().size.Height.ToString ());
                    }
                    else
                    {
                        //Console.WriteLine ("elliptical");
                    }
                }
                else
                {
                    //	Console.WriteLine ("width not a circle? float:" + currentContour.GetMinAreaRect ().size.Width.ToString () + " int: " + strwidth + " exp: " + currentContour.BoundingRectangle.Width.ToString ());
                }
            }
            else
            {
                //	Console.WriteLine ("height not a circle? float:" + currentContour.GetMinAreaRect ().size.Height.ToString () + " int: " + strheight + " exp: " + currentContour.BoundingRectangle.Height.ToString ());
            }


            // find center
            double dy = 0.5 * rectHeight + contour.BoundingRectangle.Y;
            double dx = 0.5 * rectWidth + +contour.BoundingRectangle.X;

            // sometimes pc would act up
            if (dy == 240)
            {
                // this usually happens when the variables aren't being refreshed properly, this happened with internal cam on laptop
                Console.WriteLine("oops, this shouldnt occur often with the ps eye cam, you using the right one?");
                //break;
            }
            // float coordinates of center of area
            float xf;
            float yf;

            //Console.WriteLine ("doubley: " + dy);

            // convert values to floats
            float.TryParse(dx.ToString(), out xf);
            float.TryParse(dy.ToString(), out yf);
//						if (contour == biggestContour) {
//							center = new PointF (xf, yf);
//						}
            //PointF center = new PointF (xf, yf);
            //CircleF circle = new CircleF (center2, float.Parse (contour.Area.ToString ()));
            //CircleF circle = new CircleF (center, 20f);

            // compare square footing of expected circle with contour area
            // calc average radius
            double avgr  = (rectWidth + rectHeight) / 4;
            double total = Math.PI * avgr * avgr;

            //Console.WriteLine ("circle totalarea" + contour.Area.ToString ()+ " calculated area " + total.ToString());
            double area = Convert.ToDouble(contour.Area);

            if (area > total * 1.02)
            {
                circ = false;
                // I'm actually a square after all! just nearly vertical
            }
            IdentifiedObject io = new IdentifiedObject(circ, dx, dy, Convert.ToDouble(contour.Area));

            return(io);
        }
Example #2
0
        private IdentifiedObject IdentifyObject(Contour<Point> contour, double ContourAccuracy, long timeinms)
        {
            //PointF center;

            //int boundingWidth = contour.BoundingRectangle.Width;
            //double dx = Double.Parse (boundingWidth.ToString ());

            //			// horizontal coordinates of center point of area
            //			dx = dx * 0.5;
            //			dx = dx + contour.BoundingRectangle.X;
            //int boundingHeight = contour.BoundingRectangle.Height;
            bool circ = false;
            bool rect = false;
            string strheight = contour.GetMinAreaRect ().size.Height.ToString ();
            string strwidth = contour.GetMinAreaRect ().size.Width.ToString ();

            // set accuracy for shape detection, since it depends on contouracc, we'll do it as follows
            //int boundaries = 6;
            //			if (ContourAccuracy >= 0.005) {
            //				boundaries = 8;
            //			}

            // Example: the bounding box can be 90 degrees rotated from the bounding area square
            // to make sure the right edges are compared the ratio is used to widen the range when needed
            // the following values resulted in a 99.9% true negative when fully detected, and some colours 100% true positive
            double ratio = double.Parse (strheight) / double.Parse (strwidth);
            if (ratio < 1)
                ratio = 1 / ratio;
            ratio = ratio * ratio * 1.05;
            double rectHeight = (double)contour.BoundingRectangle.Height;
            double rectWidth = (double)contour.BoundingRectangle.Width;

            // find center
            double dy = 0.5 * rectHeight + contour.BoundingRectangle.Y;
            double dx = 0.5 * rectWidth + contour.BoundingRectangle.X;

            // old: if (double.Parse(strheight) <= contour.BoundingRectangle.Height + 2 && int.Parse(strheight) >= contour.BoundingRectangle.Height - boundaries)
            if (double.Parse (strheight) <= rectHeight * ratio && double.Parse (strheight) >= rectHeight / ratio) {
                if (double.Parse (strwidth) <= rectWidth * ratio && double.Parse (strwidth) >= rectWidth / ratio) {
                    //								// is it non-elliptical?
                    if (double.Parse (strwidth) * 0.9 < double.Parse (strheight) && (double.Parse (strwidth) * 1.1 > double.Parse (strheight))) {
                        circ = true;
                        //Console.WriteLine (contour.GetMinAreaRect ().size.Height.ToString ());
                    } else {
                        return null;
                        //Console.WriteLine ("elliptical");
                    }
                } else {
                    //	Console.WriteLine ("width not a circle? float:" + currentContour.GetMinAreaRect ().size.Width.ToString () + " int: " + strwidth + " exp: " + currentContour.BoundingRectangle.Width.ToString ());
                }
            } else {
                //	Console.WriteLine ("height not a circle? float:" + currentContour.GetMinAreaRect ().size.Height.ToString () + " int: " + strheight + " exp: " + currentContour.BoundingRectangle.Height.ToString ());

            }

            // sometimes pc would act up
            if (dy == 240) {
                // this usually happens when the variables aren't being refreshed properly, this happened with internal cam on laptop
                Console.WriteLine ("oops, this shouldnt occur often with the ps eye cam, you using the right one?");
                //break;

            }
            // float coordinates of center of area
            float xf;
            float yf;

            //Console.WriteLine ("doubley: " + dy);

            // convert values to floats
            float.TryParse (dx.ToString (), out xf);
            float.TryParse (dy.ToString (), out yf);
            //						if (contour == biggestContour) {
            //							center = new PointF (xf, yf);
            //						}
            //PointF center = new PointF (xf, yf);
            //CircleF circle = new CircleF (center2, float.Parse (contour.Area.ToString ()));
            //CircleF circle = new CircleF (center, 20f);

            // compare square footing of expected circle with contour area
            // calc average radius
            double avgr = (rectWidth + rectHeight) / 4;
            double total = Math.PI * avgr * avgr;

            //Console.WriteLine ("circle totalarea" + contour.Area.ToString ()+ " calculated area " + total.ToString());
            double area = Convert.ToDouble (contour.Area);

            if (circ) if (area > total * 1.02) {
                circ = false;
                rect = true;
                // I'm actually a square after all! just nearly vertical
            }

            // if object doesn't already exist create new one

            IDcounter++;
            IdentifiedObject io = new IdentifiedObject ((int)dx, (int)dy, Convert.ToDouble (contour.Area), circ, rect, IDcounter, timeinms);
            return io;
        }
Example #3
0
        // this is for object detection
        private void ProcessFrame(object sender, EventArgs arg)
        {
            Image <Bgr, Byte> frame = null;            // the frame retrieved from camera

            //bool showWindow = true; // toggle whether or not to show the live feed (performance hit!)

            // variables you'll want to calibrate

            //int bluerange = 200;
            //int redrange = 200;
            //int greenrange = 100;



            try {
                frame = _capture.RetrieveBgrFrame();
            } catch (Exception ax) {
                Console.WriteLine("Image retrieval failed! quiting: " + ax.ToString());
                return;
            }

            framecounter++;             // counter for framerate

            // 30 frames have passed, time to print framerate!
            if (framecounter == 30)
            {
                //watch.Stop();
                double framerate = 30.0 / (Convert.ToDouble(watch.ElapsedMilliseconds) / 1000);
                if (showWindow)
                {
                    Console.WriteLine(framerate);
                }
                framecounter = 0;

                watch.Stop();
                watch.Reset();
                watch.Start();
                framecounter = 0;
            }

            Image <Hsv, Byte>  frame_HSV = frame.Convert <Hsv, Byte> ();
            Image <Gray, Byte> frame_thresh;

            frame_thresh = frame_HSV.InRange(new Hsv(hue, sat, val), new Hsv(maxHue, maxSat, maxVal));

            //processedFrame = frame.Clone ().ThresholdBinary (new Bgr (redrange, greenrange, bluerange), new Bgr (255, 255, 255));

            using (MemStorage storage = new MemStorage()) {
                List <Contour <Point> > unidentifiedObjects = this.DetectObjects(storage, frame_thresh, ContourAccuracy, minAreaSize, maxAreaSize);
                //if (unidentifiedObjects.Count == 0) Console.WriteLine ("no objects detected");
                foreach (Contour <Point> contour in unidentifiedObjects)
                {
                    long timeinms = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                    bool found    = false;
                    // calculate center
                    double rectHeight = (double)contour.BoundingRectangle.Height;
                    double rectWidth  = (double)contour.BoundingRectangle.Width;

                    // find center
                    double dy = 0.5 * rectHeight + contour.BoundingRectangle.Y;
                    double dx = 0.5 * rectWidth + contour.BoundingRectangle.X;

                    if (identifiedObjects.Count > 0)
                    {
                        //Console.WriteLine ("check 1a");
                        foreach (IdentifiedObject io in identifiedObjects)
                        {
                            // calculate center point
                            // accuracy is in pixels, 10 for now
                            if (io.liesWithin((int)dx, (int)dy, recentlyChanged, maxPixTravel, timeinms))
                            {
                                found = true;
                                //if (showWindow) Console.WriteLine("existing object");
                                break;
                            }
                        }
                    }
                    //Console.WriteLine("check 2");
                    // if not found, add object!
                    if (!found)
                    {
                        IdentifiedObject iox = this.IdentifyObject(contour, ContourAccuracy, timeinms);
                        if (iox != null)
                        {
                            if (showWindow)
                            {
                                Console.WriteLine("new object detected");
                            }
                            identifiedObjects.Add(iox);
                        }
                    }
                    //else {if (showWindow)Console.WriteLine("existing object");}
                }
                if (recentlyChanged)
                {
                    recentlyChanged = false;
                }
            }

            if (showWindow)
            {
                List <IdentifiedObject> toRemove = new List <IdentifiedObject>();
                foreach (IdentifiedObject io in identifiedObjects)
                {
                    long timeinms = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                    //Console.WriteLine (io.ToString());
                    Point center = io.getPosition(timeinms);

                    if (center.X == -1)
                    {
                        toRemove.Add(io);
                        //Console.WriteLine("ready for removal");
                    }
                    else
                    {
                        PointF  centerf = new PointF((float)center.X, (float)center.Y);
                        CircleF circlef = new CircleF(centerf, 5);
                        if (io.getShape() == "circle")
                        {
                            frame.Draw(circlef, io.getColor(), 5);
                        }
                        else if (io.getShape() == "square")
                        {
                            frame.Draw(circlef, io.getColor(), 10);
                        }
                        else
                        {
                            frame.Draw(circlef, io.getColor(), 1);
                        }
                    }
                }
                foreach (IdentifiedObject io in toRemove)
                {
                    identifiedObjects.Remove(io);
                }
                CvInvoke.cvShowImage("Capture", frame);
                CvInvoke.cvWaitKey(1);
            }
        }