ייתכן שתרצה לבצע דיגיטציה של מסמך כדי לחסוך בשטח פיזי או ליצור גיבוי לשמירה. כך או כך, כתיבת תוכנה שיכולה להמיר תמונות של קבצי הנייר שלך לפורמט סטנדרטי היא משימה ש-Python מצטיינת בה.
באמצעות שילוב של ספריות מתאימות, אתה יכול לבנות אפליקציה קטנה לדיגיטציה של מסמכים. התוכנית שלך תיקח תמונה של מסמך פיזי כקלט, תחיל עליו מספר טכניקות עיבוד תמונה ותוציא גרסה סרוקה של הקלט.
הכנת הסביבה שלך
כדי לעקוב אחר מאמר זה כדאי להכיר את יסודות פייתון. אתה צריך גם להבין כיצד לעבוד עם ספריית NumPy Python.
פתח כל Python IDE וצור שני קבצי Python. שם אחד main.py והשני transform.py. לאחר מכן הפעל את הפקודה הבאה בטרמינל כדי להתקין את הספריות הנדרשות.
pip התקנת OpenCV-Python imutils scikit-image NumPy
אתה תשתמש ב-OpenCV-Python כדי לקחת את קלט התמונה ולבצע קצת עיבוד תמונה. Imutils כדי לשנות את גודל תמונות הקלט והפלט. scikit-image כדי להחיל סף על התמונה. NumPy יעזור לך לעבוד עם מערכים.
המתן עד שההתקנה תסתיים וה-IDE יעדכן את שלדי הפרויקט. לאחר השלמת עדכון השלדים, אתה מוכן להתחיל בקידוד. קוד המקור המלא זמין ב-a
מאגר GitHub.ייבוא הספריות המותקנות
פתח את הקובץ main.py וייבא את הספריות שהתקנת בסביבה. זה יאפשר לך להתקשר ולהשתמש בפונקציות שלהם במידת הצורך.
יְבוּא cv2
יְבוּא אימוטילס
מ skimage.filters יְבוּא threshold_local
מ שינוי צורה יְבוּא פרספקטיבה_טרנספורמציה
התעלם מהשגיאה שנזרקה ב-perspective_transform. הוא ייעלם כשתסיים לעבוד על הקובץ transform.py.
קליטה ושינוי גודל הקלט
צלם תמונה ברורה של המסמך שברצונך לסרוק. ודא שארבע הפינות של המסמך והתוכן שלו גלויים. העתק את התמונה לאותה תיקייה שבה אתה מאחסן את קבצי התוכנית.
העבר את נתיב תמונת הקלט אל OpenCV. צור עותק של התמונה המקורית כפי שתזדקק לה במהלך שינוי הפרספקטיבה. חלקו את גובה התמונה המקורית בגובה שאליו תרצו לשנות את גודלה. זה ישמור על יחס הגובה-רוחב. לבסוף, פלט את התמונה ששונתה.
# עוברים את נתיב התמונה
original_img = cv2.imread('sample.jpg')
copy = original_img.copy()# הגובה שונה במאות
ratio = original_img.shape[0] / 500.0
img_resize = imutils.resize (original_img, height=500)# מציג פלט
cv2.imshow('שינוי גודל תמונה', img_resize)
# ממתין שהמשתמש ילחץ על מקש כלשהו
cv2.waitKey(0)
הפלט של הקוד לעיל הוא כדלקמן:
כעת שינית את גובה התמונה המקורית ל-500 פיקסלים.
המרת התמונה שגודלה שונה לגווני אפור
המר את תמונת ה-RGB ששונתה לגווני אפור. רוב ספריות עיבוד התמונות פועלות רק עם תמונות בגווני אפור מכיוון שהן קלות יותר לעיבוד.
grey_image = cv2.cvtColor (img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow('תמונה אפורה', תמונה_אפורה)
cv2.waitKey(0)
שימו לב להבדל בין התמונה המקורית לתמונה האפורה.
השולחן הצבעוני הפך לשחור ולבן.
החלת גלאי קצה
החל מסנן טשטוש גאוס על התמונה האפורה כדי להסיר רעש. לאחר מכן התקשר לפונקציה Canny OpenCV כדי לזהות את הקצוות הקיימים בתמונה.
blurred_image = cv2.GaussianBlur (תמונה_אפורה, (5, 5), 0)
edged_img = cv2.Canny (תמונה מטושטשת, 75, 200)
cv2.imshow('קצוות תמונה', edged_img)
cv2.waitKey(0)
הקצוות נראים על הפלט.
הקצוות שאיתם תעבדו הם אלו של המסמך.
מציאת קו המתאר הגדול ביותר
זהה את קווי המתאר הקיימים בתמונה הקצותית. מיין אותם בסדר יורד תוך שמירה על חמשת קווי המתאר הגדולים ביותר. הערך את קווי המתאר הגדול ביותר עם ארבעת הצדדים על ידי לולאה דרך קווי המתאר הממוינים.
cnts, _ = cv2.findContours (edged_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = מסודר (cnts, key=cv2.contourArea, reverse=נָכוֹן)[:5]ל ג ב cnts:
peri = cv2.arcLength (c, נָכוֹן)
approx = cv2.approxPolyDP(c, 0.02 *פרי, נָכוֹן)
אם לן (בערך) == 4:
doc = בערך
לשבור
קו המתאר עם ארבעת הצדדים עשוי להכיל את המסמך.
מקיף את ארבע הפינות של קו מתאר המסמך
הקף את הפינות של קו מתאר המסמך שזוהה. זה יעזור לך לקבוע אם התוכנית שלך הצליחה לזהות את המסמך בתמונה.
p = []
ל ד ב מסמך:
tuple_point = tuple (d[0])
cv2.circle (img_resize, tuple_point, 3, (0, 0, 255), 4)
p.append (tuple_point)
cv2.imshow('נקודות פינה מעוגלות', img_resize)
cv2.waitKey(0)
יישם מעגלים על תמונת RGB שגודלה שונה.
לאחר שזיהית את המסמך, כעת עליך לחלץ את המסמך מהתמונה.
שימוש בפרספקטיבה של עיוות כדי לקבל את התמונה הרצויה
פרספקטיבה עיוות היא טכניקת ראייה ממוחשבת להפיכת תמונה לתיקון עיוותים. זה הופך תמונה למישור אחר ומאפשר לך לצפות בתמונה מזווית אחרת.
warped_image = perspective_transform (העתק, doc.reshape(4, 2) * יחס)
warped_image = cv2.cvtColor (warped_image, cv2.COLOR_BGR2GRAY)
cv2.imshow("תמונה מעוותת", imutils.resize (warped_image, height=650))
cv2.waitKey(0)
כדי לקבל תמונה מעוותת, אתה צריך ליצור מודול פשוט שיבצע את שינוי הפרספקטיבה.
מודול טרנספורמציה
המודול יסדר את הנקודות של פינות המסמך. זה גם יהפוך את תמונת המסמך למישור אחר וישנה את זווית המצלמה לצילום עילי.
פתח את הקובץ transform.py שיצרת קודם לכן. ייבוא ספריות OpenCV ו- NumPy.
יְבוּא רדום כפי ש np
יְבוּא cv2
מודול זה יכיל שתי פונקציות. צור פונקציה שתסדר את הקואורדינטות של נקודות הפינה של המסמך. הקואורדינטה הראשונה תהיה זו של הפינה השמאלית העליונה, השנייה תהיה זו של הפינה הימנית העליונה, השלישית תהיה מהפינה הימנית התחתונה, והקואורדינטה הרביעית תהיה זו של הפינה השמאלית התחתונה פינה.
deforder_points(נקודות):
# אתחול רשימת הקואורדינטות להזמנה
rect = np.zeros((4, 2), dtype = "float32")s = pts.sum (ציר = 1)
# נקודה שמאלית עליונה תהיה הסכום הקטן ביותר
לתקן[0] = pts[np.argmin (s)]לנקודה אחת מימין למטה תהיה הסכום הגדול ביותר
לתקן[2] = נקודות[np.argmax (s)]חישוב ההפרש בין הנקודות, ה
לנקודה הימנית העליונה יהיה ההבדל הקטן ביותר,
ואילו לשמאל למטה יהיה ההבדל הגדול ביותר
diff = np.diff (נקודות, ציר = 1)
לתקן[1] = pts[np.argmin (diff)]
לתקן[3] = pts[np.argmax (diff)]
# מחזיר קואורדינטות מסודרות
לַחֲזוֹר לתקן
צור פונקציה שנייה שתחשב את קואורדינטות הפינות של התמונה החדשה ותשיג צילום מעל הראש. לאחר מכן הוא יחשב את מטריצת טרנספורמציה של הפרספקטיבה ויחזיר את התמונה המעוותת.
defפרספקטיבה_טרנספורמציה(תמונה, נקודות):
# פרק את הקואורדינטות המוזמנות בנפרד
rect = order_points (נקודות)
(tl, tr, br, bl) = rectלחשב את הרוחב של התמונה החדשה, שתהיה
מרחק מקסימלי בין ימין למטה ו שמאל תחתון
קואורדינטות x אוֹ הימני העליון ו קואורדינטות x משמאל למעלה
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max (int (widthA), int (widthB))לחשב את גובה התמונה החדשה, שתהיה
המרחק המרבי בין השמאלי העליון ו קואורדינטות y משמאל למטה
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max (int (heightA), int (heightB))לבנות את קבוצת נקודות היעד כדי להשיג זריקה מעל הראש
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, גובה מקסימלי - 1],
[0, גובה מקסימלי - 1]], dtype = "float32")# חשב את מטריצת טרנספורמציה של הפרספקטיבה
transform_matrix = cv2.getPerspectiveTransform (רect, dst)# החל את מטריצת ההמרה
warped = cv2.warpPerspective (תמונה, transform_matrix, (maxWidth, maxHeight))
# החזר את התמונה המעוותת
לַחֲזוֹר מעוות
כעת יצרת את מודול הטרנספורמציה. השגיאה ביבוא perspective_transform תיעלם כעת.
שימו לב שלתמונה המוצגת יש צילום מעל.
החלת סף מסתגל ושמירת הפלט הסרוק
בקובץ main.py, החל את הסף גאוסי על התמונה המעוותת. זה ייתן לתמונה המעוותת מראה סרוק. שמור את פלט התמונה הסרוקה בתיקייה המכילה את קבצי התוכנית.
T = threshold_local (תמונה_מעוותת, 11, offset=10, שיטה="גאוסי")
עיוות = (תמונה_מעוותת > T).astype("uint8") * 255
cv2.imwrite('./'+'לִסְרוֹק'+'.png', מעוות)
שמירת הסריקה בפורמט PNG שומרת על איכות המסמך.
הצגת הפלט
פלט את תמונת המסמך הסרוק:
cv2.imshow("תמונה סרוקה סופית", imutils.resize (עיוות, גובה=650))
cv2.waitKey(0)
cv2.destroyAllWindows()
התמונה הבאה מציגה את הפלט של התוכנית, צילום תקורה של המסמך הסרוק.
כיצד להתקדם בראיית מחשב
יצירת סורק מסמכים מכסה כמה תחומי ליבה של ראיית מחשב, שהיא תחום רחב ומורכב. כדי להתקדם בראייה ממוחשבת כדאי לעבוד על פרויקטים מעניינים אך מאתגרים.
כדאי גם לקרוא עוד על איך אתה יכול להשתמש בראייה ממוחשבת עם הטכנולוגיות העדכניות. זה ישאיר אותך מעודכן וייתן לך רעיונות חדשים לפרויקטים לעבוד עליהם.