如何使用Python創(chuàng)建自己的文檔掃描儀
介紹
對這個項目的動機很簡單。我們中的許多人轉(zhuǎn)向了在線工作。隨著在線工作量的增加,人們通常不得不通過電子郵件或其他方式呈現(xiàn)文檔的數(shù)字化版本。換句話說,將任何文檔轉(zhuǎn)換為掃描文檔。本文,將介紹如何使用 Python 從頭開始創(chuàng)建文檔掃描儀。準確地說,是用于圖像/視頻處理的 OpenCV 庫。事不宜遲,讓我們開始吧。文件掃描儀在進入編碼部分之前,我們需要了解我們將要做什么。這是在開始這個項目之前問自己的一系列問題。我們想在這里建造什么?
— 文件掃描儀。好的。但它做什么或應(yīng)該做什么?— 顯然,要掃描文檔。正確的。那么,掃描出來的文件應(yīng)該是什么樣子的呢?— 好問題,對吧?具體來看,掃描的文檔應(yīng)該有兩個特點:看起來像掃描的文檔,黑白 (B&W) 顏色;正確旋轉(zhuǎn)(無隨機角度)。讓我們先從簡單的功能開始,并根據(jù)需要增加其他功能。編碼文件掃描儀首先讓我們導入這個項目需要的所有庫(我們可能會根據(jù)需要添加一些東西)import numpy as np
import cv2
from skimage.filters import threshold_local
import math
from scipy import ndimage
print("Imports are Done!")
I. 第一個屬性:掃描(黑白)視圖讓我們從掃描儀的第一個屬性開始——生成掃描圖像!在這個例子中,我使用了一張照片,來自Yuval Noah Harari的書*“21 Lessons for the 21st Century*。
旁注:它是一本很棒的書。本系列的其他兩本書(“Sapiens: A Brief History of Humankind”和“Homo Deus: A Brief History of Tomorrow”)都建議閱讀!回到我們的文檔掃描儀,我們希望通過更改配色方案使該圖像看起來清晰明快。讓我們將此操作稱為 Scan_view()。為了使它成為一個完整的應(yīng)用程序項目,讓我們創(chuàng)建一個名為Scanner的類,其中Scan_view() 將是其方法。class Scanner:
def __init__(self, img):
self.img = img
def Scan_View(self):
print("Scanned View")
# read the original image, copy it,
# apply threshold to "scannify" it
image = cv2.imread(self.img)
orig = image.copy()
# convert our image to grayscale, apply threshold
# to create scanned view effect
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thr = threshold_local(image, 11, offset = 10, method = "gaussian")
image = (image > thr).a(chǎn)stype("uint8") * 255
# show the original image and the edge detected image
#cv2.imshow("orig", orig)
#cv2.imshow("Scanned", image)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
print(np.shape(orig), np.shape(image))
# Saving a B&W image itself
cv2.imwrite('Part_scan_view.png', image)
return image
代碼的快速解釋:創(chuàng)建一個scan具有圖像作為其屬性的對象。因此,self.img = img在__init__()方法中使用;另外,想要一種負責更改此屬性(即圖像/文檔)的方法——更改配色方案、旋轉(zhuǎn)、裁剪、調(diào)整大小等。因此Scan_View()對它的類屬性(即,對它自己或self)執(zhí)行操作。這個方法的實質(zhì)隱藏在threshold_local操作中。這基本上是一種基于像素的局部鄰域計算閾值掩碼的操作。這也稱為自適應(yīng)閾值。閾值是像素的局部鄰域的加權(quán)平均值減去常數(shù)。找到閾值掩碼后,我們只需將前景像素值選擇為image>threshold。我們可以保存新的清晰新鮮的圖像并返回以備進一步處理。要運行代碼,我們可以簡單地創(chuàng)建一個scan對象并為其提供文檔/照片作為其屬性,如下所示:
if __name__=="__main__":
# Defining the image name
img = "21_Lesson_21th_Century.jpeg"
# Calling the scanner class
scan = Scanner(img)
# Scanning the image -> B&W scheme
scanned_im = scan.Scan_View()
結(jié)果,我們得到了這張圖片:
上述文件的掃描版本。讓我們繼續(xù)進行項目的下一部分。II. 第二個屬性:文檔輪換讓我們繼續(xù)我們的掃描儀的第二個屬性——文檔旋轉(zhuǎn)!假設(shè),我們以隨機角度拍攝了一本書的照片。自動旋轉(zhuǎn)它以獲得自上而下的正面視圖不是很好嗎?當然會!問題是怎么做?最初,我們正在考慮使用主成分分析 (PCA) 來確定文檔方向。然而,對于這個項目來說,這似乎有點過分了。我們想要一些簡單但有效的東西。會自動確定文本/邊框線和水平線之間的旋轉(zhuǎn)角度的東西。因此,想出了一個更簡單的方法,它基本上利用了霍夫變換。簡而言之,霍夫變換是一種用于檢測各種形狀的技術(shù)。在我們的例子中,這將是一組沿著文本行的行!好主意,對吧?但是為了使這種方法健壯,我們需要確保檢測到正確的方向。一些線條可能沿著文本出現(xiàn),但其他線條沿著書籍/文檔邊緣出現(xiàn)——我們不希望那樣。所以,我們想要平均這些變化。換句話說,要找到所有線角的中值。因此,我們將掃描對象(Rotation())的新方法定義如下:class Scanner:
def __init__(self, img):
self.img = img
def Rotation(self):
print("Rotation")
# read the original image, copy it,
# rotate it
image = cv2.imread(self.img)
orig = image.copy()
image = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
img_edges = cv2.Canny(image, 100, 100, apertureSize=3)
lines = cv2.HoughLinesP(img_edges, rho=1, theta=np.pi / 180.0, threshold=160, minLineLength=100, maxLineGap=10)
# calculate all the angles:
angles = []
for [[x1, y1, x2, y2]] in lines:
angle = math.degrees(math.a(chǎn)tan2(y2 - y1, x2 - x1))
angles.a(chǎn)ppend(angle)
# average angles
median_angle = np.median(angles)
# actual rotation
image = ndimage.rotate(image, median_angle)
# Saving an image itself
cv2.imwrite('Part_rotation.png', image)
return image
如上所述,這部分應(yīng)用程序的重點是找到正確的霍夫線(HoughLinesP()方法,其中P代表概率,請參閱參考資料以了解有關(guān)此方法的更多信息)我們從每條線獲得角度的中值并將其用于文檔旋轉(zhuǎn)(ndimage.rotate()方法)。我們可以對清晰的黑白圖像執(zhí)行此操作,如下所示:if __name__=="__main__":
# Defining the image name
img = "Part_scan_view.png"
# Calling the scanner class
scan = Scanner(img)
# Performing Rotation
rotated_im = scan.Rotation()
結(jié)果,我們得到了一個旋轉(zhuǎn)的圖像:
精彩的掃描、清晰和旋轉(zhuǎn)的圖像!完整代碼對于感興趣的讀者,這里是一個GitHub 存儲庫,其中包含每種方法的更多詳細信息和文檔。h概括在本文中,我們學習了如何使用著名的用于圖像/視頻處理的 Python 庫 OpenCV 從頭開始構(gòu)建文檔掃描儀的工作原型。未來發(fā)展將這個應(yīng)用程序稱為文檔掃描儀 (v.1), 因為有一些可以進一步改進它的地方。1.例如,使用另一種(或改進的)算法進行文檔輪換。由于其性質(zhì),該算法可能并不總是在 100% 的情況下提供完美的俯視圖。一種替代方法可能是使用主成分分析(或 PCA)來確定文檔的更精確方向。但這超出了本文的范圍。2.關(guān)于旋轉(zhuǎn)本身,我不喜歡旋轉(zhuǎn)圖像上的那些空黑塊。這也可以解決以改進此應(yīng)用程序?赡苁鞘顾鼈?yōu)榭?( NaN) 值。3.另一個可能需要仔細檢查的操作是黑白顏色轉(zhuǎn)換。我認為自適應(yīng)閾值是一個不錯的選擇,但是,可能有更好的方法。

請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
推薦專題
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達AI統(tǒng)治的開始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 4 “AI寒武紀”爆發(fā)至今,五類新物種登上歷史舞臺
- 5 國產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計算迎來商業(yè)化突破,但落地仍需時間
- 7 東陽光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開成長空間
- 8 地平線自動駕駛方案解讀
- 9 封殺AI“照騙”,“淘寶們”終于不忍了?
- 10 優(yōu)必選:營收大增主靠小件,虧損繼續(xù)又逢關(guān)稅,能否乘機器人東風翻身?