//Esta função detecta a linhas a preto //guarda o centroide da linha com área maior //desenha o centroide e o contorno da linha seleccionada //img - imagem a cores BGR public Image <Gray, Byte> Deteccao_Linha(Image <Bgr, Byte> img) { double areaC = 0; double area_max = 0; IntPtr seq_max = CvInvoke.cvCreateMemStorage(0); IntPtr storage = CvInvoke.cvCreateMemStorage(0); IntPtr contornos = new IntPtr(); MCvMoments moments = new MCvMoments(); Image <Gray, Byte> img_Contornos = new Image <Gray, Byte>(img.Width, img.Height); Emgu.CV.Image <Gray, Byte> img_Gray = img.Convert <Gray, Byte>(); //Pré-processamento img_Gray.SmoothMedian(5); img_Gray._EqualizeHist(); //Detecção da linha Emgu.CV.Image <Gray, Byte> img_aux = img_Gray.Canny(1, 1, 5); img_Gray = img_aux.Not(); img_aux = img_Gray.Erode(10); img_Gray = img_aux.Dilate(10); //detecta contornos CvInvoke.cvCopy(img_Gray, img_Contornos, System.IntPtr.Zero); CvInvoke.cvFindContours(img_Contornos, storage, ref contornos, System.Runtime.InteropServices.Marshal.SizeOf(typeof(MCvContour)), Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL, Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, new Point(0, 0)); //percorre os contornos e detecta o que tem a maior área Seq <Point> seq = new Seq <Point>(contornos, null); for (; seq != null && seq.Ptr.ToInt64() != 0; seq = seq.HNext) { areaC = CvInvoke.cvContourArea(seq, MCvSlice.WholeSeq, 1) * -1; if (areaC > area_max) { area_max = areaC; seq_max = seq.Ptr; } } //calcula o centroide do contorno com maior área if (areaC > 0) { CvInvoke.cvMoments(seq_max, ref moments, 0); Obj_centroid.X = (int)(moments.m10 / moments.m00); Obj_centroid.Y = (int)(moments.m01 / moments.m00); //desenha contorno com maior área CvInvoke.cvDrawContours(img, seq_max, new MCvScalar(0, 0, 255), new MCvScalar(255, 0, 0), 0, 2, LINE_TYPE.CV_AA, new Point(0, 0)); CvInvoke.cvCircle(img, new Point(Obj_centroid.X, Obj_centroid.Y), 10, new MCvScalar(0, 255, 0), 3, LINE_TYPE.CV_AA, 0); } else { Obj_centroid.X = -1; Obj_centroid.Y = -1; } return(img_Gray); }