コード例 #1
0
        //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);
        }