Last active
January 23, 2018 19:43
-
-
Save loguntsov/92f07b6c8303f92ef9fd5cee823db900 to your computer and use it in GitHub Desktop.
Stabilization of white paper inside image. It will reduce perspective distortion also. For all questions pls write me on email: loguntsov@gmail.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv, cv2, numpy as np | |
import sys, math as m | |
import glob, os | |
def get_new(old): | |
new = np.ones(old.shape, np.uint8) | |
cv2.bitwise_not(new,new) | |
return new | |
def remove(contour, n): | |
if len(contour) <= n: | |
return contour | |
c = np.array([]) | |
s = -1 | |
for i, val in enumerate(contour): | |
c0 = np.copy(contour) | |
c0 = np.delete(c0, i, axis = 0) | |
s0 = m.fabs(cv2.contourArea(c0)) | |
if s0 > s: | |
s = s0 | |
c = c0 | |
print c, s | |
return remove(c,n) | |
def resize(file): | |
cv2.namedWindow('result', cv2.WINDOW_NORMAL) | |
cv2.resizeWindow('result', 2000, 1000) | |
orig = cv2.imread(file) | |
cv2.imshow('result', orig) | |
# these constants are carefully picked | |
MORPH = 10 | |
CANNY = 150 | |
HOUGH = 15 | |
HX = 1620 | |
HY = 1080 | |
gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY) | |
gray = cv2.GaussianBlur(gray, (5,5), 0) | |
img = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)[1] | |
cv2.imshow('result', img) | |
#cv2.waitKey(0) | |
# this is to recognize white on white | |
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(MORPH,MORPH)) | |
dilated = cv2.dilate(img, kernel, iterations=1) | |
cv2.imshow('result', dilated) | |
edges = cv2.Canny(dilated, 0.4*CANNY, CANNY, apertureSize=3) | |
cv2.imshow('result', edges) | |
lines = cv2.HoughLinesP(edges, 1, 3.14/180, HOUGH) | |
for line in lines[0]: | |
cv2.line(edges, (line[0], line[1]), (line[2], line[3]), | |
(255,255,255), 2, 8) | |
# finding contours | |
contours, _ = cv2.findContours(edges.copy(), cv.CV_RETR_EXTERNAL, | |
cv.CV_CHAIN_APPROX_TC89_KCOS) | |
contours = filter(lambda cont: cv2.arcLength(cont, True) > 4000, contours) | |
#contours = filter(lambda cont: m.fabs(cv2.contourArea(cont)) > 50000, contours) | |
# simplify contours down to polygons | |
rects = [] | |
new1 = get_new(img) | |
# simplify contours down to polygons | |
rects = [] | |
for cont in contours: | |
rect = cv2.approxPolyDP(cont, 200, True).copy().reshape(-1, 2) | |
rects.append(rect) | |
c = cv2.convexHull(np.array([x for sublist in rects for x in sublist])) | |
# that's basically it | |
# show only contours | |
new = get_new(img) | |
for point in c : | |
print( point ) | |
# new1 = cv2.preCornerDetect(new, 5) | |
# cv2.GaussianBlur(new, (9,9), 0, new) | |
# new = cv2.Canny(new, 0, CANNY, apertureSize=3) | |
p = remove(c, 4) | |
extBot = p[0][0] | |
extRight = p[1][0] | |
extLeft = p[2][0] | |
extTop = p[3][0] | |
cv2.circle(new, tuple(extLeft), 10, (0, 0, 0), -1) | |
cv2.circle(new, tuple(extRight), 10, (0, 0, 0), -1) | |
cv2.circle(new, tuple(extTop), 10, (0, 0, 0), -1) | |
cv2.circle(new, tuple(extBot), 10, (0, 0, 0), -1) | |
cv2.drawContours(orig, [p],-1,(255,255,255),1) | |
cv2.drawContours(new, [p],-1,(0,255,0),1) | |
pts1 = np.float32([extLeft,extTop,extRight, extBot]) | |
pts2 = np.float32([[0,0],[HX,0],[0,HY],[HX,HY]]) | |
M = cv2.getPerspectiveTransform(pts1,pts2) | |
dst = cv2.warpPerspective(orig,M,(HX,HY)) | |
#cv2.waitKey(0) | |
#cv2.waitKey(0) | |
#cv2.waitKey(0) | |
cv2.imshow('result', new) | |
#cv2.waitKey(0) | |
cv2.imshow('result', dst) | |
#cv2.waitKey(0) | |
cv2.destroyAllWindows() | |
cv2.imwrite("result/" + os.path.basename(file), dst) | |
for file in glob.glob("./*.jpg"): | |
resize(file) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment