如何使用Python創(chuàng)建自己的文檔掃描儀
介紹
對(duì)這個(gè)項(xiàng)目的動(dòng)機(jī)很簡(jiǎn)單。我們中的許多人轉(zhuǎn)向了在線工作。隨著在線工作量的增加,人們通常不得不通過(guò)電子郵件或其他方式呈現(xiàn)文檔的數(shù)字化版本。換句話說(shuō),將任何文檔轉(zhuǎn)換為掃描文檔。本文,將介紹如何使用 Python 從頭開(kāi)始創(chuàng)建文檔掃描儀。準(zhǔn)確地說(shuō),是用于圖像/視頻處理的 OpenCV 庫(kù)。事不宜遲,讓我們開(kāi)始吧。文件掃描儀在進(jìn)入編碼部分之前,我們需要了解我們將要做什么。這是在開(kāi)始這個(gè)項(xiàng)目之前問(wèn)自己的一系列問(wèn)題。我們想在這里建造什么?
— 文件掃描儀。好的。但它做什么或應(yīng)該做什么?— 顯然,要掃描文檔。正確的。那么,掃描出來(lái)的文件應(yīng)該是什么樣子的呢?— 好問(wèn)題,對(duì)吧?具體來(lái)看,掃描的文檔應(yīng)該有兩個(gè)特點(diǎn):看起來(lái)像掃描的文檔,黑白 (B&W) 顏色;正確旋轉(zhuǎn)(無(wú)隨機(jī)角度)。讓我們先從簡(jiǎn)單的功能開(kāi)始,并根據(jù)需要增加其他功能。編碼文件掃描儀首先讓我們導(dǎo)入這個(gè)項(xiàng)目需要的所有庫(kù)(我們可能會(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è)屬性開(kāi)始——生成掃描圖像!在這個(gè)例子中,我使用了一張照片,來(lái)自Yuval Noah Harari的書(shū)*“21 Lessons for the 21st Century*。
旁注:它是一本很棒的書(shū)。本系列的其他兩本書(shū)(“Sapiens: A Brief History of Humankind”和“Homo Deus: A Brief History of Tomorrow”)都建議閱讀!回到我們的文檔掃描儀,我們希望通過(guò)更改配色方案使該圖像看起來(lái)清晰明快。讓我們將此操作稱(chēng)為 Scan_view()。為了使它成為一個(gè)完整的應(yīng)用程序項(xiàng)目,讓我們創(chuàng)建一個(gè)名為Scanner的類(lèi),其中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ì)它的類(lèi)屬性(即,對(duì)它自己或self)執(zhí)行操作。這個(gè)方法的實(shí)質(zhì)隱藏在threshold_local操作中。這基本上是一種基于像素的局部鄰域計(jì)算閾值掩碼的操作。這也稱(chēng)為自適應(yīng)閾值。閾值是像素的局部鄰域的加權(quán)平均值減去常數(shù)。找到閾值掩碼后,我們只需將前景像素值選擇為image>threshold。我們可以保存新的清晰新鮮的圖像并返回以備進(jìn)一步處理。要運(yùn)行代碼,我們可以簡(jiǎ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ī)角度拍攝了一本書(shū)的照片。自動(dòng)旋轉(zhuǎn)它以獲得自上而下的正面視圖不是很好嗎?當(dāng)然會(huì)!問(wèn)題是怎么做?最初,我們正在考慮使用主成分分析 (PCA) 來(lái)確定文檔方向。然而,對(duì)于這個(gè)項(xiàng)目來(lái)說(shuō),這似乎有點(diǎn)過(guò)分了。我們想要一些簡(jiǎn)單但有效的東西。會(huì)自動(dòng)確定文本/邊框線和水平線之間的旋轉(zhuǎn)角度的東西。因此,想出了一個(gè)更簡(jiǎn)單的方法,它基本上利用了霍夫變換。簡(jiǎn)而言之,霍夫變換是一種用于檢測(cè)各種形狀的技術(shù)。在我們的例子中,這將是一組沿著文本行的行!好主意,對(duì)吧?但是為了使這種方法健壯,我們需要確保檢測(cè)到正確的方向。一些線條可能沿著文本出現(xiàn),但其他線條沿著書(shū)籍/文檔邊緣出現(xiàn)——我們不希望那樣。所以,我們想要平均這些變化。換句話說(shuō),要找到所有線角的中值。因此,我們將掃描對(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ǔ)庫(kù),其中包含每種方法的更多詳細(xì)信息和文檔。h概括在本文中,我們學(xué)習(xí)了如何使用著名的用于圖像/視頻處理的 Python 庫(kù) OpenCV 從頭開(kāi)始構(gòu)建文檔掃描儀的工作原型。未來(lái)發(fā)展將這個(gè)應(yīng)用程序稱(chēng)為文檔掃描儀 (v.1), 因?yàn)橛幸恍┛梢赃M(jìn)一步改進(jìn)它的地方。1.例如,使用另一種(或改進(jìn)的)算法進(jìn)行文檔輪換。由于其性質(zhì),該算法可能并不總是在 100% 的情況下提供完美的俯視圖。一種替代方法可能是使用主成分分析(或 PCA)來(lái)確定文檔的更精確方向。但這超出了本文的范圍。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)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
即日-12.26立即報(bào)名>>> 【在線會(huì)議】村田用于AR/VR設(shè)計(jì)開(kāi)發(fā)解決方案
-
1月8日火熱報(bào)名中>> Allegro助力汽車(chē)電氣化和底盤(pán)解決方案優(yōu)化在線研討會(huì)
-
即日-1.14火熱報(bào)名中>> OFweek2025中國(guó)智造CIO在線峰會(huì)
-
即日-1.24立即參與>>> 【限時(shí)免費(fèi)】安森美:Treo 平臺(tái)帶來(lái)出色的精密模擬
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍(lán)皮書(shū)》
-
精彩回顧立即查看>> 【線下會(huì)議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會(huì)
推薦專(zhuān)題
- 1 人形機(jī)器人核心零部件,誰(shuí)是盈利最強(qiáng)企業(yè)?
- 2 AI Agent現(xiàn)狀如何?聊聊近期國(guó)內(nèi)的智能體市場(chǎng)動(dòng)向
- 3 5nm重大突破,研祥智能助力半導(dǎo)體企業(yè)高效發(fā)展!
- 4 人形機(jī)器人引爆“PEEK材料”!概念股梳理(名單)
- 5 馬云沒(méi)回牌桌,但重注全壓在了
- 6 蘋(píng)果或?qū)渴肿止?jié)騰訊大模型,我國(guó)大模型產(chǎn)業(yè)發(fā)展駛?cè)肟燔?chē)道
- 7 豆包AI登頂國(guó)內(nèi)第一!概念股梳理(名單)
- 8 押注AI王者歸來(lái),歌爾股份“智能體”在下一盤(pán)“大棋”
- 9 AI超級(jí)應(yīng)用什么時(shí)候才能出現(xiàn)?
- 10 英偉達(dá)迎來(lái)當(dāng)頭一棒
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷(xiāo)售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷(xiāo)售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專(zhuān)家 廣東省/江門(mén)市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市