public VectorOfUMat ForwardFt(UMat img)
        {
            ///outputs quadrant-rearranged {magnitude, phase} UMat array
            ///FT stuff, reference: https://docs.opencv.org/master/d8/d01/tutorial_discrete_fourier_transform.html
            //convert image to 32bit float because spacial frequency domain values are way bigger than spatial domain values.
            img.ConvertTo(img, DepthType.Cv32F);

            //create imaginary image of zeros of same depthType and size as image representing real plane
            UMat zeros = new UMat(img.Size, img.Depth, 1);

            zeros.SetTo(new MCvScalar(0));

            //Dft accepts 2-channel images, so we use Merge to merge our 2 1-channel images into a single 2-channel image.
            //Merge accepts object arrays, so we create a VectorOfUMat of our 2 images to feed into Merge.
            VectorOfUMat vec = new VectorOfUMat(img, zeros);            //img will be at 0 index of vector

            using (UMat cImg = new UMat()) {
                CvInvoke.Merge(vec, cImg);
                zeros.Dispose();                              // TODO: fix this bad programming and other instances of it.
                CvInvoke.Dft(cImg, cImg, DxtType.Forward, 0); //use back the same image memory
                SwitchQuadrants(cImg);
                CvInvoke.Split(cImg, vec);
            }

            //make the 2-channel array into 2 1-channel arrays
            return(vec);            //[0] index contains the real values and [1] index the complex values
        }
        public VectorOfUMat InverseFt(UMat re, UMat im)
        {
            ///reference: https://stackoverflow.com/questions/16812950/how-do-i-compute-dft-and-its-reverse-with-emgu
            VectorOfUMat vec = new VectorOfUMat(re, im);

            using (UMat cImg = new UMat()) {
                CvInvoke.Merge(vec, cImg);                //because Dft method accepts and outputs 2-channel image
                CvInvoke.Dft(cImg, cImg, DxtType.Inverse, 0);
                CvInvoke.Split(cImg, vec);
            }
            return(vec);
        }
Exemplo n.º 3
0
        /*
         * /// <summary>
         * /// Convert this Mat to UMat
         * /// </summary>
         * /// <param name="access">Access type</param>
         * /// <returns>The UMat</returns>
         * public Mat ToMat(CvEnum.AccessType access)
         * {
         * return new Mat(UMatInvoke.cvUMatGetMat(Ptr, access), true);
         * }*/

        ///<summary>
        ///Split current Image into an array of gray scale images where each element
        ///in the array represent a single color channel of the original image
        ///</summary>
        ///<returns>
        ///An array of gray scale images where each element
        ///in the array represent a single color channel of the original image
        ///</returns>
        public UMat[] Split()
        {
            UMat[] mats = new UMat[NumberOfChannels];
            for (int i = 0; i < mats.Length; i++)
            {
                mats[i] = new UMat(Rows, Cols, Depth, NumberOfChannels);
            }
            using (VectorOfUMat vm = new VectorOfUMat(mats))
            {
                CvInvoke.Split(this, vm);
            }
            return(mats);
        }
Exemplo n.º 4
0
        public static UMat getSaturationAdjusted(ref UMat img, double amount)
        {
            Image <Hsv, double> outImg = img.ToImage <Hsv, double>();
            UMat dblImg = new UMat(img.Rows, img.Cols, Emgu.CV.CvEnum.DepthType.Cv64F, img.NumberOfChannels);

            outImg = img.ToImage <Hsv, double>();
            var colors = new VectorOfUMat(3);

            CvInvoke.Split(outImg, colors);
            double shift = (1 + amount) >= 0.0 ? 1 + amount : 0;

            CvInvoke.AddWeighted(colors[1], shift, colors[1], 0, 0, colors[1]);
            CvInvoke.Merge(colors, dblImg);
            return(dblImg);
        }
Exemplo n.º 5
0
        /*
         * /// <summary>
         * /// Convert this Mat to UMat
         * /// </summary>
         * /// <param name="access">Access type</param>
         * /// <returns>The UMat</returns>
         * public Mat ToMat(CvEnum.AccessType access)
         * {
         * return new Mat(UMatInvoke.cvUMatGetMat(Ptr, access), true);
         * }*/

        ///<summary>
        ///Split current Image into an array of gray scale images where each element
        ///in the array represent a single color channel of the original image
        ///</summary>
        ///<returns>
        ///An array of gray scale images where each element
        ///in the array represent a single color channel of the original image
        ///</returns>
        public UMat[] Split()
        {
            UMat[]    mats = new UMat[NumberOfChannels];
            Size      s    = this.Size;
            DepthType d    = this.Depth;

            for (int i = 0; i < mats.Length; i++)
            {
                mats[i] = new UMat(s, d, 1);
            }
            using (VectorOfUMat vm = new VectorOfUMat(mats))
            {
                CvInvoke.Split(this, vm);
            }
            return(mats);
        }
Exemplo n.º 6
0
        public static UMat getColorAdjusted(ref UMat img, double redshift, double greenshift, double blueshift)
        {
            double shift;
            UMat   dblImg = new UMat(img.Rows, img.Cols, Emgu.CV.CvEnum.DepthType.Cv64F, img.NumberOfChannels);

            img.ConvertTo(dblImg, Emgu.CV.CvEnum.DepthType.Cv64F);
            var colors = new VectorOfUMat(3);

            CvInvoke.Split(img, colors);
            shift = (1 + redshift) > 0 ? (1 + redshift) : 0;
            CvInvoke.AddWeighted(colors[2], shift, colors[2], 0, 0, colors[2]);
            shift = (1 + greenshift) > 0 ? (1 + greenshift) : 0;
            CvInvoke.AddWeighted(colors[1], shift, colors[1], 0, 0, colors[1]);
            shift = (1 + blueshift) > 0 ? (1 + blueshift) : 0;
            CvInvoke.AddWeighted(colors[0], shift, colors[0], 0, 0, colors[0]);
            CvInvoke.Merge(colors, dblImg);
            img.Dispose();
            return(dblImg);
        }
Exemplo n.º 7
0
        public void InverseT(UMat reIn, UMat imIn, UMat magOut, UMat phOut)
        {
            ///accepts real and imaginary parts, inverse (fourier) Transforms
            ///converts real and imaginary output parts to magnitude and
            ///phase, returns magnitude and phase parts.
            ///Refer to ForwardT() for more info on why I code like this.
            ///Reference: https://stackoverflow.com/questions/16812950/how-do-i-compute-dft-and-its-reverse-with-emgu

            VectorOfUMat vec = this.vec;

            vec.Push(reIn);
            vec.Push(imIn);
            UMat cImg = this.img32f2c;

            CvInvoke.Merge(vec, cImg);            //because Dft method accepts and outputs 2-channel image
            CvInvoke.Dft(cImg, cImg, DxtType.Inverse, 0);
            //new objects put into vec, vec[0] is reOut, vec[1] is imOut.
            CvInvoke.Split(cImg, vec);
            //convert output of inverse Transform to magnitude and polar
            CvInvoke.CartToPolar(vec[0], vec[1], magOut, phOut);
            vec.Clear();
        }
Exemplo n.º 8
0
        private static String OcrImage(Tesseract ocr, Mat image, OCRMode mode, Mat imageColor)
        {
            Bgr drawCharColor = new Bgr(Color.Red);

            if (image.NumberOfChannels == 1)
            {
                CvInvoke.CvtColor(image, imageColor, ColorConversion.Gray2Bgr);
            }
            else
            {
                image.CopyTo(imageColor);
            }

            if (mode == OCRMode.FullPage)
            {
                ocr.SetImage(imageColor);

                if (ocr.Recognize() != 0)
                {
                    throw new Exception("Failed to recognizer image");
                }

                Tesseract.Character[] characters = ocr.GetCharacters();
                if (characters.Length == 0)
                {
                    Mat imgGrey = new Mat();
                    CvInvoke.CvtColor(image, imgGrey, ColorConversion.Bgr2Gray);
                    Mat imgThresholded = new Mat();
                    CvInvoke.Threshold(imgGrey, imgThresholded, 65, 255, ThresholdType.Binary);
                    ocr.SetImage(imgThresholded);
                    characters = ocr.GetCharacters();
                    imageColor = imgThresholded;
                    if (characters.Length == 0)
                    {
                        CvInvoke.Threshold(image, imgThresholded, 190, 255, ThresholdType.Binary);
                        ocr.SetImage(imgThresholded);
                        characters = ocr.GetCharacters();
                        imageColor = imgThresholded;
                    }
                }
                foreach (Tesseract.Character c in characters)
                {
                    CvInvoke.Rectangle(imageColor, c.Region, drawCharColor.MCvScalar);
                }

                return(ocr.GetUTF8Text());
            }
            else
            {
                bool checkInvert = true;

                Rectangle[] regions;

                using (
                    ERFilterNM1 er1 = new ERFilterNM1("trained_classifierNM1.xml", 8, 0.00025f, 0.13f, 0.4f, true, 0.1f))
                    using (ERFilterNM2 er2 = new ERFilterNM2("trained_classifierNM2.xml", 0.3f))
                    {
                        int    channelCount = image.NumberOfChannels;
                        UMat[] channels     = new UMat[checkInvert ? channelCount * 2 : channelCount];

                        for (int i = 0; i < channelCount; i++)
                        {
                            UMat c = new UMat();
                            CvInvoke.ExtractChannel(image, c, i);
                            channels[i] = c;
                        }

                        if (checkInvert)
                        {
                            for (int i = 0; i < channelCount; i++)
                            {
                                UMat c = new UMat();
                                CvInvoke.BitwiseNot(channels[i], c);
                                channels[i + channelCount] = c;
                            }
                        }

                        VectorOfERStat[] regionVecs = new VectorOfERStat[channels.Length];
                        for (int i = 0; i < regionVecs.Length; i++)
                        {
                            regionVecs[i] = new VectorOfERStat();
                        }

                        try
                        {
                            for (int i = 0; i < channels.Length; i++)
                            {
                                er1.Run(channels[i], regionVecs[i]);
                                er2.Run(channels[i], regionVecs[i]);
                            }
                            using (VectorOfUMat vm = new VectorOfUMat(channels))
                            {
                                regions = ERFilter.ERGrouping(image, vm, regionVecs, ERFilter.GroupingMethod.OrientationHoriz,
                                                              "trained_classifier_erGrouping.xml", 0.5f);
                            }
                        }
                        finally
                        {
                            foreach (UMat tmp in channels)
                            {
                                if (tmp != null)
                                {
                                    tmp.Dispose();
                                }
                            }
                            foreach (VectorOfERStat tmp in regionVecs)
                            {
                                if (tmp != null)
                                {
                                    tmp.Dispose();
                                }
                            }
                        }

                        Rectangle imageRegion = new Rectangle(Point.Empty, imageColor.Size);
                        for (int i = 0; i < regions.Length; i++)
                        {
                            Rectangle r = ScaleRectangle(regions[i], 1.1);

                            r.Intersect(imageRegion);
                            regions[i] = r;
                        }
                    }


                List <Tesseract.Character> allChars = new List <Tesseract.Character>();
                String allText = String.Empty;
                foreach (Rectangle rect in regions)
                {
                    using (Mat region = new Mat(image, rect))
                    {
                        ocr.SetImage(region);
                        if (ocr.Recognize() != 0)
                        {
                            throw new Exception("Failed to recognize image");
                        }
                        Tesseract.Character[] characters = ocr.GetCharacters();

                        //convert the coordinates from the local region to global
                        for (int i = 0; i < characters.Length; i++)
                        {
                            Rectangle charRegion = characters[i].Region;
                            charRegion.Offset(rect.Location);
                            characters[i].Region = charRegion;
                        }
                        allChars.AddRange(characters);

                        allText += ocr.GetUTF8Text() + Environment.NewLine;
                    }
                }

                Bgr drawRegionColor = new Bgr(Color.Red);
                foreach (Rectangle rect in regions)
                {
                    CvInvoke.Rectangle(imageColor, rect, drawRegionColor.MCvScalar);
                }
                foreach (Tesseract.Character c in allChars)
                {
                    CvInvoke.Rectangle(imageColor, c.Region, drawCharColor.MCvScalar);
                }

                return(allText);
            }
        }
Exemplo n.º 9
0
        public void ProcessForwardT(UMat inImg, UMat outMagT, UMat outPhT, bool zeroPad = false, bool switchQuadrants = true)
        {
            ///Accepts a 1-channel image, updates outMagT and outPhT.
            ///magnitude and phase, cause I can't think of why you
            ///would wanna look at real and imaginary Transforms.
            ///Also can't think of how you can get complex-valued images.
            ///Quadrant rearranging doesn't support odd rows or cols.
            ///T stuff, reference: https://docs.opencv.org/master/d8/d01/tutorial_discrete_fourier_transform.html
            //convert image to 32bit float because spacial frequency
            //domain values are way bigger than spatial domain values.
            UMat re = outMagT;            //32-bit float real image, use memory from

            //outMagT cause it's gonna be updated anyway
            inImg.ConvertTo(re, DepthType.Cv32F);
            if (zeroPad)
            {
                //zero pad for faster dft
                ZeroPadImage(re);
            }
            //create imaginary image of zeros of same depthType
            //and size as image representing real plane
            UMat im = outPhT;                                           //imaginary

            im.Create(re.Rows, re.Cols, re.Depth, re.NumberOfChannels); //allocate memory so you can set it to zero array
            //if memory hasn't already been allocated for it
            im.SetTo(new MCvScalar(0));

            /// Quick exerpt about VectorOfUMat:
            /// if you create a VectorOfUMat vec, only if the first UMat variable
            /// to store the object is the vector node, like
            /// VectorOfUMat vec = new VectorOfUmat(new Umat(), new Umat());
            /// vec.Push(someUMat.Clone());
            /// then vec.Dispose/Clear actually disposes all the objects referenced
            /// to by the UMats in vec. In this case, if you did:
            /// VectorOfUMat vec = new VectorOfUMat(inImg.Clone(), inImg.Clone());
            /// UMat one = vec[0];
            /// one.Dispose();
            /// one.Dispose actually does nothing.
            /// Otherwise, if
            /// UMat one = new UMat();
            /// UMat two = new UMat();
            /// VectorOfUMat vec = new VectorOfUmat(one);
            /// vec.Push(two);
            /// calling vec.Dispose() doesn't dispose the objects.
            /// you have to call one.Dispose and two.Dispose.
            /// Note: no matter whether the UMat's first variable stored
            /// in is in a vector node or not, calling vec[index].Dispose
            /// does NOTHING.
            /// The situation is the same for vec.Clear, except Clear doesn't
            /// dispose of vec itself, it just disposes the objects the UMats in
            /// it reference to.
            //Dft accepts 2-channel images, so we use Merge to merge
            //our 2 1-channel images into a single 2-channel image.
            //Merge accepts object arrays, so we create a VectorOfUMat
            //of our 2 images to feed into Merge.

            VectorOfUMat vec  = this.vec;
            UMat         cImg = this.img32f2c;

            vec.Push(re);
            vec.Push(im);            //vec[0] = re, vec[1] = im
            ;
            CvInvoke.Merge(vec, cImg);
            CvInvoke.Dft(cImg, cImg, DxtType.Forward, 0);            //use back the same memory
            //switch quadrants while images are still combined
            if (switchQuadrants)
            {
                SwitchQuadrants(cImg);
            }
            //make the 2-channel array into 2 1-channel arrays
            CvInvoke.Split(cImg, vec); //vec[0] is reT, vec[1] is imT, they are new objects.
            CvInvoke.CartToPolar(vec[0], vec[1], outMagT, outPhT);
            vec.Clear();               //dispose reT and imT.TODO: find a way to get rid of allocating memory for reT and imT.
        }
Exemplo n.º 10
0
      public void TestERFilter()
      {
         CvInvoke.SanityCheck();
         bool checkInvert = true;
         using (Image<Bgr, Byte> image = EmguAssert.LoadImage<Bgr, Byte>("scenetext01.jpg"))
         using (ERFilterNM1 er1 = new ERFilterNM1(EmguAssert.GetFile("trained_classifierNM1.xml"), 8, 0.00025f, 0.13f, 0.4f, true, 0.1f))
         using (ERFilterNM2 er2 = new ERFilterNM2(EmguAssert.GetFile("trained_classifierNM2.xml"), 0.3f))
         {
            //using (Image<Gray, Byte> mask = new Image<Gray,byte>(image.Size.Width + 2, image.Size.Height + 2))
            int channelCount = image.NumberOfChannels;
            UMat[] channels = new UMat[checkInvert ? channelCount * 2 : channelCount];
            
            for (int i = 0; i < channelCount; i++)
            {
               UMat c = new UMat();
               CvInvoke.ExtractChannel(image.Mat, c, i);
               channels[i] = c;
            }

            if (checkInvert)
            {
               for (int i = 0; i < channelCount; i++)
               {
                  UMat c = new UMat();
                  CvInvoke.BitwiseNot(channels[i], c);
                  channels[i + channelCount] = c;
               }
            }

            VectorOfERStat[] regionVecs = new VectorOfERStat[channels.Length];
            for (int i = 0; i < regionVecs.Length; i++)
               regionVecs[i] = new VectorOfERStat();

            /*
            for (int i = 0; i < channels.Length; i++)
            {
               Emgu.CV.UI.ImageViewer.Show(channels[i]);
            }*/
            
            try
            {
               for (int i = 0; i < channels.Length; i++)
               {
                  er1.Run(channels[i], regionVecs[i]);
                  er2.Run(channels[i], regionVecs[i]);
               }
               using (VectorOfUMat vm = new VectorOfUMat(channels))
               {
                  Rectangle[] regions = ERFilter.ERGrouping(image, vm, regionVecs, ERFilter.GroupingMethod.OrientationHoriz, EmguAssert.GetFile("trained_classifier_erGrouping.xml"), 0.5f);

                  foreach (Rectangle rect in regions)
                     image.Draw(rect, new Bgr(0, 0, 255), 2);
                  
               }
            }
            finally
            {
               foreach (UMat tmp in channels)
                  if (tmp != null)
                     tmp.Dispose();
               foreach (VectorOfERStat tmp in regionVecs)
                  if (tmp != null)
                     tmp.Dispose();
            }
            //Emgu.CV.UI.ImageViewer.Show(image);
            
         }

      }
Exemplo n.º 11
0
      public void TestDenseHistogram3()
      {
         UMat img = new UMat(400, 400, DepthType.Cv8U, 3);
         CvInvoke.Randu(img, new MCvScalar(), new MCvScalar(255, 255, 255));
         UMat hist = new UMat();
         using (VectorOfUMat vms = new VectorOfUMat(img))
         {
            CvInvoke.CalcHist(vms, new int[] { 0, 1, 2 }, null, hist, new int[] { 20, 20, 20 },
               new float[] { 0, 255, 0, 255, 0, 255 }, true);
            byte[] bytes = hist.Bytes;
            hist.SetTo(bytes);

            float[] bins = new float[20 * 20 * 20];
            hist.CopyTo(bins);
         }
      }
Exemplo n.º 12
0
        private void loadImageButton_Click(object sender, EventArgs e)
        {
            if (openImageFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                fileNameTextBox.Text = openImageFileDialog.FileName;
                imageBox1.Image      = null;
                ocrTextBox.Text      = String.Empty;
                hocrTextBox.Text     = String.Empty;

                Bgr drawCharColor = new Bgr(Color.Blue);
                try
                {
                    Mat image = new Mat(openImageFileDialog.FileName, ImreadModes.AnyColor);

                    Mat imageColor = new Mat();
                    if (image.NumberOfChannels == 1)
                    {
                        CvInvoke.CvtColor(image, imageColor, ColorConversion.Gray2Bgr);
                    }
                    else
                    {
                        image.CopyTo(imageColor);
                    }

                    if (Mode == OCRMode.FullPage)
                    {
                        _ocr.Recognize(image);
                        Tesseract.Character[] characters = _ocr.GetCharacters();
                        if (characters.Length == 0)
                        {
                            Mat imgGrey = new Mat();
                            CvInvoke.CvtColor(image, imgGrey, ColorConversion.Bgr2Gray);
                            Mat imgThresholded = new Mat();
                            CvInvoke.Threshold(imgGrey, imgThresholded, 65, 255, ThresholdType.Binary);
                            _ocr.Recognize(imgThresholded);
                            characters = _ocr.GetCharacters();
                            imageColor = imgThresholded;
                            if (characters.Length == 0)
                            {
                                CvInvoke.Threshold(image, imgThresholded, 190, 255, ThresholdType.Binary);
                                _ocr.Recognize(imgThresholded);
                                characters = _ocr.GetCharacters();
                                imageColor = imgThresholded;
                            }
                        }
                        foreach (Tesseract.Character c in characters)
                        {
                            CvInvoke.Rectangle(imageColor, c.Region, drawCharColor.MCvScalar);
                        }

                        imageBox1.Image = imageColor;

                        String text = _ocr.GetText();
                        ocrTextBox.Text = text;
                        String hocrText = _ocr.GetHOCRText();
                        hocrTextBox.Text = hocrText;
                    }
                    else
                    {
                        bool checkInvert = true;

                        Rectangle[] regions;

                        using (ERFilterNM1 er1 = new ERFilterNM1("trained_classifierNM1.xml", 8, 0.00025f, 0.13f, 0.4f, true, 0.1f))
                            using (ERFilterNM2 er2 = new ERFilterNM2("trained_classifierNM2.xml", 0.3f))
                            {
                                int    channelCount = image.NumberOfChannels;
                                UMat[] channels     = new UMat[checkInvert ? channelCount * 2 : channelCount];

                                for (int i = 0; i < channelCount; i++)
                                {
                                    UMat c = new UMat();
                                    CvInvoke.ExtractChannel(image, c, i);
                                    channels[i] = c;
                                }

                                if (checkInvert)
                                {
                                    for (int i = 0; i < channelCount; i++)
                                    {
                                        UMat c = new UMat();
                                        CvInvoke.BitwiseNot(channels[i], c);
                                        channels[i + channelCount] = c;
                                    }
                                }

                                VectorOfERStat[] regionVecs = new VectorOfERStat[channels.Length];
                                for (int i = 0; i < regionVecs.Length; i++)
                                {
                                    regionVecs[i] = new VectorOfERStat();
                                }

                                try
                                {
                                    for (int i = 0; i < channels.Length; i++)
                                    {
                                        er1.Run(channels[i], regionVecs[i]);
                                        er2.Run(channels[i], regionVecs[i]);
                                    }
                                    using (VectorOfUMat vm = new VectorOfUMat(channels))
                                    {
                                        regions = ERFilter.ERGrouping(image, vm, regionVecs, ERFilter.GroupingMethod.OrientationHoriz, "trained_classifier_erGrouping.xml", 0.5f);
                                    }
                                }
                                finally
                                {
                                    foreach (UMat tmp in channels)
                                    {
                                        if (tmp != null)
                                        {
                                            tmp.Dispose();
                                        }
                                    }
                                    foreach (VectorOfERStat tmp in regionVecs)
                                    {
                                        if (tmp != null)
                                        {
                                            tmp.Dispose();
                                        }
                                    }
                                }

                                Rectangle imageRegion = new Rectangle(Point.Empty, imageColor.Size);
                                for (int i = 0; i < regions.Length; i++)
                                {
                                    Rectangle r = ScaleRectangle(regions[i], 1.1);

                                    r.Intersect(imageRegion);
                                    regions[i] = r;
                                }
                            }


                        List <Tesseract.Character> allChars = new List <Tesseract.Character>();
                        String allText = String.Empty;
                        foreach (Rectangle rect in regions)
                        {
                            using (Mat region = new Mat(image, rect))
                            {
                                _ocr.Recognize(region);
                                Tesseract.Character[] characters = _ocr.GetCharacters();

                                //convert the coordinates from the local region to global
                                for (int i = 0; i < characters.Length; i++)
                                {
                                    Rectangle charRegion = characters[i].Region;
                                    charRegion.Offset(rect.Location);
                                    characters[i].Region = charRegion;
                                }
                                allChars.AddRange(characters);

                                allText += _ocr.GetText() + Environment.NewLine;
                            }
                        }

                        Bgr drawRegionColor = new Bgr(Color.Red);
                        foreach (Rectangle rect in regions)
                        {
                            CvInvoke.Rectangle(imageColor, rect, drawRegionColor.MCvScalar);
                        }
                        foreach (Tesseract.Character c in allChars)
                        {
                            CvInvoke.Rectangle(imageColor, c.Region, drawCharColor.MCvScalar);
                        }
                        imageBox1.Image = imageColor;
                        ocrTextBox.Text = allText;
                    }
                }
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message);
                }
            }
        }
Exemplo n.º 13
0
        public void generateChannels(Image <Bgr, byte> img_original, string image_name, string destination_folder)
        {
            Directory.CreateDirectory(destination_folder);
            //string destination_folder = tbDestination.Text;
            img_original = img_original.SmoothGaussian(3);                               //smooth gaussian
            Image <Luv, byte> luv;                                                       //will contain luv image to extract LUV channels

            luv = img_original.Convert <Luv, byte>();                                    //convert from bgr to luv
            VectorOfUMat channels = new VectorOfUMat();                                  //contains luv channels

            CvInvoke.Split(luv, channels);                                               //split them
            Image <Gray, double> image_channel_L = channels[0].ToImage <Gray, double>(); //L channel

            image_channel_L = image_channel_L.SmoothGaussian(3);
            Image <Gray, double> image_channel_U = channels[1].ToImage <Gray, double>(); //U channel

            image_channel_U = image_channel_U.SmoothGaussian(3);
            Image <Gray, double> image_channel_V = channels[2].ToImage <Gray, double>();  //V channel

            image_channel_V = image_channel_V.SmoothGaussian(3);
            CvInvoke.Imwrite(@destination_folder + "__L.jpg", image_channel_L);
            CvInvoke.Imwrite(@destination_folder + "__U.jpg", image_channel_U);
            CvInvoke.Imwrite(@destination_folder + "__V.jpg", image_channel_V);

            Mat gray       = new Mat();                                                     //gray version of the original image
            Mat grad       = new Mat();                                                     //will contain the gradient magnitude
            Mat grad_x     = new Mat();                                                     //sobel x
            Mat grad_y     = new Mat();                                                     //sobel y
            Mat abs_grad_x = new Mat();                                                     //abs
            Mat abs_grad_y = new Mat();
            Mat angles     = new Mat();                                                     //matrix will contain the angle of every edge in grad magnitude channel

            CvInvoke.CvtColor(img_original, gray, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray); //get gray image from bgr

            //channels defined below will contain the edges in different angles
            Image <Gray, UInt16> C1 = new Image <Gray, UInt16>(img_original.Cols, img_original.Rows);
            Image <Gray, UInt16> C2 = new Image <Gray, UInt16>(img_original.Cols, img_original.Rows);
            Image <Gray, UInt16> C3 = new Image <Gray, UInt16>(img_original.Cols, img_original.Rows);
            Image <Gray, UInt16> C4 = new Image <Gray, UInt16>(img_original.Cols, img_original.Rows);
            Image <Gray, UInt16> C5 = new Image <Gray, UInt16>(img_original.Cols, img_original.Rows);
            Image <Gray, UInt16> C6 = new Image <Gray, UInt16>(img_original.Cols, img_original.Rows);


            //apply sobel
            CvInvoke.Sobel(gray, grad_x, Emgu.CV.CvEnum.DepthType.Cv32F, 1, 0, 3);
            CvInvoke.ConvertScaleAbs(grad_x, abs_grad_x, 1, 0);
            CvInvoke.Sobel(gray, grad_y, Emgu.CV.CvEnum.DepthType.Cv32F, 0, 1, 3);
            CvInvoke.ConvertScaleAbs(grad_y, abs_grad_y, 1, 0);
            CvInvoke.AddWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
            Image <Gray, UInt16> img_gradient = grad.ToImage <Gray, UInt16>();  //will store gradient magnitude as an image

            img_gradient = normalize(img_gradient);
            CvInvoke.Imwrite(@destination_folder + "__G.jpg", img_gradient);

            Emgu.CV.Cuda.CudaInvoke.Phase(grad_x, grad_y, angles, true);       //get angles
            Image <Gray, double> img_angles = angles.ToImage <Gray, double>(); //stores the angles as a gray image

            //loop through angles
            for (int i = 0; i < img_angles.Height; i++)
            {
                for (int j = 0; j < img_angles.Width; j++)
                {
                    double current_angle = img_angles.Data[i, j, 0];                         //current angle value in degrees
                    if (current_angle > 180)                                                 //if greater than 180
                    {
                        img_angles.Data[i, j, 0] = (double)(img_angles.Data[i, j, 0] - 180); //fix it
                    }
                    current_angle = img_angles.Data[i, j, 0];                                //update current value

                    //according to the value of the angle, add it to the corresponding channel
                    if (current_angle >= 0 && current_angle <= 30)
                    {
                        addEdgeToChannel(i, j, img_gradient.Data[i, j, 0], C1);
                    }
                    else if (current_angle > 30 && current_angle <= 60)
                    {
                        addEdgeToChannel(i, j, img_gradient.Data[i, j, 0], C2);
                    }
                    else if (current_angle > 60 && current_angle <= 90)
                    {
                        addEdgeToChannel(i, j, img_gradient.Data[i, j, 0], C3);
                    }
                    else if (current_angle > 90 && current_angle <= 120)
                    {
                        addEdgeToChannel(i, j, img_gradient.Data[i, j, 0], C4);
                    }
                    else if (current_angle > 120 && current_angle <= 150)
                    {
                        addEdgeToChannel(i, j, img_gradient.Data[i, j, 0], C5);
                    }
                    else if (current_angle > 150 && current_angle <= 180)
                    {
                        addEdgeToChannel(i, j, img_gradient.Data[i, j, 0], C6);
                    }
                }
            }

            //smooth channels
            C1 = C1.SmoothGaussian(3);
            C2 = C2.SmoothGaussian(3);
            C3 = C3.SmoothGaussian(3);
            C4 = C4.SmoothGaussian(3);
            C5 = C5.SmoothGaussian(3);
            C6 = C6.SmoothGaussian(3);
            CvInvoke.Imwrite(@destination_folder + "__C1.jpg", C1);
            CvInvoke.Imwrite(@destination_folder + "__C2.jpg", C2);
            CvInvoke.Imwrite(@destination_folder + "__C3.jpg", C3);
            CvInvoke.Imwrite(@destination_folder + "__C4.jpg", C4);
            CvInvoke.Imwrite(@destination_folder + "__C5.jpg", C5);
            CvInvoke.Imwrite(@destination_folder + "__C6.jpg", C6);
        }
Exemplo n.º 14
0
      private void loadImageButton_Click(object sender, EventArgs e)
      {
         if (openImageFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
         {
            fileNameTextBox.Text = openImageFileDialog.FileName;
            imageBox1.Image = null;
            ocrTextBox.Text = String.Empty;
            hocrTextBox.Text = String.Empty;

            Bgr drawCharColor = new Bgr(Color.Blue);
            try
            {
               Mat image = new Mat(openImageFileDialog.FileName, ImreadModes.AnyColor);

               Mat imageColor = new Mat();
               if (image.NumberOfChannels == 1)
                  CvInvoke.CvtColor(image, imageColor, ColorConversion.Gray2Bgr);
               else
                  image.CopyTo(imageColor);

               if (Mode == OCRMode.FullPage)
               {
                  _ocr.Recognize(image);
                  Tesseract.Character[] characters = _ocr.GetCharacters();
                  if (characters.Length == 0)
                  {
                     Mat imgGrey = new Mat();
                     CvInvoke.CvtColor(image, imgGrey, ColorConversion.Bgr2Gray);
                     Mat imgThresholded = new Mat();
                     CvInvoke.Threshold(imgGrey, imgThresholded,65, 255, ThresholdType.Binary);
                     _ocr.Recognize(imgThresholded);
                     characters = _ocr.GetCharacters();
                     imageColor = imgThresholded;
                     if (characters.Length == 0)
                     {
                        CvInvoke.Threshold(image, imgThresholded, 190, 255, ThresholdType.Binary);
                        _ocr.Recognize(imgThresholded);
                        characters = _ocr.GetCharacters();
                        imageColor = imgThresholded;
                     }
                  }
                  foreach (Tesseract.Character c in characters)
                  {
                     CvInvoke.Rectangle(imageColor, c.Region, drawCharColor.MCvScalar);
                  }

                  imageBox1.Image = imageColor;

                  String text = _ocr.GetText();
                  ocrTextBox.Text = text;
                  String hocrText = _ocr.GetHOCRText();
                  hocrTextBox.Text = hocrText;
               }
               else
               {
                  bool checkInvert = true;

                  Rectangle[] regions;

                  using (ERFilterNM1 er1 = new ERFilterNM1("trained_classifierNM1.xml", 8, 0.00025f, 0.13f, 0.4f, true, 0.1f))
                  using (ERFilterNM2 er2 = new ERFilterNM2("trained_classifierNM2.xml", 0.3f))
                  {
                     int channelCount = image.NumberOfChannels;
                     UMat[] channels = new UMat[checkInvert ? channelCount * 2 : channelCount];

                     for (int i = 0; i < channelCount; i++)
                     {
                        UMat c = new UMat();
                        CvInvoke.ExtractChannel(image, c, i);
                        channels[i] = c;
                     }

                     if (checkInvert)
                     {
                        for (int i = 0; i < channelCount; i++)
                        {
                           UMat c = new UMat();
                           CvInvoke.BitwiseNot(channels[i], c);
                           channels[i + channelCount] = c;
                        }
                     }

                     VectorOfERStat[] regionVecs = new VectorOfERStat[channels.Length];
                     for (int i = 0; i < regionVecs.Length; i++)
                        regionVecs[i] = new VectorOfERStat();

                     try
                     {
                        for (int i = 0; i < channels.Length; i++)
                        {
                           er1.Run(channels[i], regionVecs[i]);
                           er2.Run(channels[i], regionVecs[i]);
                        }
                        using (VectorOfUMat vm = new VectorOfUMat(channels))
                        {
                           regions = ERFilter.ERGrouping(image, vm, regionVecs, ERFilter.GroupingMethod.OrientationHoriz, "trained_classifier_erGrouping.xml", 0.5f);
                        }
                     }
                     finally
                     {
                        foreach (UMat tmp in channels)
                           if (tmp != null)
                              tmp.Dispose();
                        foreach (VectorOfERStat tmp in regionVecs)
                           if (tmp != null)
                              tmp.Dispose();
                     }

                     Rectangle imageRegion = new Rectangle(Point.Empty, imageColor.Size);
                     for (int i = 0; i < regions.Length; i++)
                     {
                        Rectangle r = ScaleRectangle( regions[i], 1.1);
                        
                        r.Intersect(imageRegion);
                        regions[i] = r;
                     }
                     
                  }

                  
                  List<Tesseract.Character> allChars = new List<Tesseract.Character>();
                  String allText = String.Empty;
                  foreach (Rectangle rect in regions)
                  {  
                     using (Mat region = new Mat(image, rect))
                     {
                        _ocr.Recognize(region);
                        Tesseract.Character[] characters = _ocr.GetCharacters();
                        
                        //convert the coordinates from the local region to global
                        for (int i = 0; i < characters.Length; i++)
                        {
                           Rectangle charRegion = characters[i].Region;
                           charRegion.Offset(rect.Location);
                           characters[i].Region = charRegion;
                           
                        }
                        allChars.AddRange(characters);
       
                        allText += _ocr.GetText() + Environment.NewLine;

                     }
                  }

                  Bgr drawRegionColor = new Bgr(Color.Red);
                  foreach (Rectangle rect in regions)
                  {
                     CvInvoke.Rectangle(imageColor, rect, drawRegionColor.MCvScalar);
                  }
                  foreach (Tesseract.Character c in allChars)
                  {
                     CvInvoke.Rectangle(imageColor, c.Region, drawCharColor.MCvScalar);
                  }
                  imageBox1.Image = imageColor;
                  ocrTextBox.Text = allText;

               }
            }
            catch (Exception exception)
            {
               MessageBox.Show(exception.Message);
            }
         }
      }
        public string Recognize(Mat image)
        {
            Rectangle[] regions;
            Bgr         drawCharColor = new Bgr(Color.Red);

            using (var er1 = new ERFilterNM1("Assets\\trained_classifierNM1.xml", 8, 0.00025f, 0.13f, 0.4f, true, 0.1f)) {
                using (var er2 = new ERFilterNM2("Assets\\trained_classifierNM2.xml", 0.3f)) {
                    var channelCount = image.NumberOfChannels;
                    var channels     = new UMat[channelCount * 2];

                    for (int i = 0; i < channelCount; i++)
                    {
                        var c = new UMat();
                        CvInvoke.ExtractChannel(image, c, i);
                        channels[i] = c;
                    }

                    for (int i = 0; i < channelCount; i++)
                    {
                        var c = new UMat();
                        CvInvoke.BitwiseNot(channels[i], c);
                        channels[i + channelCount] = c;
                    }

                    var regionVecs = new VectorOfERStat[channels.Length];
                    for (int i = 0; i < regionVecs.Length; i++)
                    {
                        regionVecs[i] = new VectorOfERStat();
                    }
                    try {
                        for (int i = 0; i < channels.Length; i++)
                        {
                            er1.Run(channels[i], regionVecs[i]);
                            er2.Run(channels[i], regionVecs[i]);
                        }
                        using (var vm = new VectorOfUMat(channels)) {
                            regions = ERFilter.ERGrouping(image, vm, regionVecs, ERFilter.GroupingMethod.OrientationHoriz,
                                                          "Assets\\trained_classifier_erGrouping.xml", 0.5f);
                        }
                    }
                    finally {
                        foreach (UMat tmp in channels)
                        {
                            if (tmp != null)
                            {
                                tmp.Dispose();
                            }
                        }
                        foreach (VectorOfERStat tmp in regionVecs)
                        {
                            if (tmp != null)
                            {
                                tmp.Dispose();
                            }
                        }
                    }
                    Rectangle imageRegion = new Rectangle(Point.Empty, image.Size);
                    for (int i = 0; i < regions.Length; i++)
                    {
                        Rectangle r = ScaleRectangle(regions[i], 1.1);

                        r.Intersect(imageRegion);
                        regions[i] = r;
                    }
                }

                var    allChars = new List <Tesseract.Character>();
                String allText  = String.Empty;
                foreach (Rectangle rect in regions)
                {
                    using (Mat region = new Mat(image, rect)) {
                        _ocr.SetImage(region);
                        if (_ocr.Recognize() != 0)
                        {
                            return(null);
                        }
                        //var characters = _ocr.GetCharacters();

                        ////convert the coordinates from the local region to global
                        //for (int i = 0; i < characters.Length; i++) {
                        //    Rectangle charRegion = characters[i].Region;
                        //    charRegion.Offset(rect.Location);
                        //    characters[i].Region = charRegion;
                        //}
                        //allChars.AddRange(characters);
                        allText += _ocr.GetUTF8Text() + "|";
                    }
                }

                //Bgr drawRegionColor = new Bgr(Color.Red);
                //foreach (Rectangle rect in regions) {
                //    CvInvoke.Rectangle(image, rect, drawRegionColor.MCvScalar);
                //}
                //foreach (Tesseract.Character c in allChars) {
                //    CvInvoke.Rectangle(image, c.Region, drawCharColor.MCvScalar);
                //}

                return(allText);
            }
        }