//object tracking function private void track(mark themarks, Mat threshold, Mat HsvImage, Image <Bgr, byte> Frame, DepthImagePixel[] depthPixels) { CvInvoke.PutText(Frame, "Tracking Started", new System.Drawing.Point(0, 50), FontFace.HersheyComplex, 1, new Bgr(0, 255, 0).MCvScalar, 2); //create temporary image Mat temp = new Mat(); threshold.CopyTo(temp); List <mark> peices = new List <mark>(); bool objectfound = false; //vectors for Findcontours VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); //find contours of filtered image using openCV findContours function CvInvoke.FindContours(temp, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); int count = contours.Size; for (int i = 0; i < count; i++) { //marks mark peice = new mark(); using (VectorOfPoint contour = contours[i]) using (VectorOfPoint approxContour = new VectorOfPoint()) { CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true); if (CvInvoke.ContourArea(approxContour, false) > 400) //only consider contours with area greater than 400 { if (approxContour.Size == 3) //The contour has 3 vertices, it is a triangle { System.Drawing.Point[] pts = approxContour.ToArray(); MCvMoments moments = CvInvoke.Moments(contours[i]); double area = moments.M00; //objectFound = true; peice.setxpos(Convert.ToInt32(moments.M10 / area)); peice.setypos(Convert.ToInt32(moments.M01 / area)); //check to see what position the peice is in for (int j = 0; j <= 2; j++) { for (int k = 0; k <= 2; k++) { //if its x position is within a half of square size pixels then boardx and y are if (Math.Abs(gboard[j, k].getxpos() - peice.getxpos()) <= BOARD_SIZE / 2) { if (Math.Abs(gboard[j, k].getypos() - peice.getypos()) <= BOARD_SIZE / 2) { peice.setboardx(k); peice.setboardy(j); //Console.WriteLine(peice.getboardx()); //Console.WriteLine(peice.getboardx()); } } } } //set peice type to triangle (1) peice.settype(1); peices.Add(peice); objectfound = true; } else if (approxContour.Size == 4) //The contour has 4 vertices. { #region determine if all the angles in the contour are within [80, 100] degree bool isRectangle = true; System.Drawing.Point[] pts = approxContour.ToArray(); LineSegment2D[] edges = Emgu.CV.PointCollection.PolyLine(pts, true); for (int j = 0; j < edges.Length; j++) { double angle = Math.Abs( edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j])); if (angle < 80 || angle > 100) { isRectangle = false; break; } } #endregion if (isRectangle) { MCvMoments moments = CvInvoke.Moments(contours[i]); double area = moments.M00; peice.setxpos(Convert.ToInt32(moments.M10 / area)); peice.setypos(Convert.ToInt32(moments.M01 / area)); //Console.WriteLine(peice.getxpos()); //Console.WriteLine(peice.getxpos()); //Console.WriteLine(peice.getypos()); //set peice board positions for (int j = 0; j <= 2; j++) { for (int k = 0; k <= 2; k++) { //if its x position is within a half of square size pixels then boardx and y are if (Math.Abs(gboard[j, k].getxpos() - peice.getxpos()) <= BOARD_SIZE / 2) { if (Math.Abs(gboard[j, k].getypos() - peice.getypos()) <= BOARD_SIZE / 2) { peice.setboardx(k); peice.setboardy(j); //Console.WriteLine(peice.getboardx()); } } } } //set peice type to square peice.settype(2); peices.Add(peice); objectfound = true; armtargetx = peice.getxpos(); armtargety = peice.getypos(); } } } } } //Console.WriteLine(peices.ElementAt(1).getboardx()); if (objectfound) { //Drawingfunction to show peices draw(peices, Frame); //check to see if board state has changed after player locks in move if (Lockin) { boardchange(peices); } depthfunction(peices, depthPixels); } if (turn) { //if its arms turn then figure out where to move strategy(); } //find depth values for returned targets }
//When sensor is ready start stream and proces information public void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e) { BitmapSource clrimg = null; int Timeout = 0; using (DepthImageFrame depthFrame = e.OpenDepthImageFrame()) { if (depthFrame != null) { depthFrame.CopyDepthImagePixelDataTo(this.depthPixels); this.depthBitmap.WritePixels( new Int32Rect(0, 0, this.depthBitmap.PixelWidth, this.depthBitmap.PixelHeight), this.depthPixels, this.depthBitmap.PixelWidth * sizeof(int), 0); } } using (ColorImageFrame imageFrame = e.OpenColorImageFrame()) { if (imageFrame != null) { imageFrame.CopyPixelDataTo(this.colorPixels); this.colorBitmap.WritePixels( new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight), this.colorPixels, this.colorBitmap.PixelWidth * sizeof(int), 0); clrimg = colorBitmap; //convert image into something opencv can use Image <Bgr, byte> Frame = new Image <Bgr, byte>(BitmapFromSource(clrimg)); mark marks = new mark(); //hsv image Mat HsvImage = new Mat(); //threshold image for marks Mat threshold = new Mat(); //threshold image for board Mat threshold2 = new Mat(); //thresh image for peices Mat threshold3 = new Mat(); //creating HsvImage CvInvoke.CvtColor(Frame, HsvImage, ColorConversion.Bgr2Hsv); //if user wants to calibrate mark button is pushed if (markcalib) { CvInvoke.InRange(HsvImage, new ScalarArray(new MCvScalar(Trackbars.minhue, Trackbars.minsat, Trackbars.minval)), new ScalarArray(new MCvScalar(Trackbars.maxhue, Trackbars.maxsat, Trackbars.maxval)), threshold3); morphOps(threshold3); CvInvoke.Imshow("thresholdedImage3", threshold3); mhmin = Trackbars.minhue; msmin = Trackbars.minsat; mvmin = Trackbars.minval; mhmax = Trackbars.maxhue; msmax = Trackbars.maxsat; mvmax = Trackbars.maxval; } //once complete set mark hsv values if (markcalibed) { markcalib = false; CvInvoke.DestroyWindow("thresholdedImage3"); //Trackbars.Visible = false; CvInvoke.InRange(HsvImage, new ScalarArray(new MCvScalar(bhmin, bsmin, bvmin)), new ScalarArray(new MCvScalar(bhmax, bsmax, bvmax)), threshold); morphOps(threshold); } //preset markcalibration values else { CvInvoke.InRange(HsvImage, new ScalarArray(new MCvScalar(165, 126, 38)), new ScalarArray(new MCvScalar(225, 223, 110)), threshold); morphOps(threshold); } //if board calibrate button is pushed if (boardcalib) { CvInvoke.InRange(HsvImage, new ScalarArray(new MCvScalar(Trackbars.minhue, Trackbars.minsat, Trackbars.minval)), new ScalarArray(new MCvScalar(Trackbars.maxhue, Trackbars.maxsat, Trackbars.maxval)), threshold2); morphOps(threshold2); bhmin = Trackbars.minhue; bsmin = Trackbars.minsat; bvmin = Trackbars.minval; bhmax = Trackbars.maxhue; bsmax = Trackbars.maxsat; bvmax = Trackbars.maxval; CvInvoke.Imshow("thresholdedImage2", threshold2); } //after calibration use calibrated values if (boardcalibed) { boardcalib = false; CvInvoke.DestroyWindow("thresholdedImage2"); CvInvoke.InRange(HsvImage, new ScalarArray(new MCvScalar(bhmin, bsmin, bvmin)), new ScalarArray(new MCvScalar(bhmax, bsmax, bvmax)), threshold2); morphOps(threshold2); } //For board calibrate values manually else { CvInvoke.InRange(HsvImage, new ScalarArray(new MCvScalar(94, 57, 66)), new ScalarArray(new MCvScalar(117, 172, 163)), threshold2); morphOps(threshold2); } //find a gameboard if (boardfind) { if (!boardfound) { findboard(threshold2, HsvImage, Frame); } } if (tracking) { track(marks, threshold, HsvImage, Frame, depthPixels); } //Show startup box and do gamestart function if (start) { StartupBox.Visible = true; StartupBox.TopMost = true; } //convert to something we can use //Image<Bgr, Byte> yeah = Mat.ToImage<Bgr, Byte>(); //Console.WriteLine(gboard[0,0].getxpos()); Image1.Image = Frame; //show board/ peices when button clicked if (showboard) { CvInvoke.Imshow("BoardThresholdedImage", threshold2); } if (showmarks) { CvInvoke.Imshow("MarksThresholdedImage", threshold); } //CvInvoke.InRange(openCv, new ScalarArray(new MCvScalar(0, 126, 116)), new ScalarArray(new MCvScalar(214, 256, 256)), threshold); //CvInvoke.cvReleaseMat(ref IntPtr threshold2); //CvInvoke.WaitKey(100); } //Timeout++; //Destroy memory every x milliseconds //if (Timeout == 3000) //{ // CvInvoke.DestroyAllWindows(); // Timeout = 0; //} } }