cari
Rumahpembangunan bahagian belakangTutorial PythonOpenCV: Cari lajur dalam jurnal Arab (Python)

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")

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

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

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")

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")

Mempunyai pakej berikut:

import cv2
import numpy as np
%matplotlib notebook
import matplotlib.pyplot as plt
from imutils.perspective import four_point_transform

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
Artikel ini dikembalikan pada:stackoverflow. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Apakah sebab -sebab umum mengapa skrip python mungkin tidak dilaksanakan pada UNIX?Apakah sebab -sebab umum mengapa skrip python mungkin tidak dilaksanakan pada UNIX?Apr 28, 2025 am 12:18 AM

Sebab -sebab mengapa skrip Python tidak dapat dijalankan pada sistem Unix termasuk: 1) kebenaran yang tidak mencukupi, menggunakan chmod xyour_script.py untuk memberikan kebenaran pelaksanaan; 2) garis shebang yang tidak betul atau hilang, anda harus menggunakan #!/Usr/bin/envpython; 3) tetapan pembolehubah persekitaran yang salah, anda boleh mencetak debugging os.environ; 4) Menggunakan versi Python yang salah, anda boleh menentukan versi pada garis Shebang atau baris arahan; 5) masalah pergantungan, menggunakan persekitaran maya untuk mengasingkan ketergantungan; 6) Kesalahan sintaks, gunakan python-mpy_compileyour_script.py untuk mengesan.

Berikan contoh senario di mana menggunakan array python akan lebih sesuai daripada menggunakan senarai.Berikan contoh senario di mana menggunakan array python akan lebih sesuai daripada menggunakan senarai.Apr 28, 2025 am 12:15 AM

Menggunakan tatasusunan python lebih sesuai untuk memproses sejumlah besar data berangka daripada senarai. 1) Array menjimatkan lebih banyak memori, 2) array lebih cepat untuk beroperasi dengan nilai berangka, 3) Arrays Force Jenis Konsistensi, 4) Array bersesuaian dengan array C, tetapi tidak fleksibel dan mudah seperti senarai.

Apakah implikasi prestasi menggunakan senarai berbanding tatasusunan dalam python?Apakah implikasi prestasi menggunakan senarai berbanding tatasusunan dalam python?Apr 28, 2025 am 12:10 AM

Listsare yang lebih baik lebih baik foreflexibilityandmixdatatatypes, whilearraysares sand sumerical sand sand sand lared datasets.1) Senarai yang tidak dapat diselaraskan xibility, mixeddatatypes, dan elementChanges.2) Operasi sensori UsArray, LargedataSet, dan WhenmememoryefficyFiciency.2

Bagaimanakah Numpy mengendalikan pengurusan memori untuk tatasusunan besar?Bagaimanakah Numpy mengendalikan pengurusan memori untuk tatasusunan besar?Apr 28, 2025 am 12:07 AM

NumpyManagesMemoryforlargeArraySefficientlyusingViews, salinan, danMemory-mappedfiles.1) viewSallowSlicingWithoutCopying, secara langsungModifyingTheoriginalArray.2) copiescanbecreatedwithTheCopy () methorpreserveservervesvesverdata.3) MemoriSberServervesvesves

Yang memerlukan mengimport modul: senarai atau tatasusunan?Yang memerlukan mengimport modul: senarai atau tatasusunan?Apr 28, 2025 am 12:06 AM

Listsinpythondonotrequireimportingamodule, whilearraysfromthearraymoduledoneedanimport.1) listsarebuilt-in, serba boleh, dancanholdmixeddatatypes.2) arraysaremorememory-efficientfornumericydatabuTabeSflexible, yang tidak dapat dilupakan.

Apakah jenis data yang boleh disimpan dalam array python?Apakah jenis data yang boleh disimpan dalam array python?Apr 27, 2025 am 12:11 AM

Pythonlistscanstoreanydatatype, arraymoduleArraysstoreonetype, andnumpyarraysarefornumumericalcomputations.1) listsareversatileButlessMememory-efficient.2) arraymoduleArduleArrayRaysarememory-efficientforhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogenhomogen

Apa yang berlaku jika anda cuba menyimpan nilai jenis data yang salah dalam array python?Apa yang berlaku jika anda cuba menyimpan nilai jenis data yang salah dalam array python?Apr 27, 2025 am 12:10 AM

KetikayyoUttemptToStoreAveFheWrongatatypeinapythonArray, anda akan menjadicounteratypeerror

Yang merupakan sebahagian daripada Perpustakaan Standard Python: Senarai atau Array?Yang merupakan sebahagian daripada Perpustakaan Standard Python: Senarai atau Array?Apr 27, 2025 am 12:03 AM

Pythonlistsarepartofthestandardlibrary, sementara

See all articles

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

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

SublimeText3 Linux versi baharu

SublimeText3 Linux versi baharu

SublimeText3 Linux versi terkini