Hopp til hovedinnhold
AI-utvikling

OCR og Dokumentparsing for RAG: OpenCV vs Docling vs Mistral OCR

Echo Algori Data
Av Echo Team
||10 min lesing
OCR og Dokumentparsing for RAG: OpenCV vs Docling vs Mistral OCR

Du har satt opp Qdrant på en budsjett-VPS. Embedding-modellen er klar. Men så kommer det uunngåelige spørsmålet: hvordan får du faktisk teksten ut av alle PDF-ene, fakturene og skannede dokumentene dine?

Her er det mange tar feil. De blander sammen datasyn (computer vision) og dokumentintelligens — to fundamentalt forskjellige disipliner som løser helt ulike problemer. Denne guiden rydder opp i forvirringen og gir deg en konkret arbeidsflyt for å bygge en dokumentpipeline som faktisk fungerer i et RAG-system.

Den grunnleggende forskjellen: Piksler vs. tekst

Før vi dykker inn i verktøy, må vi forstå hva vi egentlig prøver å gjøre.

OpenCV er datasyn. Det ser piksler. Det kan fortelle deg at et bilde inneholder rektangler, linjer og konturer. Det kan rette opp en skjev skanning, fjerne skygger og forbedre kontrast. Men det kan ikke lese — det aner ikke hva teksten sier.

OCR + Parsing er dokumentintelligens. Det gjenkjenner bokstaver, ord og setninger. Det forstår at en tabell er en tabell, at en overskrift er en overskrift, og at en punktliste er strukturert innhold. Det gir deg Markdown, JSON eller ren tekst — formater som RAG-systemet ditt faktisk kan bruke.

Tenk på det slik:

EgenskapOpenCV (Datasyn)OCR + Parsing (Dokumentintelligens)
SerPiksler, kanter, fargerBokstaver, ord, avsnitt
ForstårFormer og konturerSpråk og dokumentstruktur
OutputBearbeidet bildeStrukturert tekst (Markdown/JSON)
Alene nyttig for RAG?NeiJa
SpråkstøtteIkke relevant100+ språk inkl. norsk
TabellgjenkjenningFinner rektanglerForstår rader og kolonner

Konklusjon: Du trenger begge, men til helt forskjellige ting.

Hvorfor dette er viktig for RAG

Et RAG-system er bare så godt som dataen det bygger på. Hvis dokumentpipelinen din gir deg rotete, ustrukturert tekst med tabeller som er blitt til kaos og overskrifter som er blandet inn i brødtekst — da hjelper det ikke hvor sofistikert vektordatabasen eller LLM-en din er.

Dårlig parsing = dårlig chunking = dårlige embeddings = dårlige svar.

For norske SMBer som håndterer kontrakter, fakturaer, produktdokumentasjon og interne retningslinjer er dette kritisk. Disse dokumentene har ofte kompleks layout med tabeller, kolonner og blandede språk (norsk/engelsk).

Beste praksis-arbeidsflyt: Bruk begge sammen

Den optimale dokumentpipelinen for RAG bruker datasyn og dokumentintelligens i sekvens:

Skannede dokumenter / PDF-er
        │
        ▼
┌─────────────────────┐
│  1. OpenCV           │  ← Bildeforbehandling
│  - Rette opp skjevhet│
│  - Fjerne skygger    │
│  - Øke kontrast      │
│  - Fjerne støy       │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│  2. OCR              │  ← Tekstgjenkjenning
│  - PaddleOCR         │
│  - Tesseract         │
│  - Mistral OCR (API) │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│  3. Parsing          │  ← Strukturering
│  - Docling           │
│  - Unstructured.io   │
│  - LlamaParse        │
└─────────┬───────────┘
          │
          ▼
   Markdown / JSON
   klar for chunking
   og embedding

Steg 1: Bildeforbehandling med OpenCV

For skannede dokumenter gjør forbehandling en enorm forskjell på OCR-nøyaktigheten:

import cv2
import numpy as np

def preprocess_scanned_document(image_path: str) -> np.ndarray:
    """Forbehandle skannet dokument for bedre OCR-resultater"""
    img = cv2.imread(image_path)

    # Konverter til gråtoner
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Rett opp skjevhet (deskew)
    coords = np.column_stack(np.where(gray > 0))
    angle = cv2.minAreaRect(coords)[-1]
    if angle < -45:
        angle = -(90 + angle)
    else:
        angle = -angle

    (h, w) = gray.shape[:2]
    center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, angle, 1.0)
    rotated = cv2.warpAffine(
        gray, M, (w, h),
        flags=cv2.INTER_CUBIC,
        borderMode=cv2.BORDER_REPLICATE
    )

    # Fjern støy med gaussisk uskarphet
    denoised = cv2.GaussianBlur(rotated, (5, 5), 0)

    # Adaptiv terskelverdi for bedre kontrast
    binary = cv2.adaptiveThreshold(
        denoised, 255,
        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY, 11, 2
    )

    return binary

Tips: For digitalt genererte PDF-er (ikke skannede) kan du hoppe over dette steget. Docling og andre parsere håndterer native PDF-er direkte.

Steg 2: OCR — Gjenkjenn teksten

Etter forbehandling trenger du et OCR-verktøy som faktisk leser teksten.

Steg 3: Parsing — Strukturer outputen

OCR gir deg rå tekst. Parsing gir deg strukturert tekst med overskrifter, tabeller og hierarki — det som gjør chunking og retrieval effektivt.

Beste selvhostede verktøy (åpen kildekode)

1. Docling (IBM Research) — Gullstandarden

Docling er det mest komplette åpne verktøyet for dokumentkonvertering. IBM Research utvikler det aktivt, og det har blitt standardvalget i mange RAG-pipelines.

Nøkkeltall:

  • 97,9 % nøyaktighet på tabellgjenkjenning (IBM-benchmarks)
  • Støtter PDF, DOCX, PPTX, HTML, bilder, AsciiDoc og Markdown
  • Output i Markdown eller JSON
  • Innebygd OCR via EasyOCR eller Tesseract
  • Direkte integrasjon med LangChain og LlamaIndex
from docling.document_converter import DocumentConverter

converter = DocumentConverter()
result = converter.convert("kontrakt.pdf")

# Hent strukturert Markdown
markdown_output = result.document.export_to_markdown()

# Eller JSON for programmatisk tilgang
json_output = result.document.export_to_dict()

print(markdown_output)

Minnesbruk: Docling bruker ca. 1–1,5 GB RAM for standard dokumenter. Med GPU-akselerasjon (valgfritt) får du 3–5x raskere behandling.

Begrensning: Kan være treg på store PDF-er uten GPU. På en 2 GB VPS bør du behandle dokumenter i kø, ikke parallelt.

2. Marker — Rask PDF-til-Markdown

Marker er spesialisert på å konvertere PDF-er til ren Markdown. Det er raskere enn Docling for rene PDF-konverteringer, men har færre funksjoner.

# Installer
pip install marker-pdf

# Konverter en enkelt fil
marker_single kontrakt.pdf --output_dir ./output

# Batch-konvertering
marker ./pdf-mappe --output_dir ./output --workers 2

Fordeler:

  • 10x raskere enn naiiv OCR-pipeline
  • Fjerner topp- og bunntekst automatisk
  • Bevarer overskriftshierarki
  • Fungerer uten GPU (men tregere)

Begrensning: Kun PDF som input. Ingen DOCX/PPTX-støtte.

3. PaddleOCR — Lettvekts OCR-motor

Hvis du bare trenger ren OCR (ikke full dokumentparsing), er PaddleOCR det beste åpne alternativet. Det slår Tesseract på nøyaktighet i de fleste benchmarks, spesielt for ikke-latinske skriftsystemer.

from paddleocr import PaddleOCR

# Initialiser med norsk/engelsk støtte
ocr = PaddleOCR(use_angle_cls=True, lang='en')

result = ocr.ocr('skannet_faktura.png', cls=True)

for line in result[0]:
    text = line[1][0]
    confidence = line[1][1]
    print(f"{text} (konfidens: {confidence:.2f})")

Sammenligning med Tesseract:

EgenskapPaddleOCRTesseract
Nøyaktighet (latinsk)95–98 %90–95 %
Nøyaktighet (tabeller)GodSvak
HastighetRaskMiddels
Minnebruk~300 MB~200 MB
GPU-støtteJaNei
Aktivt vedlikeholdtJaLangsomt

Beste API-verktøy

Når du bruker API-basert OCR, sendes dokumentene dine til eksterne servere — et viktig hensyn for bedrifter som håndterer sensitive data. Gjennomgå risikoene ved tredjeparti AI-APIer før du ruter konfidensielle dokumenter gjennom eksterne tjenester.

For de som foretrekker API-baserte løsninger — enten fordi VPS-en ikke har nok ressurser, eller fordi driftskompleksiteten ikke er verdt det.

1. Mistral OCR

Mistrals OCR-API er den nyeste utfordreren og leverer imponerende resultater, spesielt på komplekse dokumenter med tabeller og diagrammer.

import requests

def mistral_ocr(file_path: str, api_key: str) -> dict:
    """Send dokument til Mistral OCR API"""
    url = "https://api.mistral.ai/v1/ocr"

    with open(file_path, "rb") as f:
        response = requests.post(
            url,
            headers={"Authorization": f"Bearer {api_key}"},
            files={"file": f},
            data={"model": "mistral-ocr-latest"}
        )

    return response.json()

Fordeler: Svært god tabellgjenkjenning, forstår kompleks layout, rask.

Ulempe: Kostnad per side, data sendes til ekstern tjeneste (GDPR-hensyn).

2. LlamaParse

LlamaIndex sitt parsingverktøy er bygget spesifikt for RAG-pipelines. Det forstår dokumentstruktur og gir output som er optimalisert for chunking.

from llama_parse import LlamaParse

parser = LlamaParse(
    api_key="din-api-nokkel",
    result_type="markdown",
    language="no"
)

documents = parser.load_data("arsrapport.pdf")

Fordeler: 1 000 gratis sider/dag, RAG-optimalisert output, god tabellhåndtering.

3. Unstructured.io

Det mest modne alternativet med bred filformatstøtte. Kan kjøres selvhostet (åpen kildekode) eller via API.

from unstructured.partition.pdf import partition_pdf

elements = partition_pdf(
    filename="dokument.pdf",
    strategy="hi_res",
    languages=["nor", "eng"]
)

# Filtrer etter type
tables = [el for el in elements if el.category == "Table"]
text_blocks = [el for el in elements if el.category == "NarrativeText"]

Sammenligningstabell for 2 GB RAM VPS

For deg som kjører RAG på en budsjett-VPS (som beskrevet i vår Qdrant-guide), er minnebruk kritisk.

VerktøyMin. RAMKjører på 2 GB VPS?NøyaktighetHastighetLisens
Docling1–1,5 GBKnapt (med swap)BesteMiddelsMIT
Marker800 MB–1,2 GBJa (med swap)Veldig godRaskGPL
PaddleOCR300–500 MBJaGodRaskApache 2.0
Tesseract150–300 MBJaOKMiddelsApache 2.0
Mistral OCR~0 (API)JaBesteRaskProprietær
LlamaParse~0 (API)JaVeldig godRaskProprietær
Unstructured1,5–2 GBNeiVeldig godTregApache 2.0

Viktig: «Kjører på 2 GB VPS» betyr at verktøyet kjører samtidig med Qdrant. Husk at Qdrant allerede bruker 1–1,5 GB.

Tips for norske SMBer på budsjett-VPS

1. Behandle dokumenter i kø, ikke parallelt

På en 2 GB VPS har du ikke råd til å kjøre OCR og Qdrant-indeksering samtidig. Bruk en enkel jobbkø:

import queue
import threading
from pathlib import Path

doc_queue = queue.Queue()

def process_document_queue():
    """Behandle dokumenter sekvensielt for å spare minne"""
    while True:
        doc_path = doc_queue.get()
        if doc_path is None:
            break

        try:
            # PaddleOCR for tekst (lavt minnebruk)
            result = ocr.ocr(str(doc_path))
            text = "\n".join(
                [line[1][0] for line in result[0]]
            )

            # Send til embedding + Qdrant
            chunks = chunk_text(text)
            embeddings = generate_embeddings(chunks)
            upsert_to_qdrant(chunks, embeddings)

        except Exception as e:
            print(f"Feil ved behandling av {doc_path}: {e}")
        finally:
            doc_queue.task_done()

# Start arbeider i bakgrunnen
worker = threading.Thread(target=process_document_queue, daemon=True)
worker.start()

2. Bruk PaddleOCR + enkel Markdown-formatering

For de minste VPS-ene er dette den mest ressurseffektive kombinasjonen:

from paddleocr import PaddleOCR
import re

ocr = PaddleOCR(use_angle_cls=True, lang='en', use_gpu=False)

def ocr_to_markdown(image_path: str) -> str:
    """Konverter skannet dokument til enkel Markdown"""
    result = ocr.ocr(image_path, cls=True)
    lines = []

    for line in result[0]:
        text = line[1][0]
        confidence = line[1][1]

        if confidence < 0.7:
            continue  # Hopp over usikre resultater

        # Enkel overskriftsdeteksjon basert på skriftstørrelse
        bbox = line[0]
        height = abs(bbox[3][1] - bbox[0][1])

        if height > 30:
            lines.append(f"## {text}")
        elif height > 22:
            lines.append(f"### {text}")
        else:
            lines.append(text)

    return "\n\n".join(lines)

3. Vurder hybrid: Selvhostet OCR + API-parsing

En kostnadseffektiv strategi for norske SMBer:

  • Vanlige dokumenter (enkel layout): PaddleOCR lokalt (gratis)
  • Komplekse dokumenter (tabeller, kolonner): Mistral OCR eller LlamaParse API (betal per side)

Dette gir deg det beste fra begge verdener — lav driftskostnad for det meste, og høy nøyaktighet når du trenger det.

4. GDPR-hensyn

For norske bedrifter er dataplassering viktig:

  • Selvhostede verktøy (Docling, PaddleOCR, Marker): Dataen forlater aldri din VPS. Full kontroll.
  • API-verktøy (Mistral, LlamaParse): Data sendes til ekstern server. Sjekk leverandørens databehandleravtale (DPA) og om data lagres. Vår guide til AI API-datasikkerhet dekker hva du bør se etter.
  • Anbefaling: Bruk selvhostede verktøy for sensitive dokumenter (kontrakter, personaldata). API for ikke-sensitiv dokumentasjon.

Echos anbefaling: Komplett budsjett-RAG-pipeline

Basert på vår erfaring med norske SMBer anbefaler vi denne pipeline-konfigurasjonen for budsjett-RAG-oppsettet:

For 2 GB VPS (€4–8/måned)

PaddleOCR (lokal) → Enkel Markdown-formatering → Qdrant
  • Totalkostnad: VPS + embedding API = ~€20/måned
  • Nøyaktighet: God nok for de fleste forretningsdokumenter
  • Begrensning: Svak på komplekse tabeller

For 4 GB VPS (€8–15/måned)

Docling (lokal) → Strukturert Markdown → Qdrant
  • Totalkostnad: VPS + embedding API = ~€25/måned
  • Nøyaktighet: Veldig god, inkludert tabeller
  • Anbefalt for de fleste norske SMBer

For hybrid (budsjett + kvalitet)

PaddleOCR (lokal, daglig bruk)
+ Mistral OCR (API, komplekse docs) → Qdrant
  • Totalkostnad: VPS + embedding API + ~€10 OCR API = ~€35/måned
  • Nøyaktighet: Beste mulige uten stor investering

Oppsummering

Dokumentparsing for RAG handler ikke om å velge ett verktøy. Det handler om å bygge en pipeline der hvert steg gjør det det er best på:

  1. OpenCV forbereder bildene (men leser dem ikke)
  2. OCR gjenkjenner teksten (PaddleOCR for selvhostet, Mistral for API)
  3. Parsing strukturerer outputen (Docling for selvhostet, LlamaParse for API)
  4. Qdrant lagrer og søker i vektorene

For norske SMBer på budsjett er PaddleOCR + enkel formatering den mest kostnadseffektive starten. Når behovene vokser, kan du oppgradere til Docling eller legge til et API-verktøy for de vanskeligste dokumentene.

Det viktigste er å starte -- en «god nok»-pipeline som kjører i dag er uendelig mye bedre enn en perfekt pipeline som aldri blir ferdig.

Ofte stilte spørsmål

Hva er forskjellen mellom OCR og dokumentparsing for RAG?

OCR (Optical Character Recognition) konverterer bildepiksler til rå teksttegn. Dokumentparsing går lenger ved å forstå dokumentets struktur -- identifisere overskrifter, tabeller, lister og avsnitt -- og produsere organiserte formater som Markdown eller JSON. For RAG-systemer er parsing langt mer verdifullt fordi strukturert tekst gir bedre chunks og mer presise embeddings.

Kan jeg kjøre Docling sammen med Qdrant på en 2GB VPS?

Det er teknisk mulig, men trangt. Docling bruker 1,5-2GB RAM, og Qdrant bruker 1-1,5GB. Du trenger en swap-fil og må behandle dokumenter sekvensielt, ikke parallelt. For et mer komfortabelt oppsett kan du enten oppgradere til en 4GB VPS eller bruke PaddleOCR (300-500MB RAM) som primærmotor ved siden av Qdrant.

Hvilket OCR-verktøy håndterer norsk tekst best?

PaddleOCR og Docling håndterer begge norsk tekst pålitelig, inkludert spesialtegn som ae, oe og aa. PaddleOCR støtter norsk via sin latinske skriftmodell og oppnår 95-98 % nøyaktighet. Tesseract støtter også norsk (installer nor-språkpakken), men scorer lavere på nøyaktighetstester. For API-baserte løsninger håndterer Mistral OCR norsk godt takket være flerspråklig treningsdata.

Lønner det seg å betale for Mistral OCR eller LlamaParse fremfor selvhosting?

For de fleste norske SMBer fungerer en hybrid tilnærming best. Bruk PaddleOCR lokalt for hverdagsdokumenter (gratis, raskt, lavt ressursbruk) og kall Mistral OCR eller LlamaParse kun for komplekse dokumenter med nestede tabeller, flerkolonne-layout eller blandet norsk/engelsk innhold. Dette holder API-kostnadene under €10/måned mens du opprettholder høy nøyaktighet der det betyr mest.

Trenger jeg OpenCV-forbehandling for digitale PDF-er?

Nei. OpenCV-forbehandling er bare nødvendig for skannede dokumenter eller fotografier av papirdokumenter. Hvis PDF-ene dine ble generert digitalt (eksportert fra Word, laget av programvare), kan verktøy som Docling og Marker parse dem direkte uten bildeforbehandling. Å hoppe over OpenCV for digitale PDF-er sparer behandlingstid og forenkler pipelinen din.


Relatert lesing

Trenger du hjelp med å bygge en dokumentpipeline for ditt RAG-system? Kontakt Echo AlgoriData for skreddersydd rådgivning og implementering.

Hold deg oppdatert

Meld deg på nyhetsbrevet for de nyeste AI-innsiktene og bransjeoppdateringer.

Ta kontakt