///// <summary> ///// Detects the page orientation, with corresponding confidence when using <see cref="PageSegMode.OsdOnly"/>. ///// </summary> ///// <remarks> ///// If using full page segmentation mode (i.e. AutoOsd) then consider using <see cref="AnalyseLayout"/> instead as this also provides a ///// deskew angle which isn't available when just performing orientation detection. ///// </remarks> ///// <param name="orientation">The page orientation.</param> ///// <param name="confidence">The confidence level of the orientation (15 is reasonably confident).</param> ///// //[Obsolete("Use DetectBestOrientation(int orientationDegrees, float confidence) that returns orientation in degrees instead.")] //public void DetectBestOrientation(out Orientation orientation,out float confidence) //{ // int orientationDegrees; // float orientationConfidence; // DetectBestOrientation(out orientationDegrees,out orientationConfidence); // // convert angle to 0-360 (shouldn't be required but do it just o be safe). // orientationDegrees = orientationDegrees % 360; // if (orientationDegrees < 0) // { // orientationDegrees += 360; // } // if (orientationDegrees > 315 || orientationDegrees <= 45) // { // orientation = Orientation.PageUp; // } // else if (orientationDegrees > 45 && orientationDegrees <= 135) // { // orientation = Orientation.PageRight; // } // else if (orientationDegrees > 135 && orientationDegrees <= 225) // { // orientation = Orientation.PageDown; // } // else // { // orientation = Orientation.PageLeft; // } // confidence = orientationConfidence; //} ///// <summary> ///// Detects the page orientation, with corresponding confidence when using <see cref="PageSegMode.OsdOnly"/>. ///// </summary> ///// <remarks> ///// If using full page segmentation mode (i.e. AutoOsd) then consider using <see cref="AnalyseLayout"/> instead as this also provides a ///// deskew angle which isn't available when just performing orientation detection. ///// </remarks> ///// <param name="orientation">The detected clockwise page rotation in degrees (0, 90, 180, or 270).</param> ///// <param name="confidence">The confidence level of the orientation (15 is reasonably confident).</param> //public void DetectBestOrientation(out int orientation,out float confidence) //{ // string scriptName; // float scriptConfidence; // DetectBestOrientationAndScript(out orientation,out confidence,out scriptName,out scriptConfidence); //} ///// <summary> ///// Detects the page orientation, with corresponding confidence when using <see cref="PageSegMode.OsdOnly"/>. ///// </summary> ///// <remarks> ///// If using full page segmentation mode (i.e. AutoOsd) then consider using <see cref="AnalyseLayout"/> instead as this also provides a ///// deskew angle which isn't available when just performing orientation detection. ///// </remarks> ///// <param name="orientation">The detected clockwise page rotation in degrees (0, 90, 180, or 270).</param> ///// <param name="confidence">The confidence level of the orientation (15 is reasonably confident).</param> ///// <param name="scriptName">The name of the script (e.g. Latin)</param> ///// <param name="scriptConfidence">The confidence level in the script</param> //public void DetectBestOrientationAndScript(out int orientation,out float confidence,out string scriptName,out float scriptConfidence) //{ // int orient_deg; // float orient_conf; // float script_conf; // if (TessApiSignatures.TessBaseAPIDetectOrientationScript(Engine.Handle,out orient_deg,out orient_conf,out scriptName,out script_conf)) // { // orientation = orient_deg; // confidence = orient_conf; // scriptConfidence = script_conf; // } // else // { // throw new TesseractException("Failed to detect image orientation."); // } //} internal void Recognize() { Guard.Verify(PageSegmentMode != PageSegMode.OsdOnly, "Cannot OCR image when using OSD only page segmentation, please use DetectBestOrientation instead."); if (!runRecognitionPhase) { if (TessApiSignatures.BaseApiRecognize(Engine.Handle, new HandleRef(this, IntPtr.Zero)) != 0) { throw new InvalidOperationException("Recognition of image failed."); } runRecognitionPhase = true; // now write out the thresholded image if required to do so bool tesseditWriteImages; if (Engine.TryGetBoolVariable("tessedit_write_images", out tesseditWriteImages) && tesseditWriteImages) { using (var thresholdedImage = GetThresholdedImage()) { var filePath = Path.Combine(Environment.CurrentDirectory, "tessinput.tif"); try { thresholdedImage.Save(filePath, ImageFormat.TiffG4); trace.TraceEvent(TraceEventType.Information, 2, "Successfully saved the thresholded image to '{0}'", filePath); } catch (Exception error) { trace.TraceEvent(TraceEventType.Error, 2, "Failed to save the thresholded image to '{0}'.\nError: {1}", filePath, error.Message); } } } } }
/// <summary> /// Creates a <see cref="ResultIterator"/> object that is used to iterate over the page as defined by the current <see cref="Page.RegionOfInterest"/>. /// </summary> /// <returns></returns> public ResultIterator GetIterator() { Recognize(); var resultIteratorHandle = TessApiSignatures.BaseApiGetIterator(Engine.Handle); return(new ResultIterator(this, resultIteratorHandle)); }
/// <summary> /// Get segmented regions at specified page iterator level. /// </summary> /// <param name="pageIteratorLevel">PageIteratorLevel enum</param> /// <returns></returns> public List <Rectangle> GetSegmentedRegions(PageIteratorLevel pageIteratorLevel) { var boxArray = TessApiSignatures.BaseAPIGetComponentImages(Engine.Handle, pageIteratorLevel, Constants.TRUE, IntPtr.Zero, IntPtr.Zero); var boxCount = LeptonicaApiSignatures.boxaGetCount(new HandleRef(this, boxArray)); var boxList = new List <Rectangle>(); for (var i = 0; i < boxCount; i++) { var box = LeptonicaApiSignatures.boxaGetBox(new HandleRef(this, boxArray), i, PixArrayAccessType.Clone); if (box == IntPtr.Zero) { continue; } int px, py, pw, ph; LeptonicaApiSignatures.boxGetGeometry(new HandleRef(this, box), out px, out py, out pw, out ph); boxList.Add(new Rectangle(px, py, pw, ph)); LeptonicaApiSignatures.boxDestroy(ref box); } LeptonicaApiSignatures.boxaDestroy(ref boxArray); return(boxList); }
protected override void Dispose(bool disposing) { if (handle.Handle != IntPtr.Zero) { TessApiSignatures.PageIteratorDelete(handle); } }
protected override void Dispose(bool disposing) { if (disposing) { TessApiSignatures.BaseAPIClear(Engine.Handle); } }
/// <summary> /// Moves the iterator to the start of the page. /// </summary> public void Begin() { VerifyNotDisposed(); if (handle.Handle != IntPtr.Zero) { TessApiSignatures.PageIteratorBegin(handle); } }
/// <summary> /// Creates a <see cref="PageIterator"/> object that is used to iterate over the page's layout as defined by the current <see cref="Page.RegionOfInterest"/>. /// </summary> /// <returns></returns> public PageIterator AnalyseLayout() { Guard.Verify(PageSegmentMode != PageSegMode.OsdOnly, "Cannot analyse image layout when using OSD only page segmentation, please use DetectBestOrientation instead."); var resultIteratorHandle = TessApiSignatures.BaseAPIAnalyseLayout(Engine.Handle); return(new PageIterator(this, resultIteratorHandle)); }
/// <summary> /// Gets the page's content as an HOCR text. /// </summary> /// <param name="pageNum">The page number (zero based).</param> /// <param name="useXHtml">True to use XHTML Output, False to HTML Output</param> /// <returns>The OCR'd output as an HOCR text string.</returns> public string GetHOCRText(int pageNum, bool useXHtml = false) { //Why Not Use 'nameof(pageNum)' instead of '"pageNum"' Guard.Require(nameof(pageNum), pageNum >= 0, "Page number must be greater than or equal to zero (0)."); Recognize(); var text = TessApiSignatures.BaseApiGetHOCRText(Engine.Handle, pageNum); return(useXHtml ? xhtmlBeginTag + text + xhtmlEndTag : htmlBeginTag + text + htmlEndTag); }
/// <summary> /// Moves to the start of the next element at the given level. /// </summary> /// <remarks> /// /// </remarks> /// <param name="level"></param> /// <returns></returns> public bool Next(PageIteratorLevel level) { VerifyNotDisposed(); if (handle.Handle == IntPtr.Zero) { return(false); } return(TessApiSignatures.PageIteratorNext(handle, level)); }
public Pix GetBinaryImage(PageIteratorLevel level) { VerifyNotDisposed(); if (handle.Handle == IntPtr.Zero) { return(null); } return(Pix.Create(TessApiSignatures.PageIteratorGetBinaryImage(handle, level))); }
/// <summary> /// Returns <c>True</c> if the iterator is positioned at the last element at the given level. /// </summary> /// <param name="level"></param> /// <param name="element"></param> /// <returns></returns> public bool IsAtFinalOf(PageIteratorLevel level, PageIteratorLevel element) { VerifyNotDisposed(); if (handle.Handle == IntPtr.Zero) { return(false); } return(TessApiSignatures.PageIteratorIsAtFinalElement(handle, level, element)); }
/// <summary> /// Gets the thresholded image that was OCR'd. /// </summary> /// <returns></returns> public Pix GetThresholdedImage() { Recognize(); var pixHandle = TessApiSignatures.BaseAPIGetThresholdedImage(Engine.Handle); if (pixHandle == IntPtr.Zero) { throw new TesseractException("Failed to get thresholded image."); } return(Pix.Create(pixHandle)); }
public Pix GetImage(PageIteratorLevel level, int padding, out int x, out int y) { VerifyNotDisposed(); if (handle.Handle == IntPtr.Zero) { x = 0; y = 0; return(null); } return(Pix.Create(TessApiSignatures.PageIteratorGetImage(handle, level, padding, page.Image.Handle, out x, out y))); }
/// <summary> /// Gets the baseline of the current element at the given level. /// </summary> /// <remarks> /// The baseline is the line that passes through (x1, y1) and (x2, y2). /// WARNING: with vertical text, baselines may be vertical! Returns false if there is no baseline at the current position.</remarks> /// <param name="level"></param> /// <param name="bounds"></param> /// <returns></returns> public bool TryGetBaseline(PageIteratorLevel level, out Rect bounds) { VerifyNotDisposed(); int x1, y1, x2, y2; if (handle.Handle != IntPtr.Zero && TessApiSignatures.PageIteratorBaseline(handle, level, out x1, out y1, out x2, out y2)) { bounds = Rect.FromCoords(x1, y1, x2, y2); return(true); } else { bounds = Rect.Empty; return(false); } }
/// <summary> /// Gets the element orientation information that the iterator currently points too. /// </summary> public ElementProperties GetProperties() { VerifyNotDisposed(); if (handle.Handle == IntPtr.Zero) { return(new ElementProperties(Orientation.PageUp, TextLineOrder.TopToBottom, WritingDirection.LeftToRight, 0f)); } Orientation orientation; WritingDirection writing_direction; TextLineOrder textLineOrder; float deskew_angle; TessApiSignatures.PageIteratorOrientation(handle, out orientation, out writing_direction, out textLineOrder, out deskew_angle); return(new ElementProperties(orientation, textLineOrder, writing_direction, deskew_angle)); }
/// <summary> /// Gets the page's content as a WordStrBox text. /// </summary> /// <param name="pageNum">The page number (zero based).</param> /// <returns>The OCR'd output as a WordStrBox text string.</returns> public string GetWordStrBoxText(int pageNum) { Guard.Require(nameof(pageNum), pageNum >= 0, "Page number must be greater than or equal to zero (0)."); Recognize(); return(TessApiSignatures.BaseApiGetWordStrBoxText(Engine.Handle, pageNum)); }
/// <summary> /// Gets the page's content as an UNLV text. /// </summary> /// <returns>The OCR'd output as an UNLV text string.</returns> public string GetUNLVText() { Recognize(); return(TessApiSignatures.BaseApiGetUNLVText(Engine.Handle)); }
/// <summary> /// Get's the mean confidence that as a percentage of the recognized text. /// </summary> /// <returns></returns> public float GetMeanConfidence() { Recognize(); return(TessApiSignatures.BaseAPIMeanTextConf(Engine.Handle) / 100.0f); }