<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged ocr</title>
<link>https://coderlegion.com/tag/ocr</link>
<description>Powered by Question2Answer</description>
<item>
<title>Building a Smart OCR Converter with Python: Turning Images into Editable Text</title>
<link>https://coderlegion.com/30625/building-a-smart-ocr-converter-with-python-turning-images-into-editable-text</link>
<description>&lt;p&gt;In today’s digital world, information is everywhere but not all information is available in a usable format. Many businesses still manage scanned documents, printed forms, invoices, receipts, and images containing important text. Manually typing this information into a computer takes time, increases the risk of errors, and reduces productivity.&lt;/p&gt;
&lt;p&gt;This is where an &lt;strong&gt;OCR (Optical Character Recognition) converter built with Python&lt;/strong&gt; can make a real difference.&lt;/p&gt;
&lt;h3 id=&quot;the-problem-text-locked-inside-images&quot;&gt;The Problem: Text Locked Inside Images&lt;/h3&gt;
&lt;p&gt;Imagine a business receiving hundreds of scanned documents every week. Employees need to read each document, extract the information, and manually enter it into a digital system.&lt;/p&gt;
&lt;p&gt;This process creates several challenges:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Time-consuming work:&lt;/strong&gt; Manually copying text from documents wastes valuable hours.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Human errors:&lt;/strong&gt; Incorrect spelling, missing information, and typing mistakes can affect data accuracy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Difficult document management:&lt;/strong&gt; Searching for specific information inside image-based documents is not easy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limited productivity:&lt;/strong&gt; Employees spend more time processing documents and less time on important tasks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalability issues:&lt;/strong&gt; As the number of documents grows, manual processing becomes increasingly difficult.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Businesses need a smarter way to convert image-based text into digital information.&lt;/p&gt;
&lt;h3 id=&quot;the-solution-developing-an-ocr-converter-using-python&quot;&gt;The Solution: Developing an OCR Converter Using Python&lt;/h3&gt;
&lt;p&gt;To address these challenges, we can build an OCR converter using Python. The application reads text from images and scanned documents, then converts it into machine-readable text that users can copy, search, edit, or save.&lt;/p&gt;
&lt;p&gt;Python is an excellent choice for this project because it provides powerful libraries for image processing, text recognition, and web application development.&lt;/p&gt;
&lt;h4 id=&quot;how-does-the-ocr-converter-work-&quot;&gt;How Does the OCR Converter Work?&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Image Upload:&lt;/strong&gt; Users upload an image containing text, such as a JPG, PNG, or a supported scanned document.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Image Processing:&lt;/strong&gt; The application prepares the image for recognition. Techniques such as grayscale conversion, noise reduction, and thresholding can improve text readability.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Text Recognition:&lt;/strong&gt; An OCR engine analyzes the processed image and identifies the characters and words.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Text Extraction:&lt;/strong&gt; The recognized text appears on the screen, allowing users to review and copy the results.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Download and Export:&lt;/strong&gt; The extracted content can be saved as a text file or integrated into other document-processing workflows.&lt;/p&gt;
&lt;p&gt;The goal is to make document conversion simple, accessible, and efficient.&lt;/p&gt;
&lt;h3 id=&quot;technologies-behind-the-project&quot;&gt;Technologies Behind the Project&lt;/h3&gt;
&lt;p&gt;A Python-based OCR converter can use several technologies working together:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python:&lt;/strong&gt; Handles the main application logic and processing workflow.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tesseract OCR:&lt;/strong&gt; Recognizes text in images and converts it into digital text.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pytesseract:&lt;/strong&gt; Connects Python code with the Tesseract OCR engine.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pillow or OpenCV:&lt;/strong&gt; Helps process images before recognition.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flask:&lt;/strong&gt; Can provide a lightweight web interface where users upload images and view extracted text.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These tools make it possible to build a practical OCR application without developing a text-recognition engine from scratch.&lt;/p&gt;
&lt;h3 id=&quot;why-image-preprocessing-matters&quot;&gt;Why Image Preprocessing Matters&lt;/h3&gt;
&lt;p&gt;One of the most important lessons in OCR development is that the quality of the input image affects the quality of the extracted text.&lt;/p&gt;
&lt;p&gt;A clear, high-resolution image usually produces better results than a blurry or poorly lit photograph.&lt;/p&gt;
&lt;p&gt;For improved recognition, developers can implement:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Grayscale conversion to simplify image information.&lt;/li&gt;
&lt;li&gt;Thresholding to improve contrast between text and background.&lt;/li&gt;
&lt;li&gt;Noise removal to reduce unwanted marks.&lt;/li&gt;
&lt;li&gt;Image resizing to improve the visibility of small characters.&lt;/li&gt;
&lt;li&gt;Deskewing to straighten tilted documents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, preprocessing methods should be selected according to the document type. Excessive processing can sometimes remove important details or reduce recognition accuracy.&lt;/p&gt;
&lt;h3 id=&quot;real-world-applications&quot;&gt;Real-World Applications&lt;/h3&gt;
&lt;p&gt;A Python OCR converter can support many practical use cases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Business Administration:&lt;/strong&gt; Extract text from invoices, forms, and printed records.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Education:&lt;/strong&gt; Convert scanned study materials and printed notes into searchable text.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;E-commerce:&lt;/strong&gt; Help digitize product information and paper based inventory records.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Healthcare Administration:&lt;/strong&gt; Assist with digitizing appropriate non-sensitive administrative documents, subject to privacy and security requirements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Digital Archiving:&lt;/strong&gt; Make historical documents and scanned records easier to search and organize.&lt;/p&gt;
&lt;p&gt;OCR can also become part of a larger workflow that extracts structured information, classifies documents, or transfers recognized text into a database.&lt;/p&gt;
&lt;h3 id=&quot;challenges-developers-should-consider&quot;&gt;Challenges Developers Should Consider&lt;/h3&gt;
&lt;p&gt;Building an OCR converter is not only about extracting text. A reliable application should also handle unexpected situations.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Poor image quality can lead to incorrect recognition.&lt;/li&gt;
&lt;li&gt;Complex layouts, tables, and multiple columns may require additional processing.&lt;/li&gt;
&lt;li&gt;Handwriting is generally more challenging than printed text.&lt;/li&gt;
&lt;li&gt;Multilingual documents may require additional language data.&lt;/li&gt;
&lt;li&gt;Large files can increase processing time and memory usage.&lt;/li&gt;
&lt;li&gt;Uploaded documents should be handled securely, with appropriate file validation, privacy protections, and retention policies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Developers should test the application with different image formats, document layouts, languages, and image qualities before deploying it for real-world use.&lt;/p&gt;
&lt;h3 id=&quot;future-improvements&quot;&gt;Future Improvements&lt;/h3&gt;
&lt;p&gt;An OCR converter can evolve into a more advanced document processing platform.&lt;/p&gt;
&lt;p&gt;Possible improvements include PDF support, batch image conversion, multilingual recognition, searchable document archives, structured data extraction, and integration with databases or business management systems.&lt;/p&gt;
&lt;p&gt;A web-based interface can also make the application accessible to users without requiring them to run Python scripts manually.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Building an OCR converter with Python is a practical way to apply programming skills to a real-world problem. By combining Python, image preprocessing, and OCR technology, developers can reduce manual data entry and make document information easier to access.&lt;/p&gt;
&lt;p&gt;The most important lesson is that &lt;strong&gt;useful software is not simply about writing code it is about solving problems efficiently and creating a better experience for users.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At Next Big Creative, we believe technology should help businesses work smarter, improve digital processes, and turn ideas into practical solutions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You thinking and we building.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Next Big Creative&lt;br&gt;
www.nextbigcreative.com&lt;/strong&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/30625/building-a-smart-ocr-converter-with-python-turning-images-into-editable-text</guid>
<pubDate>Sat, 10 Oct 2026 16:26:56 +0000</pubDate>
</item>
<item>
<title>Give Your Document OCR Pipeline a Memory</title>
<link>https://coderlegion.com/30618/give-your-document-ocr-pipeline-a-memory</link>
<description>&lt;p&gt;After OCR, most pipelines throw the layout away and re-discover the same form from scratch every time. &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/aws-samples/sample-textract-field-memory&quot;&gt;&lt;code&gt;textract-field-memory&lt;/code&gt;&lt;/a&gt; is a small, zero-dependency Python layer that remembers where fields sit, checks they landed in the right place, tells you which layout a document is, and warns you when a form quietly changes. It doesn't do OCR. It makes the OCR you already run a lot more useful.&lt;/p&gt;
&lt;h3 id=&quot;where-this-started&quot;&gt;Where this started&lt;/h3&gt;
&lt;p&gt;I kept running into the same annoying gap on document pipelines. You send a form through Textract (or Tesseract, or whatever), you get back field names and bounding boxes, you pull the values, and then you throw all the positional information away. The next copy of that exact same form shows up an hour later and the pipeline treats it like it's never seen anything like it before.&lt;/p&gt;
&lt;p&gt;That bugged me for a few reasons.&lt;/p&gt;
&lt;p&gt;Nothing checks that a field came from the right spot on the page. If &quot;Total&quot; gets read out of the shipping box instead of the amount box, the value still looks like a number, so it sails downstream and nobody blinks.&lt;/p&gt;
&lt;p&gt;Nothing notices when a form changes. A vendor nudges their invoice template, fields move a centimeter, and you find out three weeks later when a downstream job starts choking on garbage.&lt;/p&gt;
&lt;p&gt;And there's no cheap way to ask &quot;have I seen this layout before?&quot; So every document, familiar or not, takes the same expensive road.&lt;/p&gt;
&lt;p&gt;So I wrote a little library that sits &lt;em&gt;after&lt;/em&gt; OCR and keeps the memory the pipeline was throwing out.&lt;/p&gt;
&lt;h3 id=&quot;what-it-is-and-what-it-definitely-isn-t&quot;&gt;What it is, and what it definitely isn't&lt;/h3&gt;
&lt;p&gt;It's a spatial memory layer. You hand it field names plus normalized bounding boxes (x, y, width, height between 0 and 1). It learns roughly where each field tends to appear on a given template, and from then on it can validate positions, identify which template a document belongs to, and watch for drift.&lt;/p&gt;
&lt;p&gt;It is not an OCR engine and it never touches pixels. Something upstream has to extract the fields first. This library just remembers where they ended up and reasons about that.&lt;/p&gt;
&lt;p&gt;Under the hood there's nothing exotic going on, which I think is a feature. Spatial scoring is intersection-over-union plus the distance between box centers. Name matching is a normalized Levenshtein distance. Template identification is Jaccard overlap of the field-name sets combined with the spatial score. No model, no training step, no network calls. It's pure standard-library Python with zero dependencies, and templates are just JSON files on disk.&lt;/p&gt;
&lt;h3 id=&quot;a-quick-look-at-the-api&quot;&gt;A quick look at the API&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from field_memory import TemplateMemory
memory = TemplateMemory(store_path=&quot;./my_templates&quot;)
# 1. Learn — feed documents after OCR extraction
memory.record(document, template_id=&quot;employment-form&quot;)
# 2. Locate — spatial field lookup with a confidence score
matches = memory.locate(new_doc, &quot;Employee Name&quot;)
# → FieldMatch(combined_score=0.95, spatial_score=0.93, within_expected_region=True)
# 3. Identify — which known layout is this?
match = memory.identify_template(new_doc)
# → TemplateMatch(template_id=&quot;employment-form&quot;, similarity_score=0.87)
# 4. Detect drift — has the layout shifted?
drift = memory.detect_drift(new_doc, &quot;employment-form&quot;)
# → DriftReport(is_drifting=False, overall_drift_score=0.02)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clustering comes for free. If you call &lt;code&gt;record()&lt;/code&gt; and leave out the &lt;code&gt;template_id&lt;/code&gt;, it either merges the document into a template it recognizes or spins up a new one. Run that for a while and you end up with a map of every distinct layout flowing through your pipeline without ever configuring one by hand.&lt;/p&gt;
&lt;h3 id=&quot;why-there-s-no-llm-inside&quot;&gt;Why there's no LLM inside&lt;/h3&gt;
&lt;p&gt;For a layout you've already seen, answering &quot;where's this field?&quot; is basically a dictionary lookup. Sub-millisecond, and free. The same question routed through an LLM is half a second to two seconds and costs you per field. Paying that toll on forms you've processed a thousand times is silly.&lt;/p&gt;
&lt;p&gt;So the design leans into being complementary instead of competitive:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def smart_extract(document, field_name):
    matches = memory.locate(document, field_name)
    if matches and matches[0].within_expected_region and matches[0].combined_score &amp;gt;= 0.85:
        return matches[0].key_value, &quot;spatial&quot;   # free, instant
    return call_llm(document, field_name), &quot;llm&quot;  # pay only when needed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Think of it as the cheap first pass that decides whether you even need the expensive one. The 0.85 threshold is just a starting point. Crank it up if a wrong answer is costly and you'd rather fall back to the LLM more often.&lt;/p&gt;
&lt;h3 id=&quot;where-it-actually-helps&quot;&gt;Where it actually helps&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Domain &lt;/th&gt;&lt;th&gt;What it remembers &lt;/th&gt;&lt;th&gt;What it catches&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Invoice processing &lt;/td&gt;&lt;td&gt;Where fields sit per vendor layout &lt;/td&gt;&lt;td&gt;Vendor template changes, wrong-position reads&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Insurance claims &lt;/td&gt;&lt;td&gt;Field positions across many form types &lt;/td&gt;&lt;td&gt;Unknown forms that need routing for review&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Healthcare intake &lt;/td&gt;&lt;td&gt;Where fields land on clinic forms &lt;/td&gt;&lt;td&gt;Layout revisions before they break downstream&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Manufacturing QA &lt;/td&gt;&lt;td&gt;Component positions on boards &lt;/td&gt;&lt;td&gt;Parts that shifted from baseline&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The only real requirement is that your data has named things with bounding boxes. That's it.&lt;/p&gt;
&lt;h3 id=&quot;some-numbers-and-the-caveats-that-go-with-them&quot;&gt;Some numbers, and the caveats that go with them&lt;/h3&gt;
&lt;p&gt;I put it through a stress test using real Textract (FORMS) on generated PDFs plus scanned, deliberately degraded versions of the same documents.&lt;/p&gt;
&lt;p&gt;Layout identification came out at 100% across five vendors whose invoices look nothing alike, trained on just three documents each. On dense tax returns with 33 fields crammed into a tight three-column grid, roughly 0.03 units apart, it located every field. Drift detection behaved the way I hoped: as I pushed forms further off their baseline, the drift scores climbed smoothly from 0.012 up to 0.047 and tripped the flag once they crossed the threshold. On injected anomalies (shifted, scattered, reversed, wrong-form) it caught four of five. And because it's all local computation, lookups stay under a millisecond.&lt;/p&gt;
&lt;p&gt;Now the honest part.&lt;/p&gt;
&lt;p&gt;The benchmark runs on synthetic PDFs generated with ReportLab and their scanned variants, not a big real-world labeled corpus. Sample sizes are small, around 20 forms per scenario.&lt;/p&gt;
&lt;p&gt;There's no proper precision/recall/F1 yet because I don't have a ground-truth label set built. The numbers above are operational rather than a formal comparison against baselines, and I'd treat them that way.&lt;/p&gt;
&lt;p&gt;The one anomaly it missed was the &quot;same layout, just fewer fields&quot; case. The fields that remain are still sitting in the right places, so spatially nothing looks wrong. You could argue that's correct behavior, but it's worth knowing going in.&lt;/p&gt;
&lt;p&gt;Handwritten forms are a dead end, because Textract FORMS gives back nothing to learn from. That's an upstream limitation, not something this library can paper over.&lt;/p&gt;
&lt;p&gt;I'd rather you hit these on the page than in production.&lt;/p&gt;
&lt;h3 id=&quot;try-it&quot;&gt;Try it&lt;/h3&gt;
&lt;p&gt;Clone it and install from source. This works right now, nothing to sign up for:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/aws-samples/sample-textract-field-memory
cd sample-textract-field-memory
pip install -e .
python examples/demo.py   # runs on synthetic data, no AWS needed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;demo.py&lt;/code&gt; walks through template learning, spatial matching, anomaly detection, and drift analysis on synthetic data, so you can watch the whole thing work without credentials or config.&lt;/p&gt;
&lt;p&gt;Repo: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/aws-samples/sample-textract-field-memory&quot;&gt;github.com/aws-samples/sample-textract-field-memory&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It lives under &lt;code&gt;aws-samples&lt;/code&gt; but there's no AWS dependency in it. Pure standard-library Python, works completely offline with any OCR source that gives you field names and boxes. MIT-0 licensed.&lt;/p&gt;
&lt;p&gt;If you run document pipelines, the thing I'd most like feedback on is turning these stress tests into a real labeled benchmark. And if the &quot;remember it, stop re-discovering it&quot; idea resonates, you've got the whole pitch.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/30618/give-your-document-ocr-pipeline-a-memory</guid>
<pubDate>Sat, 10 Oct 2026 16:20:15 +0000</pubDate>
</item>
<item>
<title>Bento Scan AI Document Scanner</title>
<link>https://coderlegion.com/29328/bento-scan-ai-document-scanner</link>
<description>&lt;h3 id=&quot;a-white-label-scanner-that-works-offline-first&quot;&gt;A white-label scanner that works offline first&lt;/h3&gt;
&lt;p&gt;Bento Scan is a production-ready document scanner for Android and iOS built with Flutter. The mobile app handles the capture workflow on-device: it detects page boundaries, triggers automatic capture, corrects perspective, flattens curved pages, applies filters and exports multi-page PDFs.&lt;/p&gt;
&lt;p&gt;Many scanner apps depend on proprietary cloud services for basic processing. Bento Scan keeps the essential scan pipeline offline, then pairs it with an optional self-hosted backend for teams that want synchronization, search and administration under their own control.&lt;/p&gt;
&lt;h3 id=&quot;included-capabilities&quot;&gt;Included capabilities&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Offline document-edge detection and automatic capture&lt;/li&gt;
&lt;li&gt;Perspective correction and AI page flattening&lt;/li&gt;
&lt;li&gt;Multi-page scanning, filters and PDF export&lt;/li&gt;
&lt;li&gt;OCR in more than 100 languages&lt;/li&gt;
&lt;li&gt;Searchable PDFs, folders, tags and full-text search&lt;/li&gt;
&lt;li&gt;Quotas, administration statistics and S3-compatible storage&lt;/li&gt;
&lt;li&gt;Responsive web dashboard&lt;/li&gt;
&lt;li&gt;Editable Flutter, FastAPI and deployment source code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The package can be rebranded for a commercial scanner, an internal capture tool or a document workflow product. Developers receive the mobile app, backend, web dashboard, deployment configuration and training utilities rather than a closed SDK.&lt;/p&gt;
&lt;p&gt;See device requirements, screenshots and the complete package on &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.codester.com/items/71446/bento-scan-ai-document-scanner-flutter-app&quot;&gt;Codester&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Launches</category>
<guid isPermaLink="true">https://coderlegion.com/29328/bento-scan-ai-document-scanner</guid>
<pubDate>Thu, 01 Oct 2026 01:33:38 +0000</pubDate>
</item>
<item>
<title>DocBento AI Document Management</title>
<link>https://coderlegion.com/29326/docbento-ai-document-management</link>
<description>&lt;h3 id=&quot;private-document-ai-with-page-level-citations&quot;&gt;Private document AI with page-level citations&lt;/h3&gt;
&lt;p&gt;DocBento started from a practical problem: teams often have thousands of PDFs, scans, Office files and email attachments, but finding a trustworthy answer still means opening documents one by one. Generic chat tools can summarize text, yet they frequently lose the connection between an answer and the exact source page.&lt;/p&gt;
&lt;p&gt;DocBento is a self-hosted document management platform that combines OCR, full-text retrieval and semantic search. Its AI assistant answers questions against the organization’s own library and cites the pages it used, so reviewers can verify the result instead of trusting an unsupported summary.&lt;/p&gt;
&lt;h3 id=&quot;core-capabilities&quot;&gt;Core capabilities&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PaddleOCR, Tesseract and optional cloud OCR engines&lt;/li&gt;
&lt;li&gt;Hybrid full-text and semantic document search&lt;/li&gt;
&lt;li&gt;AI answers with page-level citations&lt;/li&gt;
&lt;li&gt;Folders, tags, approvals and document expiry reminders&lt;/li&gt;
&lt;li&gt;Granular roles, restricted folders and audit logs&lt;/li&gt;
&lt;li&gt;Support for PDF, images, Office files, email and other formats&lt;/li&gt;
&lt;li&gt;FastAPI, React and Docker deployment for self-hosting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The platform is designed for teams that need control over data location, model providers and access policies. It can serve internal knowledge bases, compliance archives, client-document portals or review workflows. Administrators can choose offline components where privacy matters and connect external AI services only when their policies allow it.&lt;/p&gt;
&lt;p&gt;The package includes editable source code and deployment documentation. See the complete feature list and screenshots on &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.codester.com/items/71502/docbento-python-ai-document-management&quot;&gt;Codester&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Launches</category>
<guid isPermaLink="true">https://coderlegion.com/29326/docbento-ai-document-management</guid>
<pubDate>Thu, 01 Oct 2026 01:33:30 +0000</pubDate>
</item>
<item>
<title>Designing a Clear Upload-to-Export Flow for Four Document Jobs</title>
<link>https://coderlegion.com/28621/designing-a-clear-upload-to-export-flow-for-four-document-jobs</link>
<description>&lt;p&gt;An upload control can look simple while hiding a product decision: what does the person want to accomplish with the file? A scanned page, a photo of a document, searchable text, and a spreadsheet-ready receipt are related, but they are not the same job. A useful interface makes those paths legible before the user starts.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://scanpdf.ai/&quot;&gt;ScanPDF AI&lt;/a&gt; presents four entry points—Scan PDF, Photo to PDF, OCR PDF, and Receipt to Excel. The interface gives us a concrete example of organizing around outcomes rather than asking everyone to start with one generic “upload” action.&lt;/p&gt;
&lt;h3 id=&quot;a-task-selector-is-part-of-the-product-model&quot;&gt;A task selector is part of the product model&lt;/h3&gt;
&lt;p&gt;Designing workflow labels means deciding which distinctions matter to users. For document work, the source file may be a PDF, a phone image, or a photo of a receipt. Yet the source alone does not tell us the desired result. Someone may want a portable document, extracted text, or structured transaction details.&lt;/p&gt;
&lt;p&gt;Putting those options near the start lets people choose by intent. It also helps a team keep each workflow’s promise narrow. A photo-to-PDF path can focus on document conversion. An OCR path can explain recognized-text exports. A receipt path can set expectations about fields and spreadsheet output.&lt;/p&gt;
&lt;h3 id=&quot;show-an-output-contract-before-upload&quot;&gt;Show an output contract before upload&lt;/h3&gt;
&lt;p&gt;The OCR page lists PDF, JPG, PNG, and WebP inputs and describes PDF, TXT, and DOCX exports. The receipt page describes PDF, TXT, and CSV output, and names merchant, date, total, tax, currency, and line items. This is a useful pattern: tell users what kind of artifact a workflow is intended to produce before they invest time in it.&lt;/p&gt;
&lt;p&gt;For product designers, the next improvement to look for is whether that contract remains visible after selection. Are supported formats near the file picker? Is the output type clear before a potentially lengthy upload? Does the result screen distinguish editable text from a formatted document? These are practical review questions, not assumptions about any one implementation.&lt;/p&gt;
&lt;h3 id=&quot;keep-recognized-separate-from-verified-&quot;&gt;Keep “recognized” separate from “verified”&lt;/h3&gt;
&lt;p&gt;OCR and extraction outputs can look authoritative because they are neatly formatted. That presentation should not imply perfect recognition. A receipt total might be confused with a subtotal; a date can be ambiguous; a low-quality image can omit a line. Products should make it easy to inspect extracted values and correct them before export.&lt;/p&gt;
&lt;p&gt;An example on a marketing page can explain the shape of the result, but it is not evidence of performance on arbitrary files. Teams evaluating a tool should test varied samples, including skewed photos, faded print, multiple currencies, and receipts with several tax or line-item formats. Review actual outputs before incorporating them into an operational workflow.&lt;/p&gt;
&lt;h3 id=&quot;design-for-the-whole-handoff&quot;&gt;Design for the whole handoff&lt;/h3&gt;
&lt;p&gt;The interaction does not end when a file is accepted. People need to know how the document will be processed, where the result appears, which export fits their next tool, and what they should verify. Good labels and clear output options can remove uncertainty without adding more controls.&lt;/p&gt;
&lt;p&gt;That is the broader lesson from these four paths: map the interface to the user’s next decision. When scanning, conversion, OCR, and structured extraction are presented as distinct jobs, the product can explain each one honestly—and users can pick the outcome they actually need.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/28621/designing-a-clear-upload-to-export-flow-for-four-document-jobs</guid>
<pubDate>Fri, 25 Sep 2026 14:56:23 +0000</pubDate>
</item>
<item>
<title>wsnap — macOS-style screen capture for Windows</title>
<link>https://coderlegion.com/19583/wsnap-macos-style-screen-capture-for-windows</link>
<description>&lt;p&gt;Ever taken a screenshot only to fish the file out of a folder afterward — or thought you copied the image but got a file path instead? wsnap is a native Windows capture tool built around the two things people actually do with a screenshot: paste it and drag it.&lt;/p&gt;
&lt;p&gt;Press Shift+F1 and drag a region. The instant you release the mouse, the image is on your clipboard — paste it anywhere with Ctrl+V. The floating thumbnail at the bottom-right is a real, draggable file: drop it into Slack, a chat, an editor, or an email. It stays put, so you can drop it again somewhere else.&lt;/p&gt;
&lt;p&gt;Beyond that core:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Precise overlay — freezes the screen, brightens only your selection, shows live W×H, and a magnifier loupe with pixel coordinates and the HEX color under the cursor.&lt;/li&gt;
&lt;li&gt;Annotation editor — arrow, shapes, pen, highlighter, text, numbered steps, mosaic/blur redaction, crop, with undo/redo.&lt;/li&gt;
&lt;li&gt;On-device OCR (Korean + English) — PaddleOCR PP-OCRv5, fully offline, no language pack needed.&lt;/li&gt;
&lt;li&gt;Many capture modes — region, full screen, click-to-capture a window, delayed, scrolling capture, GIF recording.&lt;/li&gt;
&lt;li&gt;Capture history gallery, color picker (eyedropper), and filename templates.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No account, no tracking, fully offline. It runs quietly from the tray with a minimal idle footprint. GPL-3.0 open source.&lt;/p&gt;
&lt;p&gt;Available for Windows 10/11 (x64) via Scoop, winget, or direct download.&lt;/p&gt;
&lt;p&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/openwong2kim/wsnap&quot;&gt;https://github.com/openwong2kim/wsnap&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/19583/wsnap-macos-style-screen-capture-for-windows</guid>
<pubDate>Wed, 03 Jun 2026 12:42:49 +0000</pubDate>
</item>
<item>
<title>How Well Can OCR Read Doctor Handwriting in 2026?</title>
<link>https://coderlegion.com/14211/how-well-can-ocr-read-doctor-handwriting-in-2026</link>
<description>&lt;p&gt;&lt;em&gt;Benchmarking four open-source OCR engines on 5,578 handwritten medical prescriptions&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PP-OCRv5 (5M parameters) and GLM-OCR (0.9B parameters) both achieve 20%+ exact match on handwritten prescriptions, a 10x jump over Tesseract and EasyOCR&lt;/li&gt;
&lt;li&gt;GLM-OCR leads on character accuracy (CER 0.328), while PP-OCRv5 leads on word accuracy (WER 0.789)&lt;/li&gt;
&lt;li&gt;A 5M-parameter model trained on curated data rivals a 900M-parameter vision-language model&lt;/li&gt;
&lt;li&gt;Neither engine is clinically deployable yet: even the best gets only 1 in 3 words exactly right&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;Last month I spent some time squinting at prescription scans, trying to figure out if a doctor wrote &lt;em&gt;Amoxicillin&lt;/em&gt; or &lt;em&gt;Amitriptyline&lt;/em&gt;. I got it wrong twice. That got me wondering: how would today's OCR engines handle this?&lt;/p&gt;
&lt;p&gt;The stakes are real. Medication errors injure approximately 1.3 million people annually in the United States alone and cost an estimated $42 billion globally (&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.who.int/news/item/29-03-2017-who-launches-global-effort-to-halve-medication-related-errors-in-5-years&quot;&gt;WHO&lt;/a&gt;, 2017). Illegible handwriting is a well-documented contributor: 35.7% of handwritten prescriptions contain errors, compared to just 2.5% of electronic ones (&lt;a rel=&quot;nofollow&quot; href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC4281619/&quot;&gt;Albarrak et al.&lt;/a&gt;, 2014).&lt;/p&gt;
&lt;p&gt;A study of 4,183 prescriptions found that 10.21% of them are illegible, and 19.39% are barely legible (&lt;a rel=&quot;nofollow&quot; href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC10686667/&quot;&gt;Albalushi et al.&lt;/a&gt;, 2023). The global OCR market is projected to reach $32.9 billion by 2030, growing at a 14.8% CAGR (&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.grandviewresearch.com/industry-analysis/optical-character-recognition-market&quot;&gt;Grand View Research&lt;/a&gt;, 2025). Healthcare is one of the fastest-growing verticals driving that growth. But I couldn't find a public benchmark comparing today's open-source OCR engines on handwritten medical text.&lt;/p&gt;
&lt;p&gt;So I ran one myself. I tested four engines on &lt;strong&gt;5,578 handwritten prescription word images&lt;/strong&gt;, and the results surprised me.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;who-are-the-four-contenders-&quot;&gt;Who Are the Four Contenders?&lt;/h3&gt;
&lt;p&gt;These four engines span three generations of OCR thinking, from traditional pattern matching to specialized deep learning to generative vision-language models.&lt;/p&gt;
&lt;h4 id=&quot;tesseract-the-veteran&quot;&gt;Tesseract: The Veteran&lt;/h4&gt;
&lt;p&gt;Google-backed and over 18 years old, Tesseract is the default OCR engine for a generation of developers. It uses an LSTM-based architecture designed primarily for printed text. Stable, well-documented, and runs everywhere, but handwritten cursive is not its strength.&lt;/p&gt;
&lt;h4 id=&quot;easyocr-the-accessible-one&quot;&gt;EasyOCR: The Accessible One&lt;/h4&gt;
&lt;p&gt;Built on a CRNN (Convolutional Recurrent Neural Network) architecture with roughly &lt;strong&gt;10 million parameters&lt;/strong&gt;, EasyOCR's selling point is simplicity: &lt;code&gt;pip install easyocr&lt;/code&gt; and you're recognizing text in 80+ languages. It uses deep learning but remains a traditional detection-recognition pipeline.&lt;/p&gt;
&lt;h4 id=&quot;pp-ocrv5-the-data-centric-specialist&quot;&gt;PP-OCRv5: The Data-Centric Specialist&lt;/h4&gt;
&lt;p&gt;Baidu's latest, with just &lt;strong&gt;5 million parameters&lt;/strong&gt;. PP-OCRv5 uses an SVTR_LCNet architecture with a Guided Training of CTC (GTC) strategy. The real innovation isn't the architecture, though. It's the training data.&lt;/p&gt;
&lt;p&gt;The PP-OCRv5 paper (&lt;a rel=&quot;nofollow&quot; href=&quot;https://arxiv.org/abs/2603.24373&quot;&gt;Cui et al.&lt;/a&gt;, 2026) shows that &lt;em&gt;data quality trumps model scale&lt;/em&gt;. They curated &lt;strong&gt;22.6 million training samples&lt;/strong&gt; by filtering along three dimensions. First, &lt;strong&gt;difficulty&lt;/strong&gt;: they use model confidence as a proxy and found that samples in the [0.95, 0.97] range hit a sweet spot, hard enough to teach the model something new, but not so hard that the labels are unreliable. Second, &lt;strong&gt;accuracy&lt;/strong&gt;: they cross-check predictions against labels to weed out mislabeled samples. Third, &lt;strong&gt;diversity&lt;/strong&gt;: they cluster training images into 1,000 visual groups using CLIP embeddings and ensure each cluster is represented. Together, these filters yielded 2-3x improvements in handwritten recognition from v3 to v5 without changing the model architecture.&lt;/p&gt;
&lt;h4 id=&quot;glm-ocr-the-compact-vision-language-model&quot;&gt;GLM-OCR: The Compact Vision-Language Model&lt;/h4&gt;
&lt;p&gt;From Zhipu AI and Tsinghua University, GLM-OCR takes a fundamentally different approach. It's a &lt;strong&gt;0.9-billion-parameter&lt;/strong&gt; multimodal model combining a 0.4B CogViT vision encoder with a 0.5B GLM language decoder (&lt;a rel=&quot;nofollow&quot; href=&quot;https://arxiv.org/abs/2603.10910&quot;&gt;Duan et al.&lt;/a&gt;, 2026). Rather than traditional CTC or attention-based sequence recognition, it &lt;em&gt;generates&lt;/em&gt; text autoregressively, like a language model that reads images.&lt;/p&gt;
&lt;p&gt;An important note: 0.9B is &lt;strong&gt;compact&lt;/strong&gt; for a vision-language model. For comparison, Qwen3-VL has 235 billion parameters and GPT-4o is even larger. GLM-OCR was designed for efficiency, using Multi-Token Prediction (MTP) to generate approximately 5.2 tokens per decoding step, yielding a roughly 50% throughput improvement over standard autoregressive generation. It's trained through a 4-stage pipeline that includes supervised fine-tuning and GRPO reinforcement learning.&lt;/p&gt;
&lt;p&gt;These four engines represent a clear spectrum: &lt;strong&gt;traditional&lt;/strong&gt; (Tesseract), &lt;strong&gt;specialized deep learning&lt;/strong&gt; (EasyOCR, PP-OCRv5), and &lt;strong&gt;generative VLM&lt;/strong&gt; (GLM-OCR). &lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-makes-the-rxhandbd-dataset-so-hard-&quot;&gt;What Makes the RxHandBD Dataset So Hard?&lt;/h3&gt;
&lt;p&gt;We use &lt;strong&gt;RxHandBD&lt;/strong&gt; (&lt;a rel=&quot;nofollow&quot; href=&quot;https://data.mendeley.com/datasets&quot;&gt;Shovon et al.&lt;/a&gt;, Mendeley Data), a dataset of 5,578 cropped word images extracted from handwritten medical prescriptions written by doctors in Bangladesh. Each image contains a single word with a corresponding ground-truth label.&lt;/p&gt;
&lt;p&gt;This dataset is hard for four reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Doctor's handwriting.&lt;/strong&gt; Enough said.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Medical terminology.&lt;/strong&gt; Drug names like &quot;Amoxicillin&quot; and &quot;Metformin&quot; alongside dosage notations like &quot;5% dns&quot; and &quot;1+0+1.&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mixed language.&lt;/strong&gt; English medical terms interspersed with Bangla script.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inconsistent quality.&lt;/strong&gt; Varying paper backgrounds, pen types, and image capture conditions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are a few samples to give you a sense of the difficulty range:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjtlg5pbxm179b0val0h.png&quot; alt=&quot;OCR Samples&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;From top to bottom: a drug name both modern engines nail (&quot;Ronem&quot;), cases where only one engine succeeds (&quot;Vineet&quot; and &quot;Eylox&quot;), and a close call where GLM-OCR gets closest but still misses (&quot;Ambrox&quot;).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;One important methodological note: these are &lt;strong&gt;pre-cropped word-level images&lt;/strong&gt;. We're isolating the &lt;strong&gt;recognition&lt;/strong&gt; half of the OCR pipeline, not testing detection (locating text regions on a full page). This means our results reflect recognition accuracy only. Real-world performance also depends on how well each engine detects text regions before recognizing them.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-did-we-run-the-benchmark-&quot;&gt;How Did We Run the Benchmark?&lt;/h3&gt;
&lt;h4 id=&quot;metrics&quot;&gt;Metrics&lt;/h4&gt;
&lt;p&gt;We evaluate using four complementary metrics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CER (Character Error Rate):&lt;/strong&gt; Edit distance between predicted and reference strings, normalized by reference length. If the label says &quot;Amoxicillin&quot; (11 characters) and the OCR outputs &quot;Amoxicilin&quot; (1 deletion), the CER is 1/11 = 0.09. Lower is better.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WER (Word Error Rate):&lt;/strong&gt; Same concept at the word level. Any mistake in a word counts the entire word as wrong. Lower is better.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exact Match Rate:&lt;/strong&gt; The strictest metric. Did the OCR output match the ground truth character-for-character after normalization? Higher is better.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Latency:&lt;/strong&gt; Wall-clock milliseconds per image, measuring practical throughput.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;setup&quot;&gt;Setup&lt;/h4&gt;
&lt;p&gt;All engines run on an Apple Silicon Mac (CPU only). Single run. Default configurations for each engine with no fine-tuning or domain-specific adjustments. PP-OCRv5 runs its full detection + recognition pipeline even on pre-cropped images. GLM-OCR processes each image with the prompt &quot;Text Recognition:&quot;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-do-the-numbers-say-&quot;&gt;What Do the Numbers Say?&lt;/h3&gt;
&lt;p&gt;GLM-OCR achieves the lowest character error rate at 0.328, while PP-OCRv5 leads on word-level accuracy with a WER of 0.789. Both modern engines dramatically outperform the older generation, with exact match rates 8-13x higher than Tesseract or EasyOCR.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Engine &lt;/th&gt;&lt;th&gt;Type &lt;/th&gt;&lt;th&gt;Parameters &lt;/th&gt;&lt;th&gt;CER (lower=better) &lt;/th&gt;&lt;th&gt;WER (lower=better) &lt;/th&gt;&lt;th&gt;Exact Match (higher=better) &lt;/th&gt;&lt;th&gt;Latency (ms/img)&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Tesseract &lt;/td&gt;&lt;td&gt;LSTM &lt;/td&gt;&lt;td&gt;n/a &lt;/td&gt;&lt;td&gt;0.785 &lt;/td&gt;&lt;td&gt;1.043 &lt;/td&gt;&lt;td&gt;2.5% &lt;/td&gt;&lt;td&gt;49&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;EasyOCR &lt;/td&gt;&lt;td&gt;CRNN &lt;/td&gt;&lt;td&gt;~10M &lt;/td&gt;&lt;td&gt;0.695 &lt;/td&gt;&lt;td&gt;1.074 &lt;/td&gt;&lt;td&gt;2.6% &lt;/td&gt;&lt;td&gt;14&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;PP-OCRv5&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;SVTR+CTC &lt;/td&gt;&lt;td&gt;&lt;strong&gt;5M&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;0.477 &lt;/td&gt;&lt;td&gt;&lt;strong&gt;0.789&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;21.4% &lt;/td&gt;&lt;td&gt;103&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;GLM-OCR&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;VLM &lt;/td&gt;&lt;td&gt;&lt;strong&gt;0.9B&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;0.328&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;0.801 &lt;/td&gt;&lt;td&gt;&lt;strong&gt;32.6%&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;141&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7aqwpajca70pmcs3hjl.png&quot; alt=&quot;CER Comparison&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ueyrt23geii16juchya0.png&quot; alt=&quot;Accuracy vs Latency&quot;&gt;&lt;/p&gt;
&lt;p&gt;Let me walk through what these numbers actually mean.&lt;/p&gt;
&lt;h4 id=&quot;finding-1-tesseract-and-easyocr-barely-function-on-handwriting&quot;&gt;Finding 1: Tesseract and EasyOCR Barely Function on Handwriting&lt;/h4&gt;
&lt;p&gt;Both Tesseract and EasyOCR achieve under &lt;strong&gt;3% exact match&lt;/strong&gt;, meaning they get fewer than 1 in 40 words perfectly right. Their WER exceeds 1.0, which means on average they produce &lt;em&gt;more errors than there are words&lt;/em&gt;. For practical purposes, these engines are unusable on handwritten medical text.&lt;/p&gt;
&lt;p&gt;This isn't a knock on either project. Tesseract's LSTM architecture was optimized for printed text, and EasyOCR's CRNN similarly excels on clean, well-formatted inputs. Handwritten medical cursive is simply a different problem.&lt;/p&gt;
&lt;h4 id=&quot;finding-2-the-modern-engines-are-a-generational-leap&quot;&gt;Finding 2: The Modern Engines Are a Generational Leap&lt;/h4&gt;
&lt;p&gt;PP-OCRv5 and GLM-OCR both break the 20% exact match barrier, a qualitative jump from the sub-3% performance of the older engines. The gap between &quot;old&quot; and &quot;new&quot; (a roughly 10x improvement in exact match) is far larger than the gap between PP-OCRv5 and GLM-OCR themselves.&lt;/p&gt;
&lt;h4 id=&quot;finding-3-why-does-glm-ocr-win-on-characters-but-lose-on-words-&quot;&gt;Finding 3: Why Does GLM-OCR Win on Characters but Lose on Words?&lt;/h4&gt;
&lt;p&gt;This is the most interesting finding. GLM-OCR achieves a CER of &lt;strong&gt;0.328&lt;/strong&gt;, which is 31% lower than PP-OCRv5's 0.477. At the character level, the vision-language approach genuinely helps. GLM-OCR can use its language decoder's knowledge of likely character sequences to infer partially visible characters.&lt;/p&gt;
&lt;p&gt;But PP-OCRv5 edges ahead on WER: &lt;strong&gt;0.789 vs 0.801&lt;/strong&gt;. It makes fewer word-level mistakes.&lt;/p&gt;
&lt;p&gt;Why the divergence? My hypothesis: GLM-OCR's autoregressive generation occasionally produces subtle extra tokens or formatting variations. The GLM-OCR paper itself acknowledges &quot;minor stochastic variation in formatting behaviors, particularly in line breaks and whitespace handling&quot; (&lt;a rel=&quot;nofollow&quot; href=&quot;https://arxiv.org/abs/2603.10910&quot;&gt;Duan et al.&lt;/a&gt;, 2026). These small artifacts barely affect CER but can flip a word from &quot;correct&quot; to &quot;incorrect&quot; in WER/exact-match scoring.&lt;/p&gt;
&lt;p&gt;The practical takeaway: &lt;strong&gt;which engine is &quot;better&quot; depends on your error metric.&lt;/strong&gt; If you care about getting as close as possible character-by-character (for downstream spell-correction, for example), GLM-OCR wins. If you need clean word-level outputs with minimal postprocessing, PP-OCRv5 has the edge.&lt;/p&gt;
&lt;h4 id=&quot;finding-4-what-are-the-real-deployment-trade-offs-&quot;&gt;Finding 4: What Are the Real Deployment Trade-offs?&lt;/h4&gt;
&lt;p&gt;Both engines are fast enough for practical use. PP-OCRv5 processes images at &lt;strong&gt;103ms each&lt;/strong&gt; and GLM-OCR at &lt;strong&gt;141ms&lt;/strong&gt;. GLM-OCR's Multi-Token Prediction (generating roughly 5.2 tokens per step instead of one) keeps its inference speed competitive despite the larger model.&lt;/p&gt;
&lt;p&gt;The bigger difference is &lt;strong&gt;model size and memory footprint&lt;/strong&gt;. PP-OCRv5's 5M parameters take up roughly 20MB on disk, small enough for a Raspberry Pi or embedded device. GLM-OCR's 0.9B parameters need around 1.8GB at FP16 (less with quantization). Both run on CPU without a GPU, as our Apple Silicon benchmark shows, but GLM-OCR consumes significantly more RAM. The GLM-OCR paper notes that the model &quot;enables deployment in both large-scale and resource-constrained edge scenarios&quot; and supports frameworks like Ollama for local inference (&lt;a rel=&quot;nofollow&quot; href=&quot;https://arxiv.org/abs/2603.10910&quot;&gt;Duan et al.&lt;/a&gt;, 2026). For deploying across thousands of low-spec workstations, PP-OCRv5's small footprint is a clear advantage. For a centralized server or any machine with a few GB of RAM to spare, GLM-OCR is equally practical.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-do-the-predictions-actually-look-like-&quot;&gt;What Do the Predictions Actually Look Like?&lt;/h3&gt;
&lt;p&gt;Numbers tell one story. Seeing the actual predictions tells another. Here are four representative samples from the benchmark, hand-picked to illustrate each finding above.&lt;/p&gt;
&lt;h4 id=&quot;glm-ocr-nails-a-complex-drug-name&quot;&gt;GLM-OCR Nails a Complex Drug Name&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f50vz8qzjypfxds957f8.png&quot; alt=&quot;GLM-OCR nails &amp;quot;Ceftriaxone&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&quot;Ceftriaxone&quot; (a common antibiotic), 11 characters long. Tesseract reads &quot;Wau&quot; and EasyOCR produces &quot;@@FNRH,&quot; both useless. PP-OCRv5 gets close with &quot;CEFRAXONE&quot; (CER=0.18, missing the 'ti'). Only GLM-OCR reads it perfectly. On long drug names, the language decoder's knowledge of likely character sequences gives it a real edge.&lt;/p&gt;
&lt;h4 id=&quot;when-pp-ocrv5-is-closer-and-glm-ocr-hallucinates&quot;&gt;When PP-OCRv5 Is Closer and GLM-OCR Hallucinates&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hzhur0d9njtprem6cvds.png&quot; alt=&quot;PP-OCRv5 closer on &amp;quot;Zolfin&amp;quot;, GLM-OCR hallucinates&quot;&gt;&lt;/p&gt;
&lt;p&gt;&quot;Zolfin&quot; (a proton pump inhibitor). PP-OCRv5 reads &quot;zolfiu&quot; (CER=0.17, just the last character wrong). GLM-OCR outputs &quot;2016'u&quot; (CER=1.0), completely misreading the word as a number. This is the flip side of the VLM approach: when the handwriting doesn't match patterns in the training data, the language model can steer the output in the wrong direction entirely.&lt;/p&gt;
&lt;h4 id=&quot;glm-ocr-nearly-perfect&quot;&gt;GLM-OCR Nearly Perfect&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45x5mr6cgpg2r54q6xmy.png&quot; alt=&quot;GLM-OCR nearly perfect on &amp;quot;Pantonix&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&quot;Pantonix&quot; (a pantoprazole brand). GLM-OCR outputs &quot;Pantomix&quot; (CER=0.125, one character off). PP-OCRv5 gets &quot;Pantomy&quot; (CER=0.375). Both are close, but GLM-OCR is three times more accurate by CER. Neither gets an exact match, which is the pattern behind Finding 3: GLM-OCR consistently gets closer character-by-character, even when neither engine gets the word exactly right.&lt;/p&gt;
&lt;h4 id=&quot;when-the-vlm-goes-off-the-rails&quot;&gt;When the VLM Goes Off the Rails&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fsukpn1xj6tw0jve4c7.png&quot; alt=&quot;GLM-OCR outputs LaTeX for &amp;quot;Fexo&amp;quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&quot;Fexo&quot; (fexofenadine, an antihistamine). EasyOCR reads &quot;Texo&quot; (CER=0.25) and PP-OCRv5 reads &quot;-exo&quot; (CER=0.25), both reasonable attempts. GLM-OCR outputs LaTeX math notation: &lt;code&gt;$ \sqrt{e} x_{0} $&lt;/code&gt; (CER=4.75). This is a rare but real failure mode of generative VLMs: the model interprets the handwriting as a math expression instead of text. It produced more characters than the ground truth has, which is why CER exceeds 1.0.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-are-the-limitations-&quot;&gt;What Are the Limitations?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Single dataset, single run.&lt;/strong&gt; RxHandBD is one dataset of Bangladeshi prescriptions. US, European, or East Asian handwriting styles may produce different rankings. We don't have confidence intervals from multiple runs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Word-level only.&lt;/strong&gt; We tested recognition on pre-cropped word images, not full-page detection + recognition. Real-world performance depends on the complete pipeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU-only.&lt;/strong&gt; All engines ran on CPU. GPU acceleration could significantly change the latency picture, particularly for GLM-OCR.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Default configs.&lt;/strong&gt; No engine was fine-tuned on medical data. Domain-specific adaptation could improve all of them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No clinical validation.&lt;/strong&gt; OCR accuracy and clinical safety are different things. A 32.6% exact match rate is impressive for research, but not nearly sufficient for automated prescription processing without human review.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;conclusion-1&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Modern OCR has made a genuine leap on handwritten medical text. &lt;strong&gt;PP-OCRv5&lt;/strong&gt; (5M parameters, best word-level accuracy) and &lt;strong&gt;GLM-OCR&lt;/strong&gt; (0.9B parameters, best character-level accuracy) both dramatically outperform Tesseract and EasyOCR.&lt;/p&gt;
&lt;p&gt;The two champions represent fundamentally different design philosophies: a data-centric specialized pipeline vs. a compact vision-language model. Yet they arrive at remarkably similar performance levels. Both are open-source and practically deployable.&lt;/p&gt;
&lt;p&gt;For practitioners building healthcare OCR systems: these two engines deserve serious evaluation. Start with your specific error tolerance, hardware constraints, and whether you need word-level recognition or full-page document understanding.&lt;/p&gt;
&lt;p&gt;For researchers: this is a domain with high clinical impact and, as these results show, plenty of room for improvement. Even the best engine here gets only 1 in 3 words exactly right on doctor handwriting. There's real work left to do.&lt;/p&gt;
&lt;p&gt;What datasets or engines should I test next? Let me know in the comments.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;World Health Organization. &quot;WHO launches global effort to halve medication-related errors in 5 years.&quot; March 29, 2017. &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.who.int/news/item/29-03-2017-who-launches-global-effort-to-halve-medication-related-errors-in-5-years&quot;&gt;https://www.who.int/news/item/29-03-2017-who-launches-global-effort-to-halve-medication-related-errors-in-5-years&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Albarrak AI, Al Rashidi EA, Fatani RK, Al Ageel SI, Mohammed R. &quot;Assessment of legibility and completeness of handwritten and electronic prescriptions.&quot; &lt;em&gt;Saudi Pharmaceutical Journal&lt;/em&gt;, 2014. &lt;a rel=&quot;nofollow&quot; href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC4281619/&quot;&gt;https://pmc.ncbi.nlm.nih.gov/articles/PMC4281619/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Albalushi AK, et al. &quot;Assessment of Legibility of Handwritten Prescriptions and Adherence to W.H.O. Prescription Writing Guidelines.&quot; &lt;em&gt;J. of Pharmaceutical Research International&lt;/em&gt;, 2023. &lt;a rel=&quot;nofollow&quot; href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC10686667/&quot;&gt;https://pmc.ncbi.nlm.nih.gov/articles/PMC10686667/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cui C, Zhang Y, Sun T, et al. &quot;PP-OCRv5: A Specialized 5M-Parameter Model Rivaling Billion-Parameter Vision-Language Models on OCR Tasks.&quot; arXiv:2603.24373, March 2026. &lt;a rel=&quot;nofollow&quot; href=&quot;https://arxiv.org/abs/2603.24373&quot;&gt;https://arxiv.org/abs/2603.24373&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Duan S, Xue Y, Wang W, et al. &quot;GLM-OCR Technical Report.&quot; arXiv:2603.10910, March 2026. &lt;a rel=&quot;nofollow&quot; href=&quot;https://arxiv.org/abs/2603.10910&quot;&gt;https://arxiv.org/abs/2603.10910&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shovon MSH, et al. &quot;RxHandBD: A Handwritten Prescription Recognition Dataset from Bangladesh.&quot; &lt;em&gt;Mendeley Data&lt;/em&gt;. &lt;a rel=&quot;nofollow&quot; href=&quot;https://data.mendeley.com/datasets&quot;&gt;https://data.mendeley.com/datasets&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Grand View Research. &quot;Optical Character Recognition Market Analysis.&quot; 2025. &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.grandviewresearch.com/industry-analysis/optical-character-recognition-market&quot;&gt;https://www.grandviewresearch.com/industry-analysis/optical-character-recognition-market&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Benchmark conducted independently. No affiliation with any OCR project. All engines evaluated using default configurations.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;About the author:&lt;/strong&gt; Botao Deng is an ML/AI engineer and researcher who builds and evaluates production models.&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/robot010&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14211/how-well-can-ocr-read-doctor-handwriting-in-2026</guid>
<pubDate>Wed, 08 Apr 2026 06:00:04 +0000</pubDate>
</item>
<item>
<title>Enhanced Paperless-NGX with Paddle OCR + LLM Pipeline</title>
<link>https://coderlegion.com/6107/enhanced-paperless-ngx-with-paddle-ocr-llm-pipeline</link>
<description>&lt;h3 id=&quot;building-a-private-ai-document-pipeline-with-paperless-paddleocr-and-llms&quot;&gt;Building a Private AI Document Pipeline with Paperless, PaddleOCR, and LLMs&lt;/h3&gt;
&lt;p&gt;So this past week I hacked together a little side project to smarten up my &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/paperless-ngx/paperless-ngx&quot;&gt;Paperless-ngx&lt;/a&gt; setup — you know, that self-hosted document management system that eats PDFs and makes them searchable.&lt;/p&gt;
&lt;p&gt;Now, Paperless-ngx is solid, don’t get me wrong. But it uses Tesseract for OCR, and honestly... Tesseract is not optimal for anything that's not clean text.&lt;/p&gt;
&lt;p&gt;So this just evolved out of need to improve paperless-ngx's OCR capability and to properly classify documents and extract tags. titles and summaries for documents.&lt;/p&gt;
&lt;p&gt;This blog is a walkthrough of what I built — what worked, what didn’t, and how it turned into a pretty neat little pipeline with its own microservices. Hope it gives you some ideas.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-i-was-going-for&quot;&gt;What I Was Going For&lt;/h3&gt;
&lt;p&gt;I wanted a system that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uses &lt;strong&gt;PaddleOCR&lt;/strong&gt; instead of Tesseract for better OCR output&lt;/li&gt;
&lt;li&gt;Runs a &lt;strong&gt;local LLM&lt;/strong&gt; using &lt;a rel=&quot;nofollow&quot; href=&quot;https://ollama.com&quot;&gt;Ollama&lt;/a&gt; to:&lt;ul&gt;
&lt;li&gt;Suggest a smart document title&lt;/li&gt;
&lt;li&gt;Classify the document into a type (invoice, id, tax, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pushes that back to Paperless so the doc is nicely searchable and tagged&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything stays local/private. No exposure to external LLMs. Just Python, containers, compose to stitch everything together.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-it-all-works-now-&quot;&gt;How It All Works (Now)&lt;/h3&gt;
&lt;p&gt;After a few iterations, I ended up with a clean microservice setup with each part doing its job:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;paperless-ngx&lt;/code&gt;: The main document management system (already amazing)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ollama&lt;/code&gt;: Runs a local LLM like Mistral (or phi3 or any configurable in env), no cloud stuff&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ocr-service&lt;/code&gt;: FastAPI service that runs PaddleOCR&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pipeline&lt;/code&gt;: Python CLI that connects all the dots — downloads doc from Paperless, sends it to OCR and LLM, then updates Paperless with the smart results&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That way, each service does one thing and does it well or can be enhanced in isolation. They all run in Docker, talk to each other over the same network, and make one smooth, local AI document workflow.&lt;/p&gt;
&lt;p&gt;This leverages &lt;code&gt;paperless-ngx&lt;/code&gt;'s extensive features and augments it with better OCR and LLM classification capabilities.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-flow-looks-like-this-&quot;&gt;The Flow Looks Like This:&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt; Paperless stores docs in its DB
⬇️
 I run my pipeline CLI: `docker compose run pipeline 42`
⬇️
 pipeline downloads the doc via Paperless API (by ID)
⬇️
 Sends it to the OCR microservice over HTTP
⬇️
 Gets back clean OCR’d text
⬇️
 Sends text to Ollama (LLM) to generate:
    - title
    - document type
⬇️
 Updates Paperless document via PATCH
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;everything-runs-in-docker&quot;&gt;Everything Runs in Docker&lt;/h3&gt;
&lt;p&gt;Here's the final list of containers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;paperless → standard Paperless-ngx&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;redis → required by Paperless&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ollama → runs local LLMs like Mistral&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ocr-service → FastAPI + PaddleOCR&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pipeline → command-line microservice that ties it all together&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;architecture-diagram&quot;&gt;Architecture Diagram&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;                   ┌────────────────────────┐
                   │  Paperless-ngx (UI)  │
                   └────────────┬───────────┘
                                │
                    [User notes Document ID]
                                │
                   ┌────────────▼────────────┐
                   │    Pipeline Service    │
                   │ (LLM &amp;amp; Orchestration)   │
                   └────────────┬────────────┘
                                │
           ┌────────────────────┼────────────────────┐
           │                    │                    │
           ▼                    ▼                    ▼
  ┌────────────────┐   ┌────────────────┐   ┌────────────────────┐
  │ Downloads PDF  │   │ Sends to OCR   │   │ Sends OCR text to  │
  │ via Paperless  │   │ microservice   │   │ Ollama LLM (Mistral)│
  └────────────────┘   └────────────────┘   └────────────────────┘
                                                │
                     ◀────────────┬─────────────┘
                                  ▼
                        Title + Type Prediction
                                  │
                        PATCH back to Paperless
                       (update metadata + text)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;what-gave-me-trouble&quot;&gt;What Gave Me Trouble&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Paperless consumes files from consume/ automatically and moves it — I had to work around that by working only with doc IDs via API as at this time I was more focused on adding OCR/AI features. This one is high on my TODO list.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PaddleOCR kept re-downloading models — made sure models are cached.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;folder-structure&quot;&gt;Folder Structure&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;├── docker-compose.yml
├── __init__.py
├── model-cache
├── ocr_service
│   ├── app
│   │   ├── __init__.py
│   │   ├── main.py
│   │   ├── ocr_config.yaml
│   │   └── ocr_engine.py
│   ├── Dockerfile
│   └── requirements.txt
├── paperless-data
│   ├── consume
│   ├── data
│   │   ├── db.sqlite3
│   │   ├── index
│   │   │   ├── _MAIN_63.toc
│   │   │   ├── MAIN_9v88o8vye3gbqub1.seg
│   │   │   ├── MAIN_ui8jrpftrvauh4n1.seg
│   │   │   ├── MAIN_wceagdbh71brm5wg.seg
│   │   │   └── MAIN_WRITELOCK
│   │   ├── log
│   │   │   └── celery.log.1
│   │   └── migration_lock
│   └── media
│       ├── documents
│       │   ├── archive
│       │   │   ├── 0000009.pdf
│       │   │   └── 0000016.pdf
│       │   ├── originals
│       │   │   ├── 0000009.jpg
│       │   │   └── 0000016.pdf
│       │   └── thumbnails
│       │       ├── 0000009.webp
│       │       └── 0000016.webp
│       └── media.lock
├── pipeline_service
│   ├── app
│   │   ├── api_client.py
│   │   ├── __init__.py
│   │   ├── llm_processor.py
│   │   ├── main.py
│   │   └── watcher.py
│   ├── Dockerfile
│   ├── __init__.py
│   ├── logger.py
│   ├── prompts
│   │   └── classify_title.txt
│   ├── requirements.txt
│   └── test.py
└── README.md
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;-what-s-next-&quot;&gt;✅ What's Next?&lt;/h3&gt;
&lt;p&gt;I might:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Run the pipeline automatically when a new doc lands&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add authentication for OCR and pipeline service (utilizing &lt;code&gt;paperless-ngx&lt;/code&gt;'s token auth?)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improve performance of OCR service, perhaps using other language (Go, Rust)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add document summarization via LLM&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extract metadata like amount, date, sender&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hook into Paperless tags and correspondents&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;wrapping-up&quot;&gt;Wrapping Up&lt;/h3&gt;
&lt;p&gt;If you need a document management system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;That ingests all kinds off docs PDFs, images etc.&lt;/li&gt;
&lt;li&gt;That reliably extracts text from varied kind of docs.&lt;/li&gt;
&lt;li&gt;That classifies, tags and summarizes docs using LLM.&lt;/li&gt;
&lt;li&gt;That keeps stuff private - no exposure to external LLMs.&lt;/li&gt;
&lt;li&gt;It comes with features loaded from &lt;code&gt;paperless-ngx&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then this might be an appealing setup.&lt;/p&gt;
&lt;p&gt;It’s Python all the way down. No rocket science — just containers, OCR, and a private LLM.&lt;/p&gt;
&lt;p&gt;Questions or inputs are welcome.&lt;/p&gt;
</description>
<category>Backend Dev</category>
<guid isPermaLink="true">https://coderlegion.com/6107/enhanced-paperless-ngx-with-paddle-ocr-llm-pipeline</guid>
<pubDate>Mon, 06 Oct 2025 09:15:37 +0000</pubDate>
</item>
</channel>
</rss>