Terlepas dari digitalisasi segala sesuatu dan semua orang, pada saat umat manusia hampir menciptakan antarmuka neuroin, ketika AI telah menjadi hal biasa, tugas klasik untuk mendapatkan data dari pemindaian / gambar masih relevan.
Selamat siang. Nama saya Aleksey. Saya bekerja sebagai programmer di sebuah perusahaan yang menjual peralatan. Saya memiliki praktik terbaik saya sendiri untuk mengenali dan memuat data ke dalam program akuntansi, dan hanya manajer yang memasukkan lusinan halaman dokumen pdf secara manual yang tidak dapat dengan mudah ditransfer ke EDF. Saya mengundang mereka untuk mencoba solusi saya.
Awalnya, ABBYY Cloud digunakan untuk pengenalan, tetapi tidak gratis, dan mode uji coba tidak cukup lama. Saya memutuskan untuk menulis API saya dengan python, di mana semua kekuatan tesseracta gratis digunakan. Masalahnya adalah bahwa tesseract adalah pengenalan teks, dan tidak mendefinisikan tabel, ternyata tidak banyak berguna. Sehari sebelum saya membaca artikel https://vc.ru/ml/139816-povyshenie-kachestva-raspoznavaniya-skanov-dokumentov-s-tablicami-s-pomoshchyu-vychisleniya-koordinat-yacheek, di mana semua sel tabel diperoleh menggunakan openCV, setiap sel dijalankan melalui tesseract dan dengan demikian data yang benar dapat diperoleh. Saya memutuskan untuk mencoba metode ini. Posting akan tentang apa yang terjadi.
Untuk pengujian, saya ambil dari basis demo 1c TORG-12. Formulir ini memiliki struktur yang agak rumit, banyak tabel, banyak teks, banyak data. Hanya yang Anda butuhkan.
pdf , gostscript . ImageMagick, - . cmd , gostscript .
, openCV , QR-. pyzbar.
, . , . , , . - .
clahe = cv2.createCLAHE(clipLimit=50, tileGridSize=(50, 50))
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
l2 = clahe.apply(l)
lab = cv2.merge((l2, a, b))
img2 = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 75, 255, cv2.THRESH_BINARY_INV )
kernel = np.ones((2, 2), np.uint8)
obr_img = cv2.erode(thresh, kernel, iterations=1)
obr_img = cv2.GaussianBlur(obr_img, (3,3), 0)
, . , . 5 , delta.
contours, hierarchy = cv2.findContours(obr_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_TC89_L1)
coordinates = []
ogr = round(max(img.shape[0], img.shape[1]) * 0.005)
delta = round(ogr/2 +0.5)
ind = 1;
for i in range(0, len(contours)):
l, t, w, h = cv2.boundingRect(contours[i])
if (h > ogr and w > ogr):
#
#
#
#
#
#
#
#
coordinates.append((0, ind, 0, l, t, w, h, ''))
ind = ind + 1
, . sqlite3 coordinates. . , hierarchy, , . .
, . - . , .
, , - . , , . . , , . , , , , , , .
2 :
. , . , . . , , , , . - . . , , . . . . / 2*. . , - , . .
. . 4 . , , "". "" , , . - , 4 , .
. . tesseract , 3 , . , "-". "-", "---00", . .
text1 = pytesseract.image_to_string(image[t1:t2,l1:l2], lang=lang, config='--psm 6')
text2 = pytesseract.image_to_string(image[t1:t2,l1:l2], lang=lang, config='')
text3 = pytesseract.image_to_string(image[t1+round(delta/2):t2-round(delta/2),l1+round(delta/2):l2-round(delta/2)], lang=lang, config='--psm 7')
text1 = text1.replace("\n", " ")
text2 = text2.replace("\n", " ")
text3 = text3.replace("\n", " ")
text1 = re.sub(' *[^ \(\)--\d\w\/\\\.\-,:; ]+ *', ' ', text1)
text2 = re.sub(' *[^ \(\)--\d\w\/\\\.\-,:; ]+ *', ' ', text2)
text3 = re.sub(' *[^ \(\)--\d\w\/\\\.\-,:; ]+ *', ' ', text3)
while text1.find(' ')!=-1:
text1 = text1.replace(' ',' ')
while text2.find(' ') != -1:
text2 = text2.replace(' ', ' ')
while text3.find(' ') != -1:
text3 = text3.replace(' ', ' ')
. , . , . , -, , , . , , . , , , . , , ? , 2 , . . , , , . , ; ; , . .
. . 4 . "". , , . .
, , . , . API JSON, 1 . , . . . 1 pdf 20 , . , Tesserocr Pytesseract, .
https://github.com/Trim891/API. PyCharm "", GitHub, *.py requirements.txt. , , , , , ; " , ", , , - ; , , 2 . .
PS Ada banyak komentar di file, banyak hal yang tidak perlu dan, secara umum, kode kotoran adalah kekacauan kreatif. Itu semua untuk penggunaan internal, tidak ada waktu untuk berdandan =)