天天看點

c++在csv寫入漢字_python-opencv表格識别轉csv

最近學習了一下opencv,做了個簡單的小東西,就是識别圖檔中的表格,識别完成後再把資料寫入到csv中儲存起來。

環境準備:

下面先說下我們應該要準備下啥環境:

1.python安裝完成(筆者python3.7)

2.tesseract(google的開源cr架構)

3.pytesseract(python對tesseract的封裝,調用時是通過pytesseract去調用tesseract)

4.python的一些類庫,numpy,matplotlib

5.特别提一下要導入opencv的包,安裝的時候名稱是opencv-python,使用的時候名稱是cv2,cv2不是說是opencv的版本二哦,意思是在cv的基礎上做了提升和優化的意思,跟版本沒關系。

這裡還有一點要注意的,使用cv2報錯的話,可能還要安裝一下opencv-python-headless。

識别步驟:

我們先來簡單說一下原理,是怎麼識别表格的呢?是這樣的,如果直接咱們把一張圖檔用tesseract去識别成中文,它會把表格的橫豎線都算進去,

很多漢字都識别不出來,效果也很難看。是以我們要做的前置步驟就是識别出excel圖檔的一個個單元格,把每個單元格中的資訊給識别出來,然後拼接

成一個csv,在最後轉為excel隻需要通過excel導入csv的資料就可以了。

注意事項:本人水準有限,目前還隻能處理比較簡單的方方正正的表格,下面的程式是可直接跑的。但是如果有一些圖檔的表格是拍出來斜着的,或有幹擾物

比如有支筆在圖檔中,或有很複雜的水印,這種目前還處理不了,還在繼續研究當中。有興趣的小夥伴可以一起玩啊,加個微信一起讨論交流。

不過咱們也對這些情況有一些方案,還在處理當中:

1.如果表格是傾斜的咱們可以使用透射變換先将表格處理成正常的矩形;

2.簡單的水印,可以通過灰階之後,選個合理的門檻值,将圖檔二值化後,白黑圖可以去掉水印。

這裡咱們安利一個很好的python-opencv的入門教程:ex2tron/OpenCV-Python-Tutorial

好了廢話說完了,開始教程:

原圖:

c++在csv寫入漢字_python-opencv表格識别轉csv

1.讀入圖檔灰階化:

可以了解為把彩色圖檔變為灰色圖檔

raw = cv2.imread(src, 1)
# 灰階圖檔
gray = cv2.cvtColor(raw, cv2.COLOR_BGR2GRAY)
           

2.圖檔二值化:

可以了解為把圖檔變成隻有黑白兩種顔色,這樣更友善處理,再說咱們處理表格也不需要顔色

binary = cv2.adaptiveThreshold(~gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 35, -5)
# 展示圖檔
cv2.imshow("binary_picture", binary)
           

二值化的圖檔:

c++在csv寫入漢字_python-opencv表格識别轉csv

3.識别出橫線,豎線:

在此之後,如果圖像不夠清晰或者有小像素點,可以使用腐蝕,膨脹等操作讓圖檔更清晰一點

rows, cols = binary.shape
scale = 40
# 自适應擷取核值
# 識别橫線:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (cols // scale, 1))
eroded = cv2.erode(binary, kernel, iterations=1)
dilated_col = cv2.dilate(eroded, kernel, iterations=1)
cv2.imshow("excel_horizontal_line", dilated_col)

# 識别豎線:
scale = 20
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, rows // scale))
eroded = cv2.erode(binary, kernel, iterations=1)
dilated_row = cv2.dilate(eroded, kernel, iterations=1)
cv2.imshow("excel_vertical_line:", dilated_row)
           

橫線豎線的圖:

c++在csv寫入漢字_python-opencv表格識别轉csv
c++在csv寫入漢字_python-opencv表格識别轉csv

4.計算出橫豎線的焦點,就得到了每個單元格的坐标

# 将識别出來的橫豎線合起來
bitwise_and = cv2.bitwise_and(dilated_col, dilated_row)
cv2.imshow("excel_bitwise_and", bitwise_and)

# 辨別表格輪廓
merge = cv2.add(dilated_col, dilated_row)
cv2.imshow("entire_excel_contour:", merge)

# 兩張圖檔進行減法運算,去掉表格框線
merge2 = cv2.subtract(binary, merge)
cv2.imshow("binary_sub_excel_rect", merge2)

new_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
erode_image = cv2.morphologyEx(merge2, cv2.MORPH_OPEN, new_kernel)
cv2.imshow('erode_image2', erode_image)
merge3 = cv2.add(erode_image, bitwise_and)
cv2.imshow('merge3', merge3)

# 将焦點辨別取出來
ys, xs = np.where(bitwise_and > 0)
           

焦點圖:

c++在csv寫入漢字_python-opencv表格識别轉csv

5.将坐标篩選下,臨近的幾個算一個:

這裡說一下圖檔的數組中是(y,x)這樣的,y在前面

# 橫縱坐标數組
           

6.通過坐标把每個單元格圖像取出來,然後使用pytesseract識别文字 :去除特殊符号後,data就是處理好的值

# 循環y坐标,x坐标分割表格
data = [[] for i in range(len(y_point_arr))]
for i in range(len(y_point_arr) - 1):
    for j in range(len(x_point_arr) - 1):
        # 在分割時,第一個參數為y坐标,第二個參數為x坐标
        cell = src[y_point_arr[i]:y_point_arr[i + 1], x_point_arr[j]:x_point_arr[j + 1]]
        cv2.imshow("sub_pic" + str(i) + str(j), cell)

        # 讀取文字,此為預設英文
        # pytesseract.pytesseract.tesseract_cmd = 'E:/Tesseract-OCR/tesseract.exe'
        text1 = pytesseract.image_to_string(cell, )

        # 去除特殊字元
        text1 = re.findall(r'[^*"/:?|<>″′‖ 〈n]', text1, re.S)
        text1 = "".join(text1)
        print('單元格圖檔資訊:' + text1)
        data[i].append(text1)
        j = j + 1
    i = i + 1
           

6.最後把所有的資訊寫入csv

path是要寫入的檔案路徑,data是資料

with open(path, "w", newline='') as csv_file:
      writer = csv.writer(file, dialect='excel')
      for index, item in enumerate(data):
          if index != 0 and index != len(data) - 1:
              writer.writerows([[item[0], item[1], item[2], item[3], item[4], item[5]]])
           

寫入表格資料:

c++在csv寫入漢字_python-opencv表格識别轉csv

總結:

1.完成之後就大緻知道了表格識别的原理,并且對opencv的api有了一定的了解和熟悉,這裡放上github的位址:wxwwt/opencv-picture-to-excel,覺得還可以點點star,fork啥的哈。

2.不過這個介紹是說完了大緻流程,其實過程中還有遇到很多坑,直接運作github的項目有可能跑出的結果和我不一樣,

那是因為一個是要下載下傳tesseract的中文資料集,第二是這個裡面數學和幾個文字竟然識别不出來,需要手動給tesseract增加

一些訓練集。這個增加訓練資料集應該後面會再出一篇文章。

3.弄完這個表格識别,準備在看下圖檔矯正和去除水印,複雜的表格識别也會使用到的。

參考資料:

1.tesseract-ocr/tesseract

2.pytesseract

3.CSDN-專業IT技術社群-登入

4.基于圖像識别的表格資料提取系統 - 秋沐霖 - 部落格園

繼續閱讀