Jadual Kandungan
Jawapan betul
Rumah pembangunan bahagian belakang Tutorial Python OpenCV: Cari lajur dalam jurnal Arab (Python)

OpenCV: Cari lajur dalam jurnal Arab (Python)

Feb 22, 2024 pm 12:52 PM
overflow

OpenCV: Cari lajur dalam jurnal Arab (Python)

Kandungan soalan

Saya baru kenal opencv dan baru kenal python. Saya cuba menyusun kod yang saya temui dalam talian untuk menyelesaikan masalah penyelidikan saya. Saya mempunyai diari Arab tahun 1870 yang mempunyai ratusan halaman, setiap halaman mengandungi dua lajur dan mempunyai sempadan hitam tebal. Saya ingin mengekstrak dua lajur sebagai fail imej supaya saya boleh menjalankan ocr pada mereka secara individu sambil mengabaikan pengepala dan pengaki. Berikut ialah halaman contoh:

Halaman 3

Saya mempunyai sepuluh muka surat cetakan asal sebagai fail png yang berasingan. Saya menulis skrip berikut untuk mengendalikan setiap satu. Ia berfungsi seperti yang dijangkakan dalam 2 daripada 10 halaman, tetapi gagal menjana lajur dalam 8 halaman yang lain. Saya tidak memahami semua fungsi dengan cukup baik untuk mengetahui di mana saya boleh menggunakan nilai ini, atau jika keseluruhan pendekatan saya tersasar - Saya fikir cara terbaik untuk belajar ialah bertanya kepada komuniti bagaimana anda akan menyelesaikan masalah ini.

import cv2

def cutpage(fname, pnum):
    image = cv2.imread(fname)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (7,7), 0)
    thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 13))
    dilate = cv2.dilate(thresh, kernel, iterations=1)
    dilatename = "temp/dilate" + str(pnum) + ".png"
    cv2.imwrite(dilatename, dilate)
    cnts = cv2.findContours(dilate, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    cnts = sorted(cnts, key=lambda x: cv2.boundingRect(x)[0])

    fullpage=1
    column=1
    for c in cnts:
        x, y, w, h = cv2.boundingRect(c)
        if h > 300 and w > 20:
            if (h/w)<2.5:
                print("Found full page: ", x, y, w, h)
                filename = "temp/p" + str(pnum) + "-full" + str(fullpage) + ".png"
                fullpage+=1
            else:
                print("Found column: ", x, y, w, h)
                filename = "temp/p" + str(pnum) + "-col" + str(column) + ".png"
                column+=1
            roi = image[y:y+h, x:x+w]
            cv2.imwrite(filename, roi)
    return (column-1)
        
for nr in range(10):
    filename = "p"+str(nr)+".png"
    print("Checking page", nr)
    diditwork = cutpage(filename, nr)
    print("Found", diditwork, "columns")
Salin selepas log masuk

Berikutan tutorial, saya mencipta penyongsangan binari yang kabur dan diluaskan supaya ia dapat mengenal pasti kawasan segi empat tepat yang berbeza oleh kawasan putih yang besar. Saya juga menyimpan salinan setiap versi lanjutan supaya saya dapat melihat rupanya, berikut ialah halaman di atas selepas diproses:

Muka surat 3 telah dibesarkan

Gelung "untuk c dalam cnts" harus mencari kawasan segi empat tepat yang besar dalam imej. Jika nisbah aspek kurang daripada 2.5 saya mendapat halaman penuh (tanpa pengepala dan pengaki, yang berfungsi dengan baik), jika nisbah aspek lebih besar daripada ini, saya tahu ia adalah lajur dan ia menyimpannya cth. temp/ p2-col2.png

Saya mendapat beberapa halaman penuh yang bagus tanpa pengepala dan pengaki, iaitu, hanya sempadan hitam yang besar, tetapi tidak dicincang menjadi lajur. Dalam 2 muka surat daripada 10 saya mendapat apa yang saya mahu, iaitu:

Lajur Kejayaan di Halaman 2

Memandangkan saya kadang-kadang mendapat hasil yang diinginkan, mesti ada sesuatu yang berkesan, tetapi saya tidak tahu bagaimana untuk memperbaikinya lagi.

Editor:

Berikut adalah lebih banyak contoh halaman:

p0

p1

p5


Jawapan betul


Saya mencuba sesuatu tanpa sebarang pengembangan kerana saya ingin melihat sama ada saya boleh menggunakan garis tengah sebagai "pemisah". Ini kodnya:

im = cv2.cvtcolor(cv2.imread("arabic.png"), cv2.color_bgr2rgb) # read im as rgb for better plots
gray = cv2.cvtcolor(im, cv2.color_rgb2gray) # convert to gray
_, threshold = cv2.threshold(gray, 250, 255, cv2.thresh_binary_inv) # inverse thresholding
contours, _ = cv2.findcontours(threshold, cv2.retr_external, cv2.chain_approx_none) # find contours
sortedcontours = sorted(contours, key = cv2.contourarea, reverse=true) # sort according to area, descending
bigbox = sortedcontours[0] # get the contour of the big box
middleline = sortedcontours[1] # get the contour of the vertical line
xmiddleline, _, _, _ = cv2.boundingrect(middleline) # get x coordinate of middleline
leftboxcontour = np.array([point for point in bigbox if point[0, 0] < xmiddleline]) # assign left of line as points from the big contour
rightboxcontour = np.array([point for point in bigbox if point[0, 0] >= xmiddleline]) # assigh right of line as points from the big contour
leftboxx, leftboxy, leftboxw, leftboxh = cv2.boundingrect(leftboxcontour) # get properties of box on left
rightboxx, rightboxy, rightboxw, rightboxh = cv2.boundingrect(rightboxcontour) # get properties of box on right
leftboxcrop = im[leftboxy:leftboxy + leftboxh, leftboxx:leftboxx + leftboxw] # crop left 
rightboxcrop = im[rightboxy:rightboxy + rightboxh, rightboxx:rightboxx + rightboxw] # crop right
# maybe do you assertations about aspect ratio??
cv2.imwrite("right.png", rightboxcrop) # save image
cv2.imwrite("left.png", leftboxcrop) # save image
Salin selepas log masuk

Saya tidak menggunakan sebarang penegasan tentang nisbah aspek, jadi mungkin ini masih perlu anda lakukan..

Pada asasnya, garisan yang paling penting dalam kaedah ini adalah menghasilkan kontur kiri dan kanan berdasarkan koordinat x. Ini adalah keputusan akhir yang saya dapat:

Masih ada sedikit bahagian hitam di bahagian tepi, tetapi itu tidak menjadi masalah untuk ocr.

FYI: Saya menggunakan pakej berikut dalam jupyter:

import cv2
import numpy as np
%matplotlib notebook
import matplotlib.pyplot as plt
Salin selepas log masuk

v2.0: Dilaksanakan hanya menggunakan pengesanan kotak besar:

Jadi saya melakukan sedikit pelebaran dan kotak besar itu mudah dikesan. Saya menggunakan kernel mendatar untuk memastikan bahawa garis menegak kotak besar sentiasa cukup tebal untuk dikesan. Walau bagaimanapun, saya tidak dapat menyelesaikan masalah dengan garis tengah kerana ia sangat nipis... Namun begitu, berikut adalah kod untuk kaedah di atas:

im = cv2.cvtcolor(cv2.imread("1.png"), cv2.color_bgr2rgb) # read im as rgb for better plots
gray = cv2.cvtcolor(im, cv2.color_rgb2gray) # convert to gray
gray[gray<255] = 0 # added some contrast to make it either completly black or white
_, threshold = cv2.threshold(gray, 250, 255, cv2.thresh_binary_inv) # inverse thresholding
thresholddilated = cv2.dilate(threshold, np.ones((1,10)), iterations = 1) # dilate horizontally
contours, _ = cv2.findcontours(thresholddilated, cv2.retr_external, cv2.chain_approx_none) # find contours
sortedcontours = sorted(contours, key = cv2.contourarea, reverse=true) # sort according to area, descending
x, y, w, h = cv2.boundingrect(sortedcontours[0]) # get the bounding rect properties of the contour
left = im[y:y+h, x:x+int(w/2)+10].copy() # generate left, i included 10 pix from the right just in case
right = im[y:y+h, int(w/2)-10:w].copy() # and right, i included 10 pix from the left just in case
fig, ax = plt.subplots(nrows = 2, ncols = 3) # plotting...
ax[0,0].axis("off")
ax[0,1].imshow(im)
ax[0,1].axis("off")
ax[0,2].axis("off")
ax[1,0].imshow(left)
ax[1,0].axis("off")
ax[1,1].axis("off")
ax[1,2].imshow(right)
ax[1,2].axis("off")
Salin selepas log masuk

Ini adalah hasilnya, anda boleh melihat ia tidak sempurna, tetapi sekali lagi, kerana sasaran anda adalah ocr, ini tidak sepatutnya menjadi masalah.

Tolong beritahu saya jika ini berkesan, jika tidak saya akan memerah otak saya untuk mencari penyelesaian yang lebih baik...

v3.0: Cara yang lebih baik untuk mendapatkan imej yang lebih lurus, yang akan meningkatkan kualiti ocr.

Diinspirasikan oleh jawapan saya yang lain di sini: jawab. Adalah wajar untuk meluruskan imej supaya ocr mempunyai hasil yang lebih baik. Oleh itu, saya menggunakan transformasi empat mata pada bingkai luar yang dikesan. Ini akan meluruskan sedikit imej dan menjadikan teks lebih mendatar. Ini kodnya:

im = cv2.cvtcolor(cv2.imread("2.png"), cv2.color_bgr2rgb) # read im as rgb for better plots
gray = cv2.cvtcolor(im, cv2.color_rgb2gray) # convert to gray
gray[gray<255] = 0 # added some contrast to make it either completly black or white
_, threshold = cv2.threshold(gray, 250, 255, cv2.thresh_binary_inv) # inverse thresholding
thresholddilated = cv2.dilate(threshold, np.ones((1,10)), iterations = 1) # dilate horizontally
contours, _ = cv2.findcontours(thresholddilated, cv2.retr_external, cv2.chain_approx_none) # find contours
largest_contour = max(contours, key = cv2.contourarea) # get largest contour
hull = cv2.convexhull(largest_contour) # get the hull
epsilon = 0.02 * cv2.arclength(largest_contour, true) # epsilon
pts1 = np.float32(cv2.approxpolydp(hull, epsilon, true).reshape(-1, 2)) # get the points
result = four_point_transform(im, pts1) # using imutils
height, width = result.shape[:2] # get the dimensions of the transformed image
left = result[:, 0:int(width/2)].copy() # from the beginning to half the width
right = result[:, int(width/2): width].copy() # from half the width till the end
fig, ax = plt.subplots(nrows = 2, ncols = 3) # plotting...
ax[0,0].axis("off")
ax[0,1].imshow(result)
ax[0,1].axvline(width/2)
ax[0,1].axis("off")
ax[0,2].axis("off")
ax[1,0].imshow(left)
ax[1,0].axis("off")
ax[1,1].axis("off")
ax[1,2].imshow(right)
ax[1,2].axis("off")
Salin selepas log masuk

Mempunyai pakej berikut:

import cv2
import numpy as np
%matplotlib notebook
import matplotlib.pyplot as plt
from imutils.perspective import four_point_transform
Salin selepas log masuk

Seperti yang anda boleh lihat daripada kod, ini adalah pendekatan yang lebih baik, anda boleh memaksa imej untuk dipusatkan dan mendatar terima kasih kepada transformasi empat titik. Tambahan pula, tidak perlu memasukkan beberapa pertindihan kerana imej dipisahkan dengan baik. Berikut adalah contoh untuk rujukan anda:

Atas ialah kandungan terperinci OpenCV: Cari lajur dalam jurnal Arab (Python). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial Java
1663
14
Tutorial PHP
1266
29
Tutorial C#
1239
24
Adakah pengeluaran halaman H5 adalah pembangunan front-end? Adakah pengeluaran halaman H5 adalah pembangunan front-end? Apr 05, 2025 pm 11:42 PM

Ya, pengeluaran halaman H5 adalah kaedah pelaksanaan penting untuk pembangunan front-end, yang melibatkan teknologi teras seperti HTML, CSS dan JavaScript. Pemaju membina halaman H5 yang dinamik dan berkuasa dengan bijak menggabungkan teknologi ini, seperti menggunakan & lt; kanvas & gt; Tag untuk menarik grafik atau menggunakan JavaScript untuk mengawal tingkah laku interaksi.

Bagaimana untuk menyesuaikan simbol saiz semula melalui CSS dan menjadikannya seragam dengan warna latar belakang? Bagaimana untuk menyesuaikan simbol saiz semula melalui CSS dan menjadikannya seragam dengan warna latar belakang? Apr 05, 2025 pm 02:30 PM

Kaedah penyesuaian simbol saiz semula dalam CSS bersatu dengan warna latar belakang. Dalam perkembangan harian, kita sering menghadapi situasi di mana kita perlu menyesuaikan butiran antara muka pengguna, seperti menyesuaikan ...

Kenapa unsur-unsur blok sebaris tidak disengajakan? Bagaimana menyelesaikan masalah ini? Kenapa unsur-unsur blok sebaris tidak disengajakan? Bagaimana menyelesaikan masalah ini? Apr 04, 2025 pm 10:39 PM

Mengenai sebab-sebab dan penyelesaian untuk memaparkan unsur-unsur blok sebaris. Apabila menulis susun atur laman web, kami sering menghadapi masalah paparan yang kelihatan aneh. Bandingkan ...

Bagaimana cara menggunakan atribut clip-path CSS untuk mencapai kesan lengkung 45 darjah segmen? Bagaimana cara menggunakan atribut clip-path CSS untuk mencapai kesan lengkung 45 darjah segmen? Apr 04, 2025 pm 11:45 PM

Bagaimana untuk mencapai kesan lengkung 45 darjah segmen? Dalam proses melaksanakan segmen, bagaimana membuat sempadan yang betul berubah menjadi lengkung 45 darjah ketika mengklik butang kiri, dan titik ...

Bagaimana untuk mengawal bahagian atas dan akhir halaman dalam tetapan percetakan penyemak imbas melalui JavaScript atau CSS? Bagaimana untuk mengawal bahagian atas dan akhir halaman dalam tetapan percetakan penyemak imbas melalui JavaScript atau CSS? Apr 05, 2025 pm 10:39 PM

Cara menggunakan JavaScript atau CSS untuk mengawal bahagian atas dan akhir halaman dalam tetapan percetakan penyemak imbas. Dalam tetapan percetakan penyemak imbas, ada pilihan untuk mengawal sama ada paparan ...

Harga terbaru Bitcoin pada 2018-2024 USD Harga terbaru Bitcoin pada 2018-2024 USD Feb 15, 2025 pm 07:12 PM

Harga USD Bitcoin masa nyata Faktor yang menjejaskan harga bitcoin Petunjuk untuk meramalkan harga bitcoin masa depan Berikut adalah beberapa maklumat penting mengenai harga Bitcoin pada 2018-2024:

Bagaimana untuk mencapai kesan segmentasi dengan sempadan lengkung 45 darjah? Bagaimana untuk mencapai kesan segmentasi dengan sempadan lengkung 45 darjah? Apr 04, 2025 pm 11:48 PM

Petua untuk melaksanakan kesan segmen dalam reka bentuk antara muka pengguna, Segmenter adalah elemen navigasi biasa, terutamanya dalam aplikasi mudah alih dan laman web responsif. …

Bagaimana untuk bersesuaian dengan peninggalan limpahan multi-line pada terminal mudah alih? Bagaimana untuk bersesuaian dengan peninggalan limpahan multi-line pada terminal mudah alih? Apr 05, 2025 pm 10:36 PM

Isu keserasian limpahan berbilang baris pada terminal mudah alih yang ditinggalkan pada peranti yang berbeza apabila membangunkan aplikasi mudah alih menggunakan Vue 2.0, anda sering menghadapi keperluan untuk melimpah teks ...

See all articles