private Point centroideDeCorIndividual(Image <Gray, byte> imgGray) { //USANDO BLOBS blobDetector.Detect(imgGray, detectedBlobs); blobList = detectedBlobs.Values.ToList(); int posicao = filterSize(blobList); centro.X = (int)blobList[posicao].Centroid.X; centro.Y = (int)blobList[posicao].Centroid.Y; detectedBlobs.Clear(); return(centro); }
/// <summary> /// /// </summary> /// <param name="img"></param> /// <param name="blobs"></param> /// <returns></returns> public static int Perform(IplImage img, CvBlobs blobs) { if (img == null) throw new ArgumentNullException("img"); if (blobs == null) throw new ArgumentNullException("blobs"); if (img.Depth != BitDepth.U8 || img.NChannels != 1) throw new ArgumentException("'img' must be a 1-channel U8 image."); LabelData labels = blobs.Labels; if (labels == null) throw new ArgumentException(""); //if(labels.GetLength(0) != h || labels.GetLength(1) != w) if (labels.Rows != img.Height || labels.Cols != img.Width) throw new ArgumentException("img.Size != labels' size"); int numPixels = 0; blobs.Clear(); int step = img.WidthStep; CvRect roi = img.ROI; int w = roi.Width; int h = roi.Height; int offset = 0; if (img.ROIPointer != IntPtr.Zero) { IplROI r = img.ROIValue; w = r.width; h = r.height; offset = r.xOffset + (r.yOffset * step); } byte[] imgIn; unsafe { byte* imgInPtr = img.ImageDataPtr + offset; imgIn = new byte[h * step]; Marshal.Copy(new IntPtr(imgInPtr), imgIn, 0, imgIn.Length); } int label = 0; int lastLabel = 0; CvBlob lastBlob = null; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (imgIn[x + y * step] == 0) continue; bool labeled = labels[y, x] != 0; if (!labeled && ((y == 0) || (imgIn[x + (y - 1) * step] == 0))) { labeled = true; // Label contour. label++; if (label == MarkerValue) throw new Exception(); labels[y, x] = label; numPixels++; // XXX This is not necessary at all. I only do this for consistency. if (y > 0) labels[y - 1, x] = MarkerValue; CvBlob blob = new CvBlob(label, x, y); blobs.Add(label, blob); lastLabel = label; lastBlob = blob; blob.Contour.StartingPoint = new CvPoint(x, y); int direction = 1; int xx = x; int yy = y; bool contourEnd = false; do { for (int numAttempts = 0; numAttempts < 3; numAttempts++) { bool found = false; for (int i = 0; i < 3; i++) { int nx = xx + MovesE[direction, i, 0]; int ny = yy + MovesE[direction, i, 1]; if ((nx < w) && (nx >= 0) && (ny < h) && (ny >= 0)) { if (imgIn[nx + ny * step] != 0) { found = true; blob.Contour.ChainCode.Add((CvChainCode)MovesE[direction, i, 3]); xx = nx; yy = ny; direction = MovesE[direction, i, 2]; break; } labels[ny, nx] = MarkerValue; } } if (!found) direction = (direction + 1) % 4; else { if (labels[yy, xx] != label) { labels[yy, xx] = label; numPixels++; if (xx < blob.MinX) blob.MinX = xx; else if (xx > blob.MaxX) blob.MaxX = xx; if (yy < blob.MinY) blob.MinY = yy; else if (yy > blob.MaxY) blob.MaxY = yy; blob.Area++; blob.M10 += xx; blob.M01 += yy; blob.M11 += xx * yy; blob.M20 += xx * xx; blob.M02 += yy * yy; } break; } contourEnd = ((xx == x) && (yy == y) && (direction == 1)); if (contourEnd) break; } } while (!contourEnd); } if ((y + 1 < h) && (imgIn[x + (y + 1) * step] == 0) && (labels[y + 1, x] == 0)) { labeled = true; // Label internal contour int l; CvBlob blob; if (labels[y, x] == 0) { l = labels[y, x - 1]; labels[y, x] = l; numPixels++; if (l == lastLabel) blob = lastBlob; else { blob = blobs[l]; lastLabel = l; lastBlob = blob; } if (blob == null) throw new Exception(); blob.Area++; blob.M10 += x; blob.M01 += y; blob.M11 += x * y; blob.M20 += x * x; blob.M02 += y * y; } else { l = labels[y, x]; if (l == lastLabel) blob = lastBlob; else { blob = blobs[l]; lastLabel = l; lastBlob = blob; } } if (blob == null) throw new Exception(); // XXX This is not necessary (I believe). I only do this for consistency. labels[y + 1, x] = MarkerValue; var contour = new CvContourChainCode { StartingPoint = new CvPoint(x, y) }; int direction = 3; int xx = x; int yy = y; do { for (int numAttempts = 0; numAttempts < 3; numAttempts++) { bool found = false; for (int i = 0; i < 3; i++) { int nx = xx + MovesI[direction, i, 0]; int ny = yy + MovesI[direction, i, 1]; if (imgIn[nx + ny * step] != 0) { found = true; contour.ChainCode.Add((CvChainCode)MovesI[direction, i, 3]); xx = nx; yy = ny; direction = MovesI[direction, i, 2]; break; } labels[ny, nx] = MarkerValue; } if (!found) direction = (direction + 1) % 4; else { if (labels[yy, xx] == 0) { labels[yy, xx] = l; numPixels++; blob.Area++; blob.M10 += xx; blob.M01 += yy; blob.M11 += xx * yy; blob.M20 += xx * xx; blob.M02 += yy * yy; } break; } } } while (!(xx == x && yy == y)); blob.InternalContours.Add(contour); } //else if (!imageOut(x, y)) if (!labeled) { // Internal pixel int l = labels[y, x - 1]; labels[y, x] = l; numPixels++; CvBlob blob; if (l == lastLabel) blob = lastBlob; else { blob = blobs[l]; lastLabel = l; lastBlob = blob; } if (blob == null) throw new Exception(); blob.Area++; blob.M10 += x; blob.M01 += y; blob.M11 += x * y; blob.M20 += x * x; blob.M02 += y * y; } } } foreach (var kv in blobs) { kv.Value.SetMoments(); } return numPixels; }
private void timer_process_Tick(object sender, EventArgs e) { timer_process.Enabled = false; Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics graphics = Graphics.FromImage(bitmap as Image); graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size); bitmap.Save("4.png"); long Ticks = DateTime.Now.Millisecond; Mat mat = new Mat("4.png", Emgu.CV.CvEnum.LoadImageType.Color); Image <Bgr, Byte> imgBgr = mat.ToImage <Bgr, Byte>(); Image <Gray, Byte> imgGray = mat.ToImage <Gray, Byte>(); int nWid = imgGray.Width; int nHei = imgGray.Height; byte[,,] pData = imgGray.Data; for (int y = 0; y < nHei; y++) { for (int x = 0; x < nWid; x++) { byte c = pData[y, x, 0]; if (c > 5) { pData[y, x, 0] = 0; } else { pData[y, x, 0] = 255; } } } CvBlobs blobs = new CvBlobs(); _blobDetector.Detect(imgGray, blobs); blobs.FilterByArea(100, int.MaxValue); //_tracker.Process(smoothedFrame, forgroundMask); if (blobs.Count < 1) { timer_process.Enabled = true; return; } //------------------------------- Rectangle rc = Rectangle.Empty; foreach (var pair in blobs) { CvBlob b = pair.Value; rc = b.BoundingBox; //CvInvoke.Rectangle(imgBgr, b.BoundingBox, new MCvScalar(255.0, 0, 0), 2); break; } // -------Detect Blue Region ---- / imgGray = imgBgr.Convert <Gray, Byte>(); pData = imgGray.Data; for (int y = 0; y < nHei; y++) { for (int x = 0; x < nWid; x++) { if (!rc.Contains(x, y)) { pData[y, x, 0] = 0; continue; } byte c = pData[y, x, 0]; if (c >= 100 && c <= 120) { pData[y, x, 0] = 255; } else { pData[y, x, 0] = 0; } } } blobs.Clear(); _blobDetector.Detect(imgGray, blobs); blobs.FilterByArea(100, int.MaxValue); //_tracker.Process(smoothedFrame, forgroundMask); if (blobs.Count < 1) { timer_process.Enabled = true; return; } //------------------------------- rc = Rectangle.Empty; int nSizeMax = 0; foreach (var pair in blobs) { CvBlob b = pair.Value; if (b.BoundingBox.Width * b.BoundingBox.Height > nSizeMax) { rc = b.BoundingBox; nSizeMax = rc.Width * rc.Height; } //break; } CvInvoke.Rectangle(imgBgr, rc, new MCvScalar(255, 255, 0), 2); Global.g_rcROI = rc; Global.DEF_MAIN_BOARD_X = 238; Global.DEF_MAIN_BOARD_Y = 42; Global.DEF_MAIN_BOARD_W = 570; Global.DEF_MAIN_BOARD_H = 570; int nGameBoardX = Global.DEF_MAIN_BOARD_X + rc.X; int nGameBoardY = Global.DEF_MAIN_BOARD_Y + rc.Y; Global.GetRatioCalcedValues(rc.Width, rc.Height, ref nGameBoardX, ref nGameBoardY); Global.GetRatioCalcedValues(rc.Width, rc.Height, ref Global.DEF_MAIN_BOARD_W, ref Global.DEF_MAIN_BOARD_H); CvInvoke.Rectangle(imgBgr, new Rectangle(nGameBoardX, nGameBoardY, Global.DEF_MAIN_BOARD_W, Global.DEF_MAIN_BOARD_H), new MCvScalar(255, 255, 0), 2); Global.DEF_MARKS_X = 15; Global.DEF_MARKS_Y = 204; Global.DEF_MARKS_W = 189; Global.DEF_MARKS_H = 69; int nMarksX = Global.DEF_MARKS_X + rc.X; int nMarksY = Global.DEF_MARKS_Y + rc.Y; Global.GetRatioCalcedValues(rc.Width, rc.Height, ref nMarksX, ref nMarksY); Global.GetRatioCalcedValues(rc.Width, rc.Height, ref Global.DEF_MARKS_W, ref Global.DEF_MARKS_H); CvInvoke.Rectangle(imgBgr, new Rectangle(nMarksX, nMarksY, Global.DEF_MARKS_W, Global.DEF_MARKS_H), new MCvScalar(255, 255, 0), 2); int nStepX = Global.DEF_MAIN_BOARD_W / 8; int nStepY = Global.DEF_MAIN_BOARD_H / 8; var rois = new List <Rectangle>(); // List of rois var imageparts = new List <Image <Bgr, byte> >(); // List of extracted image parts for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { Rectangle roi = new Rectangle(nGameBoardX + j * nStepX, nGameBoardY + i * nStepY, Global.DEF_ITEM_W, Global.DEF_ITEM_H); rois.Add(roi); imgBgr.ROI = roi; imageparts.Add(imgBgr.Copy()); } } imgBgr.ROI = Rectangle.Empty; m_LstCharacter.Clear(); bool bCanProcess = true; int k = 0, nRow = 0, nCol = 0; foreach (Image <Bgr, Byte> img in imageparts) { int nCharac = (int)ImageMatcher.DetermineCharacter(img); m_LstCharacter.Add(nCharac); MovementDecision.g_AllocCharacters[nRow, nCol] = nCharac; nCol++; if (nCol >= 8) { nRow++; nCol = 0; } //if (nCharac != 0) CvInvoke.Rectangle(imgBgr, rois[k], new MCvScalar(255, 255, 0), 2); //CvInvoke.Rectangle(imgBgr, rois[k], cols[nCharac - 1], 2); if (nCharac == 0) { bCanProcess = false; } k++; } string szLine = ""; lstBox.Items.Clear(); for (int i = 0; i < 8; i++) { szLine = ""; for (int j = 0; j < 8; j++) { szLine += "" + MovementDecision.g_AllocCharacters[i, j] + " "; } lstBox.Items.Add(szLine); } //imgBgr.Save("processed.png"); picScr.Image = imgBgr.Bitmap; if (!bCanProcess) { timer_process.Enabled = true; return; } MovementDecision.Process(); long Ticks2 = DateTime.Now.Millisecond; lbProcessTime.Text = "" + (Ticks2 - Ticks); timer_process.Enabled = true; }