خبر و ترفند روز

خبر و ترفند های روز را اینجا بخوانید!

نحوه ایجاد یک اسکنر سند با استفاده از پایتون

از اسناد مهم پشتیبان تهیه کنید و در این فرآیند کمی در مورد بینایی کامپیوتری بیاموزید.

ممکن است بخواهید یک سند را دیجیتالی کنید تا فضای فیزیکی ذخیره شود یا یک نسخه پشتیبان ذخیره کنید. در هر صورت، نوشتن برنامه‌ای که بتواند عکس‌های فایل‌های کاغذی شما را به فرمت استاندارد تبدیل کند، کاری است که پایتون در آن برتری دارد.

با استفاده از ترکیبی از کتابخانه های مناسب، می توانید یک برنامه کوچک برای دیجیتالی کردن اسناد بسازید. برنامه شما تصویری از یک سند فیزیکی به عنوان ورودی می گیرد، چندین تکنیک پردازش تصویر را روی آن اعمال می کند و یک نسخه اسکن شده از ورودی را خروجی می دهد.

آماده کردن محیط

برای دنبال کردن این مقاله باید با اصول پایتون آشنا باشید. همچنین باید درک درستی از نحوه کار با کتابخانه NumPy Python داشته باشید.

هر IDE پایتون را باز کنید و دو فایل پایتون ایجاد کنید. یکی main.py و دیگری transform.py را نام ببرید. سپس دستور زیر را در ترمینال اجرا کنید تا کتابخانه های مورد نیاز نصب شوند.

pip install OpenCV-Python imutils scikit-image NumPy

شما از OpenCV-Python برای گرفتن ورودی تصویر و انجام برخی پردازش های تصویری استفاده خواهید کرد. Imutils برای تغییر اندازه تصاویر ورودی و خروجی. scikit-image برای اعمال آستانه بر روی تصویر. NumPy به شما کمک می کند تا با آرایه ها کار کنید.

نصب کتابخانه های پایتون در ترمینال

منتظر بمانید تا نصب به پایان برسد و IDE اسکلت های پروژه را به روز کند. پس از تکمیل به‌روزرسانی اسکلت‌ها، آماده شروع کدنویسی هستید. کد منبع کامل در یک مخزن GitHub موجود است.

واردات کتابخانه های نصب شده

فایل main.py را باز کنید و کتابخانه هایی را که نصب کرده اید در محیط وارد کنید. این به شما امکان می دهد در صورت لزوم تماس بگیرید و از عملکردهای آنها استفاده کنید.

import cv2
import imutils
from skimage.filters import threshold_local
from transform import perspective_transform

خطای پرتاب شده در view_transform را نادیده بگیرید. هنگامی که کار بر روی فایل transform.py را تمام کردید ناپدید می شود.

گرفتن و تغییر اندازه ورودی

یک تصویر واضح از سندی که می خواهید اسکن کنید بگیرید. اطمینان حاصل کنید که چهار گوشه سند و محتوای آن قابل مشاهده است. تصویر را در همان پوشه ای که فایل های برنامه را ذخیره می کنید کپی کنید.

مطلب مرتبط:   آیا میزبانی جانگو در PythonAnywhere ایده خوبی است؟

تصویر یک سند روی میز

مسیر تصویر ورودی را به OpenCV منتقل کنید. یک کپی از تصویر اصلی تهیه کنید زیرا در طول تبدیل پرسپکتیو به آن نیاز دارید. ارتفاع تصویر اصلی را بر ارتفاعی که می خواهید اندازه آن را تغییر دهید تقسیم کنید. این نسبت تصویر را حفظ می کند. در نهایت تصویر تغییر اندازه را خروجی بگیرید.

# Passing the image path
original_img = cv2.imread('sample.jpg')
copy = original_img.copy()

# The resized height in hundreds
ratio = original_img.shape[0] / 500.0
img_resize = imutils.resize(original_img, height=500)

# Displaying output
cv2.imshow('Resized image', img_resize)

# Waiting for the user to press any key
cv2.waitKey(0)

خروجی کد بالا به صورت زیر است:

خروجی یک برنامه در یک IDE که یک تصویر برش خورده را نشان می دهد

اکنون اندازه ارتفاع تصویر اصلی را به 500 پیکسل تغییر داده اید.

تبدیل تصویر تغییر سایز به Grayscale

تغییر اندازه تصویر RGB را به مقیاس خاکستری تبدیل کنید. اکثر کتابخانه های پردازش تصویر فقط با تصاویر در مقیاس خاکستری کار می کنند زیرا پردازش آنها آسان تر است.

gray_image = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow('Grayed Image', gray_image)
cv2.waitKey(0)

به تفاوت بین تصویر اصلی و تصویر خاکستری توجه کنید.

خروجی یک برنامه در یک IDE که یک تصویر خاکستری را نشان می دهد

میز رنگی سیاه و سفید شده است.

استفاده از ردیاب لبه

برای حذف نویز، یک فیلتر گاوسی تاری روی تصویر خاکستری اعمال کنید. سپس تابع OpenCV canny را برای تشخیص لبه های موجود در تصویر فراخوانی کنید.

blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 0)
edged_img = cv2.Canny(blurred_image, 75, 200)
cv2.imshow('Image edges', edged_img)
cv2.waitKey(0)

لبه ها در خروجی قابل مشاهده است.

خروجی یک برنامه در یک IDE که لبه های شناسایی شده روی تصویر را نشان می دهد

لبه هایی که با آنها کار خواهید کرد لبه های سند هستند.

پیدا کردن بزرگترین کانتور

خطوط موجود در تصویر لبه را تشخیص دهید. آنها را به ترتیب نزولی مرتب کنید و فقط پنج امتداد بزرگ را حفظ کنید. با حلقه زدن خطوط مرتب شده، بزرگ ترین کانتور را با چهار طرف تقریب بزنید.

cnts, _ = cv2.findContours(edged_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:5]

for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)

    if len(approx) == 4:
        doc = approx
        break

کانتور با چهار طرف احتمالاً حاوی سند است.

دور چهار گوشه کانتور سند

گوشه های کانتور سند شناسایی شده را دور بزنید. این به شما کمک می کند تا تعیین کنید که آیا برنامه شما قادر به تشخیص سند در تصویر است یا خیر.

p = []

for d in doc:
    tuple_point = tuple(d[0])
    cv2.circle(img_resize, tuple_point, 3, (0, 0, 255), 4)
    p.append(tuple_point)

cv2.imshow('Circled corner points', img_resize)
cv2.waitKey(0)

چرخش را روی تصویر RGB تغییر اندازه اعمال کنید.

مطلب مرتبط:   نحوه نصب پایتون در مک و اجرای اولین اسکریپت

خروجی یک برنامه در یک IDE که سندی را با گوشه های دایره ای نشان می دهد

پس از شناسایی سند، اکنون باید سند را از تصویر استخراج کنید.

استفاده از Warp Perspective برای دریافت تصویر مورد نظر

پرسپکتیو Warp یک تکنیک بینایی کامپیوتری برای تبدیل تصویر به منظور اصلاح اعوجاج است. این یک تصویر را به یک صفحه متفاوت تبدیل می کند و به شما امکان می دهد تصویر را از زاویه دیگری مشاهده کنید.

warped_image = perspective_transform(copy, doc.reshape(4, 2) * ratio)
warped_image = cv2.cvtColor(warped_image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Warped Image", imutils.resize(warped_image, height=650))
cv2.waitKey(0)

برای به دست آوردن یک تصویر تاب خورده، باید یک ماژول ساده ایجاد کنید که تبدیل پرسپکتیو را انجام دهد.

ماژول تحول

ماژول نقاط گوشه های سند را ترتیب می دهد. همچنین تصویر سند را به یک صفحه متفاوت تبدیل می‌کند و زاویه دوربین را به یک عکس بالای سر تغییر می‌دهد.

فایل transform.py را که قبلا ایجاد کردید باز کنید. کتابخانه های OpenCV و NumPy را وارد کنید.

import numpy as np
import cv2

این ماژول شامل دو تابع خواهد بود. تابعی ایجاد کنید که مختصات نقاط گوشه سند را ترتیب دهد. مختصات اول گوشه بالا سمت چپ، مختصات دوم گوشه بالا سمت راست، مختصات سوم گوشه پایین سمت راست و چهارمین مختصات گوشه پایین سمت چپ خواهد بود.

def order_points(pts):
   # initializing the list of coordinates to be ordered
   rect = np.zeros((4, 2), dtype = "float32")

   s = pts.sum(axis = 1)

   # top-left point will have the smallest sum
   rect[0] = pts[np.argmin(s)]

   # bottom-right point will have the largest sum
   rect[2] = pts[np.argmax(s)]

   '''computing the difference between the points, the
   top-right point will have the smallest difference,
   whereas the bottom-left will have the largest difference'''
   diff = np.diff(pts, axis = 1)
   rect[1] = pts[np.argmin(diff)]
   rect[3] = pts[np.argmax(diff)]

   # returns ordered coordinates
   return rect

یک تابع دوم ایجاد کنید که مختصات گوشه تصویر جدید را محاسبه می کند و یک عکس از سر به دست می آورد. سپس ماتریس تبدیل پرسپکتیو را محاسبه کرده و تصویر تاب خورده را برمی گرداند.

def perspective_transform(image, pts):
   # unpack the ordered coordinates individually
   rect = order_points(pts)
   (tl, tr, br, bl) = rect

   '''compute the width of the new image, which will be the
   maximum distance between bottom-right and bottom-left
   x-coordinates or the top-right and top-left x-coordinates'''
   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))

   '''compute the height of the new image, which will be the
   maximum distance between the top-left and bottom-left y-coordinates'''
   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))

   '''construct the set of destination points to obtain an overhead shot'''
   dst = np.array([
      [0, 0],
      [maxWidth - 1, 0],
      [maxWidth - 1, maxHeight - 1],
      [0, maxHeight - 1]], dtype = "float32")

   # compute the perspective transform matrix
   transform_matrix = cv2.getPerspectiveTransform(rect, dst)

   # Apply the transform matrix
   warped = cv2.warpPerspective(image, transform_matrix, (maxWidth, maxHeight))

   # return the warped image
   return warped

اکنون ماژول تبدیل را ایجاد کرده اید. خطای وارد کردن view_transform اکنون ناپدید خواهد شد.

مطلب مرتبط:   نحوه نوشتن مترجم کد مورس در پایتون

خروجی یک برنامه در یک IDE که یک تصویر تاب خورده از یک سند را نشان می دهد

توجه داشته باشید که تصویر نمایش داده شده دارای یک عکس بالای سر است.

اعمال آستانه تطبیقی ​​و ذخیره خروجی اسکن شده

در فایل main.py، آستانه گاوسی را روی تصویر تاب خورده اعمال کنید. این به تصویر تاب خورده ظاهری اسکن شده می دهد. خروجی تصویر اسکن شده را در پوشه حاوی فایل های برنامه ذخیره کنید.

T = threshold_local(warped_image, 11, offset=10, method="gaussian")
warped = (warped_image > T).astype("uint8") * 255
cv2.imwrite('./'+'scan'+'.png',warped)

ذخیره اسکن در فرمت PNG کیفیت سند را حفظ می کند.

نمایش خروجی

خروجی تصویر سند اسکن شده:

cv2.imshow("Final Scanned image", imutils.resize(warped, height=650))
cv2.waitKey(0)
cv2.destroyAllWindows()

تصویر زیر خروجی برنامه را نشان می دهد، یک عکس سربار از سند اسکن شده.

خروجی یک برنامه در یک IDE که یک سند اسکن شده را نشان می دهد

چگونه در بینایی کامپیوتری پیشرفت کنیم

ایجاد یک اسکنر اسناد برخی از حوزه های اصلی بینایی کامپیوتر را پوشش می دهد که یک زمینه گسترده و پیچیده است. برای پیشرفت در بینایی کامپیوتر باید روی پروژه های جالب اما چالش برانگیز کار کنید.

همچنین باید در مورد نحوه استفاده از بینایی کامپیوتر با فناوری های فعلی بیشتر بخوانید. این شما را در جریان قرار می‌دهد و ایده‌های جدیدی برای پروژه‌ها به شما می‌دهد.