You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用pytesseract在Python中读取扫描表格并转换为CSV文件?

Hey Lucas, let's break down your problem step by step and get that table converted to CSV smoothly.

First, let's clarify what image_to_boxes does—since you mentioned you don't understand its output: this method returns character-level bounding box data, meaning it gives you the coordinates (left, bottom, right, top) for every single character it detects, plus the character itself. It's great for tasks like text alignment or character-level analysis, but totally overkill (and unhelpful) for extracting structured table data. That's why the output seemed meaningless for your goal.

Now, let's fix your original issue with image_to_data and explore better approaches for table extraction:

1. Fix image_to_data for Table Extraction

The most likely reason image_to_data was throwing errors is poor image quality or incorrect Tesseract configuration. Tesseract works best with clean, high-contrast images. Let's add preprocessing and tweak the config:

import cv2
import pytesseract
from pytesseract import Output
import csv

# Load and preprocess the image (critical for Tesseract accuracy)
img = cv2.imread("p27-001.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Adaptive thresholding handles uneven lighting better than regular thresholding
thresh = cv2.adaptiveThreshold(
    gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2
)

# Configure Tesseract: --psm 6 assumes a single uniform block of text (perfect for tables)
custom_config = r"--oem 3 --psm 6"
data = pytesseract.image_to_data(thresh, output_type=Output.DICT, config=custom_config)

# Parse the output into a structured table
table_data = []
current_row = []
confidence_threshold = 60  # Adjust based on your image's clarity

for i in range(len(data["text"])):
    text = data["text"][i].strip()
    # Only keep text with decent confidence to avoid garbage
    if int(data["conf"][i]) > confidence_threshold and text:
        # Check if we've moved to a new row (using vertical position)
        if i > 0 and abs(data["top"][i] - data["top"][i-1]) > 10:
            table_data.append(current_row)
            current_row = []
        current_row.append(text)

# Add the final row
if current_row:
    table_data.append(current_row)

# Save to CSV
with open("p27-001_table.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(table_data)

2. Better Approach: Cell Segmentation + OCR

For tables with clear lines, splitting the image into individual cells first will give you much more accurate row/column alignment. Here's how to do it with OpenCV + Tesseract:

import cv2
import pytesseract
import csv

img = cv2.imread("p27-001.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Detect horizontal and vertical table lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40, 1))
horizontal_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 40))
vertical_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)

# Combine lines to get the table grid
combined_grid = cv2.addWeighted(horizontal_lines, 0.5, vertical_lines, 0.5, 0.0)
combined_grid = cv2.threshold(combined_grid, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

# Find cell contours and sort them by row then column
contours, _ = cv2.findContours(combined_grid, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=lambda x: (cv2.boundingRect(x)[1], cv2.boundingRect(x)[0]))

table_data = []
current_row = []
prev_y = None

for cnt in contours:
    x, y, w, h = cv2.boundingRect(cnt)
    # Skip tiny contours (noise)
    if w > 20 and h > 20:
        # Extract and preprocess the cell
        cell = gray[y:y+h, x:x+w]
        cell_thresh = cv2.threshold(cell, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
        # OCR the cell text
        text = pytesseract.image_to_string(cell_thresh, config="--oem 3 --psm 6").strip()
        # Check for new row
        if prev_y is not None and abs(y - prev_y) > 15:
            table_data.append(current_row)
            current_row = []
        current_row.append(text)
        prev_y = y

# Add the last row
if current_row:
    table_data.append(current_row)

# Save to CSV
with open("p27-001_table.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(table_data)

3. Quick Win: Use EasyOCR's Table Detection

If you want to skip the low-level preprocessing, EasyOCR has built-in table detection that works surprisingly well for images:

import easyocr
import csv

# Initialize reader (add your language code if not English)
reader = easyocr.Reader(["en"])
# Detect table and extract cells
table_result = reader.readtext("p27-001.jpg", detect_table=True)

# Convert to table format
table_data = []
for row in table_result[0]["cells"]:
    row_text = [cell["text"].strip() for cell in row]
    table_data.append(row_text)

# Save to CSV
with open("p27-001_table.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(table_data)

Final Notes:

  • If image_to_data was throwing specific errors, double-check your Tesseract installation path (use pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' on Windows if needed) and image file path.
  • For messy tables (merged cells, faded lines), you might need to manually clean up the CSV, but the above methods should get you 90% of the way there.

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:16:02