forked from kscottz/dewarp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dewarp.py
114 lines (105 loc) · 3.18 KB
/
dewarp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from SimpleCV import Camera, VideoStream, Color, Display, Image, VirtualCamera
import cv2
import numpy as np
import time
# deprecated, checks if point in the sphere is in our output
def isInROI(x,y,R1,R2,Cx,Cy):
isInOuter = False
isInInner = False
xv = x-Cx
yv = y-Cy
rt = (xv*xv)+(yv*yv)
if( rt < R2*R2 ):
isInOuter = True
if( rt < R1*R1 ):
isInInner = True
return isInOuter and not isInInner
# build the mapping
def buildMap(Ws,Hs,Wd,Hd,R1,R2,Cx,Cy):
map_x = np.zeros((Hd,Wd),np.float32)
map_y = np.zeros((Hd,Wd),np.float32)
for y in range(0,int(Hd-1)):
for x in range(0,int(Wd-1)):
r = (float(y)/float(Hd))*(R2-R1)+R1
theta = (float(x)/float(Wd))*2.0*np.pi
xS = Cx+r*np.sin(theta)
yS = Cy+r*np.cos(theta)
map_x.itemset((y,x),int(xS))
map_y.itemset((y,x),int(yS))
return map_x, map_y
# do the unwarping
def unwarp(img,xmap,ymap):
output = cv2.remap(img.getNumpyCv2(),xmap,ymap,cv2.INTER_LINEAR)
result = Image(output,cv2image=True)
return result
disp = Display((800,600))
vals = []
last = (0,0)
# Load the video from the rpi
vc = VirtualCamera("video.h264","video")
# Sometimes there is crud at the begining, buffer it out
for i in range(0,10):
img = vc.getImage()
img.save(disp)
# Show the user a frame let them left click the center
# of the "donut" and the right inner and outer edge
# in that order. Press esc to exit the display
while not disp.isDone():
test = disp.leftButtonDownPosition()
if( test != last and test is not None):
last = test
vals.append(test)
# 0 = xc yc
# 1 = r1
# 2 = r2
# center of the "donut"
Cx = vals[0][0]
Cy = vals[0][1]
# Inner donut radius
R1x = vals[1][0]
R1y = vals[1][1]
R1 = R1x-Cx
# outer donut radius
R2x = vals[2][0]
R2y = vals[2][1]
R2 = R2x-Cx
# our input and output image siZes
Wd = 2.0*((R2+R1)/2)*np.pi
Hd = (R2-R1)
Ws = img.width
Hs = img.height
# build the pixel map, this could be sped up
print "BUILDING MAP!"
xmap,ymap = buildMap(Ws,Hs,Wd,Hd,R1,R2,Cx,Cy)
print "MAP DONE!"
# do an unwarping and show it to us
result = unwarp(img,xmap,ymap)
result = result.adaptiveScale(resolution=(640,480))
result.save(disp)
# SimpleCV/OpenCV video out was giving problems
# decided to output frames and convert using
# avconv / ffmpeg. Comment out the block below
# to save to video
#ofname = 'OUT.AVI'
#vs = VideoStream(fps=20,filename=ofname,framefill=False)
#vs.initializeWriter((640,480))
# I used these params for converting the raw frames to video
# avconv -f image2 -r 30 -v:b 1024K -i samples/lapinsnipermin/%03d.jpeg output.mpeg
i = 0
while img is not None:
print img.width,img.height
result = unwarp(img,xmap,ymap)
#derp = result.adaptiveScale(resolution=(640,480))
#result = result.resize(w=img.width)
# Once we get an image overlay it on the source
derp = img.blit(result,(0,img.height-result.height))
derp = derp.applyLayers()
#derp = derp.resize(640,480)
derp.save(disp)
# Save to file
fname = "FRAME{num:05d}.png".format(num=i)
derp.save(fname)
#vs.writeFrame(derp)
# get the next frame
img = vc.getImage()
i = i + 1