Mohsen Khoshnazar Homepage

Mohsen Khoshnazar Homepage
سلام به همه.
سعی می کنم تجربیات خودم رو در این وبلاگ قرار بدم تا دیگر علاقه مندان نیز بتوانند از آنها استفاده کنند.
موفق باشید:)

Telegram Channel: mohsenteq
Instagram: mohsenteq
Site: www.mteq.ir
دنبال کنندگان ۱ نفر
این وبلاگ را دنبال کنید
آخرین نظرات
پنجشنبه, ۳۰ ارديبهشت ۱۳۹۵، ۰۱:۴۰ ب.ظ

اسکن مدارک با استفاده از OpenCV و Python

   در این پست قصد داریم با استفاده از OpenCV و Python، برنامه اسکنی شبیه به آنچه که در گوش های امروزی وجود دارد بنویسیم. در پست پیشین (تبدیل Perspective با استفاده از مختصات اولیه و نهایی 4 نقطه از تصویر)، برنامه ای برای تبدیل حالت پرسپکتیو نوشته شد و از آن در این برنامه استفاده خواهیم کرد. در اینجا مختصات نقاط اولیه نیز به طور خودکار و با استفاده از تشخیص لبه و Contour بدست می آیند.
   اسکن یک فایل از سه مرحله ساده تشکیل شده است:

  • مرحله اول: تشخیص لبه ها

  • مرحله دوم: استفاده از لبه ها برای پیدا کردن Contour ها

  • مرحله سوم: اعمال تبدیل پرسپکتیو

مرحله اول: تشخیص لبه ها

# import the necessary packages
import cv2
import numpy as np
import sys
sys.path.append('/home/pi/myfunctions.py')
from myfunctions import four_point_transform

# load the image
img=cv2.imread('document2.jpg')
orig=img.copy()

# convert the image to grayscale, blur it, and find edges
# in the image
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray=cv2.GaussianBlur(gray,(5,5),0)
edged=cv2.Canny(gray,75,200)

# show the original image and the edge detected image
print "STEP 1: Edge Detection"
cv2.imwrite("Image.jpg", img)
cv2.imwrite("Edged.jpg", edged)

   ابتدا پکیج های مورد نیاز را وارد می کنیم. numpy برای Numberical Processing و cv2 برای OpenCV هستند. تبدیل پرسپکتیو وارد می کنیم تا در مرحله آخر از آن استفاده نماییم.

   حال تصویر مورد نظر را بارگذادی می کنیم. لازم است تا لبه های تصویر مشخص شوند. برای این کار باید تصویر رنگی (BGR) را با استفاده از دستور cv2.cvtColor به خاکستری (GRAY) تبدیل کنیم.

   برای رفع نویزهای فرکانس بالا و افزایش دقت تشخیص لبه ها از فیلتر Gaussian استفاده کردیم.

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

   تصویر سمت راست، تصویر اصلی است و پس از اعمال دستور Canny، تصویر سمت چپ حاصل می شود. مرحله اول به پایان رسید.

مرحله دوم: استفاده از لبه ها برای پیدار کردن Contour ها

   همانطوری که در تصویر مرحله قبل مشخص است، لبه های زیادی پیدا شده است؛ ولی هدف ما فقط لبه های برگه اصلی است و نه لبه های دیگر. به عبارت دیگر باید به دنبال بزرگترین Contour بگردیم.

# find the contours in the edged image, keeping only the
# largest ones, and initialize the screen contour
(_,contours,_)=cv2.findContours(edged.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key = cv2.contourArea, reverse = True)[:5]

# loop over the contours

for c in contours:

# approximate the contour

peri = cv2.arcLength(c, True)

  approx = cv2.approxPolyDP(c, 0.02 * peri, True)

# if our approximated contour has four points, then we

# can assume that we have found our screen
if len(approx) == 4:
screenCnt = approx

 break

# show the contour (outline) of the piece of paper

print "STEP 2: Find contours of paper"

cv2.drawContours(img, [screenCnt], -1, (0, 255, 0), 2)

cv2.imwrite("Outline.jpg", img)

   توسط دستور cv2.finfContours، تمامی Contour های موجود در تصویر را پیدا می کنیم. سپس آنها را مرتب می کنیم.

   فرض بر این است که هر بار فقط یک برگه را می خواهیم اسکن کنیم و برگه ها همگی مستطیل شکل (4 گوشه) هستند.

   اکنون محیط Contour های مشخص شده را پیدا کرده و برحسب آنها یک چند گوشه را با استفاده از دستور cv2.approxPolyDP مشخص می کنیم. حال اگر تعداد المان های هر یک از چند گوشه ها برابر 4 باشد، بدین معناست که یک 4 گوش پیدا کردیم.

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

   مرحله دوم نیز به پایان رسید و اکنون نوبت به اعمال تبدیل پرسپکتیو می رسد.

مرحله سوم: اعمال تبدیل پرسپکتیو

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

# apply the four point transform to obtain a top-down
# view of the original image
warped = four_point_transform(orig, screenCnt.reshape(4, 2) )

# convert the warped image to grayscale, then threshold it
# to give it that 'black and white' paper effect
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
warped=cv2.adaptiveThreshold(warped,251,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
 
# show the original and scanned images
print "STEP 3: Apply perspective transform"
cv2.imshow("Original", orig)
warped=cv2.resize(warped,(img.shape[1],img.shape[0]),interpolation=cv2.INTER_AREA)
cv2.imshow("Scanned",warped)
cv2.imwrite("Scanned.jpg",warped)
cv2.waitKey(0)

   تابع four_point_transform را فراخوانی می کنیم. با استفاده از بزرگترین Contour که در مرحله قبل پیدا کرده بودیم، مختصات نقاط اوله را در اختیار داریم.

   پس از آن باید تصویر اصلی از حالت BGR به GRAY تبدیل کنیم. در قسمت بعدی با اعمال Adaptive Threshold، تصویر خاکستری را به حالت سیاه-سفید تبدیل می کنیم. و در آخر آن را نمایش می دهیم. شکل زیر تصویر اصلی و اسکن شده است.

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

دریافت

حجم: 2.14 مگابایت

توضیحات: Document Scanner

نظرات (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی