Skip to content

Instantly share code, notes, and snippets.

@lhchavez
Created July 21, 2011 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lhchavez/1097661 to your computer and use it in GitHub Desktop.
Save lhchavez/1097661 to your computer and use it in GitHub Desktop.
removes a perspective projection from a region of an image.
#!/usr/bin/python
import Image
import math
# calculates simple two-line intersection. be warned: fails miserably with
# vertical lines and parallelograms.
def intersection(p0, p1, p2, p3):
m0 = (p1[1] - p0[1]) / float(p1[0] - p0[0])
m2 = (p3[1] - p2[1]) / float(p3[0] - p2[0])
return intersection2(p0, m0, p2, m2)
# gets the intersection between two point-slope lines
def intersection2(p0, m0, p2, m2):
x = (p2[1] - p0[1] + m0*p0[0] - m2*p2[0]) / (m0 - m2)
y = m0 * (x - p0[0]) + p0[1]
return x, y
img = Image.open('grid.jpg')
# sorry, you have to provide these yourself :P
corners = ((2018, 101), (143, 644), (188, 1699), (2227, 1678))
xf = intersection(*corners)
yf = intersection(*(corners[1:] + corners[:1]))
minx = math.atan2(corners[0][1] - xf[1], corners[0][0] - xf[0])
miny = math.atan2(corners[2][1] - yf[1], corners[2][0] - yf[0])
maxx = math.atan2(corners[2][1] - xf[1], corners[2][0] - xf[0])
maxy = math.atan2(corners[0][1] - yf[1], corners[0][0] - yf[0])
dx = maxx - minx
dy = maxy - miny
w = 1024
h = 600
out = Image.new('RGB', (w, h))
for y in xrange(h):
for x in xrange(w):
my = math.tan(miny + dy * (x / float(w)) ** 1.3) # don't ask, i don't know either
mx = math.tan(minx + dx * (y / float(h)))
xx, yy = intersection2(yf, my, xf, mx)
try:
out.putpixel((x, y), img.getpixel((xx, yy)))
except:
pass
out.save('output.jpg')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment