/// <summary> /// Takes image on input and returns the selected regions in a vector of ERStat only distinctive ERs which correspond to characters are selected by a sequential classifier /// </summary> /// <param name="image">Sinle channel image CV_8UC1</param> /// <param name="regions">Output for the 1st stage and Input/Output for the 2nd. The selected Extremal Regions are stored here.</param> public void Run(IInputArray image, VectorOfERStat regions) { using (InputArray iaImage = image.GetInputArray()) CvERFilterRun(_ptr, iaImage, regions); }
public void Run(Image<Gray, Byte> image, VectorOfERStat regions) { CvInvoke.CvERFilterRun(_ptr, image, regions); }
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); } }
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); } } }
/// <summary> /// Find groups of Extremal Regions that are organized as text blocks. /// </summary> /// <param name="image">The image where ER grouping is to be perform on</param> /// <param name="channels">Array of single channel images from which the regions were extracted</param> /// <param name="erstats">Vector of ER’s retrieved from the ERFilter algorithm from each channel</param> /// <param name="groupingTrainedFileName">The XML or YAML file with the classifier model (e.g. trained_classifier_erGrouping.xml)</param> /// <param name="minProbability">The minimum probability for accepting a group.</param> /// <param name="groupMethods">The grouping methods</param> /// <returns>The output of the algorithm that indicates the text regions</returns> public static System.Drawing.Rectangle[] ERGrouping(IInputArray image, IInputArrayOfArrays channels, VectorOfERStat[] erstats, GroupingMethod groupMethods = GroupingMethod.OrientationHoriz, String groupingTrainedFileName = null, float minProbability = 0.5f) { IntPtr[] erstatPtrs = new IntPtr[erstats.Length]; for (int i = 0; i < erstatPtrs.Length; i++) { erstatPtrs[i] = erstats[i].Ptr; } using (VectorOfVectorOfPoint regionGroups = new VectorOfVectorOfPoint()) using (VectorOfRect groupsBoxes = new VectorOfRect()) using (InputArray iaImage = image.GetInputArray()) using (InputArray iaChannels = channels.GetInputArray()) using (CvString s = (groupingTrainedFileName == null ? new CvString() : new CvString(groupingTrainedFileName))) { GCHandle erstatsHandle = GCHandle.Alloc(erstatPtrs, GCHandleType.Pinned); CvERGrouping( iaImage, iaChannels, erstatsHandle.AddrOfPinnedObject(), erstatPtrs.Length, regionGroups, groupsBoxes, groupMethods, s, minProbability); erstatsHandle.Free(); return groupsBoxes.ToArray(); } }