Skip to content

Commit 1d68878

Browse files
Sarath ShekkizharSarath Shekkizhar
Sarath Shekkizhar
authored and
Sarath Shekkizhar
committed
Image Scanner project and Image lib
1 parent 8d72fcd commit 1d68878

11 files changed

+299
-35
lines changed

.idea/ImageProcessingProjects.iml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 136 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ImageScanner.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
__author__ = 'Charlie'
2+
import os, sys, inspect
3+
import cv2
4+
import numpy as np
5+
import argparse
6+
7+
# Info:
8+
# cmd_folder = os.path.dirname(os.path.abspath(__file__))
9+
# __file__ fails if script is called in different ways on Windows
10+
# __file__ fails if someone does os.chdir() before
11+
# sys.argv[0] also fails because it doesn't not always contains the path
12+
cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"Image_Lib")))
13+
if cmd_subfolder not in sys.path:
14+
sys.path.insert(0, cmd_subfolder)
15+
16+
from image_transform import four_point_transform
17+
import image_utils as utils
18+
19+
ap = argparse.ArgumentParser()
20+
ap.add_argument("-i", "--image", required = True, help = "Path to Image to be scanned")
21+
args = vars(ap.parse_args())
22+
23+
image = cv2.imread(args["image"])
24+
ratio = image.shape[0]/500.0
25+
orig = image.copy()
26+
image = utils.image_resize(image, height = 500)
27+
28+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
29+
gray = cv2.GaussianBlur(gray, (5, 5), 0)
30+
# clahe = cv2.createCLAHE()
31+
# gray = clahe.apply(gray)
32+
edged = cv2.Canny(gray, 25, 75)
33+
34+
# show the original image and the edge detected image
35+
print "STEP 1: Edge Detection"
36+
# cv2.imshow("Image", image)
37+
# cv2.imshow("Edged", edged)
38+
# cv2.waitKey(0)
39+
# cv2.destroyAllWindows()
40+
41+
42+
# find the contours in the edged image, keeping only the
43+
# largest ones, and initialize the screen contour
44+
(_, cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
45+
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]
46+
47+
# loop over the contours
48+
for c in cnts:
49+
# approximate the contour
50+
peri = cv2.arcLength(c, True)
51+
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
52+
53+
# if our approximated contour has four points, then we
54+
# can assume that we have found our screen
55+
if len(approx) == 4:
56+
screenCnt = approx
57+
break
58+
59+
# show the contour (outline) of the piece of paper
60+
print "STEP 2: Find contours of paper"
61+
# cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 2)
62+
# cv2.imshow("Outline", image)
63+
# cv2.waitKey(0)
64+
# cv2.destroyAllWindows()
65+
66+
67+
# apply the four point transform to obtain a top-down
68+
# view of the original image
69+
warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)
70+
71+
# convert the warped image to grayscale, then threshold it
72+
# to give it that 'black and white' paper effect
73+
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
74+
warped = utils.adaptive_threshold(warped)
75+
warped = warped.astype("uint8")
76+
77+
# show the original and scanned images
78+
print "STEP 3: Apply perspective transform"
79+
# cv2.imshow("Original", utils.image_resize(orig, height = 650))
80+
cv2.imshow("Scanned", utils.image_resize(warped, height = 650))
81+
cv2.waitKey(0)

Image_Lib/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__author__ = 'Charlie'

Image_Lib/image_transform.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
__author__ = 'Charlie'
2+
import numpy as np
3+
import cv2
4+
5+
def order_points(pts):
6+
# initialzie a list of coordinates that will be ordered
7+
# such that the first entry in the list is the top-left,
8+
# the second entry is the top-right, the third is the
9+
# bottom-right, and the fourth is the bottom-left
10+
rect = np.zeros((4, 2), dtype = "float32")
11+
12+
# the top-left point will have the smallest sum, whereas
13+
# the bottom-right point will have the largest sum
14+
s = pts.sum(axis = 1)
15+
rect[0] = pts[np.argmin(s)]
16+
rect[2] = pts[np.argmax(s)]
17+
18+
# now, compute the difference between the points, the
19+
# top-right point will have the smallest difference,
20+
# whereas the bottom-left will have the largest difference
21+
diff = np.diff(pts, axis = 1)
22+
rect[1] = pts[np.argmin(diff)]
23+
rect[3] = pts[np.argmax(diff)]
24+
25+
# return the ordered coordinates
26+
return rect
27+
28+
29+
def four_point_transform(image, pts):
30+
# obtain a consistent order of the points and unpack them
31+
# individually
32+
rect = order_points(pts)
33+
(tl, tr, br, bl) = rect
34+
35+
# compute the width of the new image, which will be the
36+
# maximum distance between bottom-right and bottom-left
37+
# x-coordiates or the top-right and top-left x-coordinates
38+
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
39+
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
40+
maxWidth = max(int(widthA), int(widthB))
41+
42+
# compute the height of the new image, which will be the
43+
# maximum distance between the top-right and bottom-right
44+
# y-coordinates or the top-left and bottom-left y-coordinates
45+
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
46+
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
47+
maxHeight = max(int(heightA), int(heightB))
48+
49+
# now that we have the dimensions of the new image, construct
50+
# the set of destination points to obtain a "birds eye view",
51+
# (i.e. top-down view) of the image, again specifying points
52+
# in the top-left, top-right, bottom-right, and bottom-left
53+
# order
54+
dst = np.array([
55+
[0, 0],
56+
[maxWidth - 1, 0],
57+
[maxWidth - 1, maxHeight - 1],
58+
[0, maxHeight - 1]], dtype = "float32")
59+
60+
# compute the perspective transform matrix and then apply it
61+
M = cv2.getPerspectiveTransform(rect, dst)
62+
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
63+
return warped

Image_Lib/image_transform.pyc

1.67 KB
Binary file not shown.

Image_Lib/image_utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
__author__ = 'Charlie'
2+
import cv2
3+
4+
def image_resize(image, width = -1, height = -1):
5+
shape = image.shape
6+
if(width == -1):
7+
if(height == -1):
8+
return image
9+
else:
10+
return cv2.resize(image, (int(height * shape[1]/shape[0]), height))
11+
elif (height == -1):
12+
return cv2.resize(image, (width, int(width * shape[0]/shape[1])))
13+
14+
15+
def adaptive_threshold(image):
16+
return cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)

Image_Lib/image_utils.pyc

1009 Bytes
Binary file not shown.

recipt.jpg

1.06 MB
Loading

recipt2.jpg

35.1 KB
Loading

0 commit comments

Comments
 (0)