如何使用Python創(chuàng)建自己的文檔掃描儀
介紹
對(duì)這個(gè)項(xiàng)目的動(dòng)機(jī)很簡單。我們中的許多人轉(zhuǎn)向了在線工作。隨著在線工作量的增加,人們通常不得不通過電子郵件或其他方式呈現(xiàn)文檔的數(shù)字化版本。換句話說,將任何文檔轉(zhuǎn)換為掃描文檔。本文,將介紹如何使用 Python 從頭開始創(chuàng)建文檔掃描儀。準(zhǔn)確地說,是用于圖像/視頻處理的 OpenCV 庫。事不宜遲,讓我們開始吧。文件掃描儀在進(jìn)入編碼部分之前,我們需要了解我們將要做什么。這是在開始這個(gè)項(xiàng)目之前問自己的一系列問題。我們想在這里建造什么?
— 文件掃描儀。好的。但它做什么或應(yīng)該做什么?— 顯然,要掃描文檔。正確的。那么,掃描出來的文件應(yīng)該是什么樣子的呢?— 好問題,對(duì)吧?具體來看,掃描的文檔應(yīng)該有兩個(gè)特點(diǎn):看起來像掃描的文檔,黑白 (B&W) 顏色;正確旋轉(zhuǎn)(無隨機(jī)角度)。讓我們先從簡單的功能開始,并根據(jù)需要增加其他功能。編碼文件掃描儀首先讓我們導(dǎo)入這個(gè)項(xiàng)目需要的所有庫(我們可能會(huì)根據(jù)需要添加一些東西)import numpy as np
import cv2
from skimage.filters import threshold_local
import math
from scipy import ndimage
print("Imports are Done!")
I. 第一個(gè)屬性:掃描(黑白)視圖讓我們從掃描儀的第一個(gè)屬性開始——生成掃描圖像!在這個(gè)例子中,我使用了一張照片,來自Yuval Noah Harari的書*“21 Lessons for the 21st Century*。
旁注:它是一本很棒的書。本系列的其他兩本書(“Sapiens: A Brief History of Humankind”和“Homo Deus: A Brief History of Tomorrow”)都建議閱讀!回到我們的文檔掃描儀,我們希望通過更改配色方案使該圖像看起來清晰明快。讓我們將此操作稱為 Scan_view()。為了使它成為一個(gè)完整的應(yīng)用程序項(xiàng)目,讓我們創(chuàng)建一個(gè)名為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)建一個(gè)scan具有圖像作為其屬性的對(duì)象。因此,self.img = img在__init__()方法中使用;另外,想要一種負(fù)責(zé)更改此屬性(即圖像/文檔)的方法——更改配色方案、旋轉(zhuǎn)、裁剪、調(diào)整大小等。因此Scan_View()對(duì)它的類屬性(即,對(duì)它自己或self)執(zhí)行操作。這個(gè)方法的實(shí)質(zhì)隱藏在threshold_local操作中。這基本上是一種基于像素的局部鄰域計(jì)算閾值掩碼的操作。這也稱為自適應(yīng)閾值。閾值是像素的局部鄰域的加權(quán)平均值減去常數(shù)。找到閾值掩碼后,我們只需將前景像素值選擇為image>threshold。我們可以保存新的清晰新鮮的圖像并返回以備進(jìn)一步處理。要運(yùn)行代碼,我們可以簡單地創(chuàng)建一個(gè)scan對(duì)象并為其提供文檔/照片作為其屬性,如下所示:
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ù)進(jìn)行項(xiàng)目的下一部分。II. 第二個(gè)屬性:文檔輪換讓我們繼續(xù)我們的掃描儀的第二個(gè)屬性——文檔旋轉(zhuǎn)!假設(shè),我們以隨機(jī)角度拍攝了一本書的照片。自動(dòng)旋轉(zhuǎn)它以獲得自上而下的正面視圖不是很好嗎?當(dāng)然會(huì)!問題是怎么做?最初,我們正在考慮使用主成分分析 (PCA) 來確定文檔方向。然而,對(duì)于這個(gè)項(xiàng)目來說,這似乎有點(diǎn)過分了。我們想要一些簡單但有效的東西。會(huì)自動(dòng)確定文本/邊框線和水平線之間的旋轉(zhuǎn)角度的東西。因此,想出了一個(gè)更簡單的方法,它基本上利用了霍夫變換。簡而言之,霍夫變換是一種用于檢測各種形狀的技術(shù)。在我們的例子中,這將是一組沿著文本行的行!好主意,對(duì)吧?但是為了使這種方法健壯,我們需要確保檢測到正確的方向。一些線條可能沿著文本出現(xiàn),但其他線條沿著書籍/文檔邊緣出現(xiàn)——我們不希望那樣。所以,我們想要平均這些變化。換句話說,要找到所有線角的中值。因此,我們將掃描對(duì)象(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)用程序的重點(diǎn)是找到正確的霍夫線(HoughLinesP()方法,其中P代表概率,請(qǐng)參閱參考資料以了解有關(guān)此方法的更多信息)我們從每條線獲得角度的中值并將其用于文檔旋轉(zhuǎn)(ndimage.rotate()方法)。我們可以對(duì)清晰的黑白圖像執(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é)果,我們得到了一個(gè)旋轉(zhuǎn)的圖像:
精彩的掃描、清晰和旋轉(zhuǎn)的圖像!完整代碼對(duì)于感興趣的讀者,這里是一個(gè)GitHub 存儲(chǔ)庫,其中包含每種方法的更多詳細(xì)信息和文檔。h概括在本文中,我們學(xué)習(xí)了如何使用著名的用于圖像/視頻處理的 Python 庫 OpenCV 從頭開始構(gòu)建文檔掃描儀的工作原型。未來發(fā)展將這個(gè)應(yīng)用程序稱為文檔掃描儀 (v.1), 因?yàn)橛幸恍┛梢赃M(jìn)一步改進(jìn)它的地方。1.例如,使用另一種(或改進(jìn)的)算法進(jìn)行文檔輪換。由于其性質(zhì),該算法可能并不總是在 100% 的情況下提供完美的俯視圖。一種替代方法可能是使用主成分分析(或 PCA)來確定文檔的更精確方向。但這超出了本文的范圍。2.關(guān)于旋轉(zhuǎn)本身,我不喜歡旋轉(zhuǎn)圖像上的那些空黑塊。這也可以解決以改進(jìn)此應(yīng)用程序?赡苁鞘顾鼈?yōu)榭?( NaN) 值。3.另一個(gè)可能需要仔細(xì)檢查的操作是黑白顏色轉(zhuǎn)換。我認(rèn)為自適應(yīng)閾值是一個(gè)不錯(cuò)的選擇,但是,可能有更好的方法。
發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長度6~500個(gè)字
最新活動(dòng)更多
-
即日-11.13立即報(bào)名>>> 【在線會(huì)議】多物理場仿真助跑新能源汽車
-
11月28日立即報(bào)名>>> 2024工程師系列—工業(yè)電子技術(shù)在線會(huì)議
-
12月19日立即報(bào)名>> 【線下會(huì)議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會(huì)
-
即日-12.26火熱報(bào)名中>> OFweek2024中國智造CIO在線峰會(huì)
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍(lán)皮書》
-
精彩回顧立即查看>> 【限時(shí)免費(fèi)下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
推薦專題
- 1 【一周車話】沒有方向盤和踏板的車,你敢坐嗎?
- 2 特斯拉發(fā)布無人駕駛車,還未迎來“Chatgpt時(shí)刻”
- 3 特斯拉股價(jià)大跌15%:Robotaxi離落地還差一個(gè)蘿卜快跑
- 4 馬斯克給的“驚喜”夠嗎?
- 5 打完“價(jià)格戰(zhàn)”,大模型還要比什么?
- 6 馬斯克致敬“國產(chǎn)蘿卜”?
- 7 神經(jīng)網(wǎng)絡(luò),誰是盈利最強(qiáng)企業(yè)?
- 8 比蘋果偉大100倍!真正改寫人類歷史的智能產(chǎn)品降臨
- 9 諾獎(jiǎng)進(jìn)入“AI時(shí)代”,人類何去何從?
- 10 Open AI融資后成萬億獨(dú)角獸,AI人才之爭開啟
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市