forked from eokeeffe/videoExtractor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextractFrameAuto_Calibrate.py
170 lines (133 loc) · 5.7 KB
/
extractFrameAuto_Calibrate.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env python
#
# make sure to run install.sh before trying this script
# for exif data manipulation
# This script will also calibrate the images and save with EXIF data
#
import cv,cv2
from gi.repository import GExiv2
from fractions import Fraction
import argparse,re,time,os,sys
import random,math
import numpy as np
def splitfn(fn):
path, fn = os.path.split(fn)
name, ext = os.path.splitext(fn)
return path, name, ext
def calibrateImage(frame,camera_mtx,distortions):
h,w = frame.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(camera_mtx,distortions,(w,h),1,(w,h))
#undistort
mapx,mapy = cv2.initUndistortRectifyMap(camera_mtx,distortions,None,newcameramtx,(w,h),5)
undistorted = cv2.remap(frame,mapx,mapy,cv2.INTER_LINEAR)
#crop the image
x,y,w,h = roi
undistorted = undistorted[y:y+h,x:x+w]
return undistorted
parser = argparse.ArgumentParser(description='Program transforms video into seperate images for use in visual SFM, uses single image from target camera to automatically add EXIF information and uses the numpy loadtxt function to load camera distortions and camera matrix to calibrated the images as well as store the EXIF.')
parser.add_argument('-still', action="store",
help='file to read exif from,must be of the same camera',
dest="still", default=None)
parser.add_argument('-file', action="store",
help='file to transform',
dest="files", default=None)
parser.add_argument('-n', action="store",
help='use only nth image',
dest="capture_step", default=1)
parser.add_argument('-mtx', action="store",
help='camera matrix file location',
dest="camera_mtx", default=None)
parser.add_argument('-dist', action="store",
help='distortion coefficient file location',
dest="distortions", default=None)
parser.add_argument('-calibrate', action="store",
help='should the images be calibrated, requires -mtx and -dist args (bool)',
dest="calibrate", default=True)
args = parser.parse_args()
camera_mtx = np.loadtxt(args.camera_mtx)
distortions = np.loadtxt(args.distortions)
calibrate = bool(args.calibrate)
#print camera_mtx
#print distortions
#print calibrate,type(calibrate)
capture_step = int(args.capture_step)
if capture_step < 1: capture_step = 1
tf = ''.join(args.files)
files = [tf]
#for f in tf.split(' '): files.append(f.split(','))
#files = [item for sublist in files for item in sublist]
# N = F/D
# N = f number
# F = focal lenght
# D = diameter of lens
exif1 = GExiv2.Metadata(args.still)
print "Converting files:",files
print "Using file:%s as exif data input"%args.still
print "values:"
print "FNumber:",exif1['Exif.Photo.FNumber']
print "Focal Length:",exif1['Exif.Photo.FocalLength']
print "Aperture Value:",exif1['Exif.Photo.ApertureValue']
print "Camera Model:",exif1['Exif.Image.Model']
print "Camera Brand:",exif1['Exif.Image.Make']
if calibrate==True:
print "Calibrating Images as well"
print "Given input matrices are correct"
print camera_mtx
print distortions
else:
print "images will not be calibrated"
for f in files:
capture = cv2.VideoCapture(f)
width = capture.get(cv.CV_CAP_PROP_FRAME_WIDTH)
height = capture.get(cv.CV_CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv.CV_CAP_PROP_FPS)
frame_count = capture.get(cv.CV_CAP_PROP_FRAME_COUNT)
codec = capture.get(cv.CV_CAP_PROP_FOURCC)
print "Starting work on %s now" % f
if capture_step > frame_count: frame_count = frame_count - 1
ISOSPEEDS = [64, 100, 200, 250, 320, 400, 640, 800, 1000, 1600, 3200]
SHUTTERSPEEDS = [15, 30, 60, 125, 250, 400,
500, 1000, 1250, 1600, 2000, 4000]
FSTOPS = [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.7,
1.8, 2, 2.2, 2.4, 2.6, 2.8, 3.2, 3.4, 3.7,
4, 4.4, 4.8, 5.2, 5.6, 6.2, 6.7, 7.3, 8, 8.7,
9.5, 10, 11, 12, 14, 15, 16, 17, 19, 21, 22]
flash = [0x00,#No flash
0x1,
0x18,
0x19,
0x49,
0x4d,
0x4f,
0x49,
0x4d,
0x4f]
aperture = Fraction(random.uniform(1.0, 16.0)).limit_denominator(2000)
exposure = Fraction(1.0/round(random.randint(8, int(100.0*aperture))+1, -2)).limit_denominator(4000)
for i in xrange(int(frame_count)):
ret, frame = capture.read()
if ret and (i % capture_step == 0):
sys.stdout.write('saving frame:%s\r'%i)
sys.stdout.flush()
path = "%s.jpg"%(i)
if calibrate:
frame = calibrateImage(frame,camera_mtx,distortions)
cv2.imwrite(path, frame, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
exif = GExiv2.Metadata(path)
t = os.path.getctime(path)
ctime = time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(t))
exif['Exif.Image.ImageDescription'] = "SEQ#%s"%i
exif['Exif.Image.Make'] = exif1['Exif.Image.Make']
exif['Exif.Image.Model'] = exif1['Exif.Image.Model']
exif['Exif.Image.DateTime'] = ctime
exif['Exif.Image.Software'] = "https://github.com/eokeeffe/videoExtractor"
exif['Exif.Image.Orientation'] = exif1['Exif.Image.Orientation']
exif['Exif.Photo.UserComment'] = "calibrated awesomeness"
exif['Exif.Photo.Flash'] = exif1['Exif.Photo.Flash']
exif['Exif.Photo.FNumber'] = exif1['Exif.Photo.FNumber']
exif['Exif.Photo.FocalLength'] = exif1['Exif.Photo.FocalLength']
exif['Exif.Photo.ApertureValue'] = exif1['Exif.Photo.ApertureValue']
exif['Exif.Photo.ExposureTime'] = exif1['Exif.Photo.ExposureTime']
exif['Exif.Photo.ExposureBiasValue'] = exif1['Exif.Photo.ExposureBiasValue']
exif['Exif.Photo.ISOSpeedRatings'] = exif1['Exif.Photo.ISOSpeedRatings']
exif.save_file()