forked from seereality/opencvDemos
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimgUtils.py
More file actions
273 lines (209 loc) · 9 KB
/
imgUtils.py
File metadata and controls
273 lines (209 loc) · 9 KB
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
'''
These functions are most often utilized in a signal processing pipline
and are organized within this module to reprsent the form:
signal --> acquire as data --> processing --> output as data
'''
# TODO: Import only specific things and not the entire namespace
# TODO: What if the namespace is already imported?
import os
import cv2
import numpy as np
import cPickle
#===============================================================================
# Acquire data
#===============================================================================
# facerec predictor loaded from pickled file
def loadPredictor(fileName):
if not fileName:
print 'Failed to load: given file name was None type'
else:
pklFile = open(fileName, 'rb')
predictor = cPickle.load(pklFile)
pklFile.close()
return predictor
# Files from a folder with subfolders
def fetchFiles(pathToFolder, flag, keyWord):
# TODO: Display directory structure using dirPath, dirNames
'''fetchFiles() requires three arguments:
1. pathToFolder is the location of files which may contain subfolders
2. flag must be 'STARTS_WITH' or 'ENDS_WITH'
3. keyWord is a string to search the file's name
Be careful, the keyWord is case sensitive and must be exact
Example: fetchFiles('/Documents/Photos/','ENDS_WITH','.jpg')
returns: _pathToFiles, _fileNames '''
_pathToFiles = []
_fileNames = []
for dirPath, dirNames, fileNames in os.walk(pathToFolder):
if flag == 'ENDS_WITH':
selectedPath = [os.path.join(dirPath,item) for item in fileNames
if item.endswith(keyWord)]
_pathToFiles.extend(selectedPath)
selectedFile = [item for item in fileNames if
item.endswith(keyWord)]
_fileNames.extend(selectedFile)
elif flag == 'STARTS_WITH':
selectedPath = [os.path.join(dirPath,item) for item in fileNames
if item.startswith(keyWord)]
_pathToFiles.extend(selectedPath)
selectedFile = [item for item in fileNames
if item.startswith(keyWord)]
_fileNames.extend(selectedFile)
else:
print fetchFiles.__doc__
break
# Try to remove empty entries if no required files are in directory
try:
_pathToFiles.remove('')
_fileNames.remove('')
except ValueError:
pass
# Warn if nothing was found amongst the given paths
if selectedFile == []:
print 'No files with given parameters were found in:\n', dirPath, '\n'
print len(_fileNames), 'files were found in searched folder(s)'
return _pathToFiles, _fileNames
#===============================================================================
# Process the acquired data
#===============================================================================
def isEmpty(anyStructure):
if anyStructure:
return False
else:
return True
def chooseCascade(choice='frontalFace'):
# TODO: write the doc for this function
# 'mouth' cascade doesn't work properly
opts = {'frontalFace':'./cascadeFiles/haarcascade_frontalface_alt2.xml',
'profileFace':'./cascadeFiles/haarcascade_profileface.xml',
'leftEye':'./cascadeFiles/haarcascade_leftEye.xml',
'rightEye':'./cascadeFiles/haarcascade_rightEye.xml',
'rightEye2':'./cascadeFiles/haarcascade_righteye_2splits.xml',
'frontalEyes':'./cascadeFiles/haarcascade_frontalEyes.xml',
'eyeGlasses':'./cascadeFiles/haarcascade_eye_tree_eyeglasses.xml',
'fullBody':'./cascadeFiles/haarcascade_eye_tree_eyeglasses.xml',
'upperBody':'./cascadeFiles/haarcascade_upperbody.xml',
'lowerBody':'./cascadeFiles/haarcascade_upperbody.xml',
'lowerBody':'./cascadeFiles/haarcascade_lowerbody.xml',
'head':'./cascadeFiles/haarcascade_head_16x16.xml',
'nose':'./cascadeFiles/haarcascade_nose_25x15.xml',
'mouth':'./cascadeFiles/haarcascade_mcs_mouth.xml',
'frontalFace_LBP':'./cascadeFiles/lbpcascade_frontalface.xml',
'mascfrontalFace_LBP': './cascadeFiles/lbpcascade_mascFrontalFace_20x20_Nov-22-2013.xml'}
_cascade = cv2.CascadeClassifier(opts[choice])
return _cascade
def cropToObj(cascade,image):
'''
Crop to the object of interest in the image
Since cascade.detectMultiScale() can return a list
the output of this function is also a list
even for the case when a single image is to be returned
'''
# TODO: What if croping shouldn't produce rectangular region?
# TODO: What if objImages keeps growing and consumes all available memory?
_objRegions = cascade.detectMultiScale(image,
scaleFactor=1.2,
minNeighbors=3,
minSize=(20, 20))
# _objRegions = cascade.detectMultiScale(image)
_objImages = []
for rowNum in range(len(_objRegions)):
x1 = _objRegions[rowNum,0]
y1 = _objRegions[rowNum,1]
x1PlusWidth = _objRegions[rowNum,0] + _objRegions[rowNum,2]
y1PlusHeight = _objRegions[rowNum,1] + _objRegions[rowNum,3]
_objImage = image[y1:y1PlusHeight,x1:x1PlusWidth]
_objImages.append(_objImage)
return _objRegions, _objImages
def cropByPercent(_image,hAxisPct,vAxisPct):
'''
use only for face images returned by cropToObj!
crop off the forehead by hAxisPct
crop off the ears by vAxisPct
hAxisPct and vAxisPct should be a value between 0 and 1
example:
image2 = cropByPercent(image1,0.3,0.2)
'''
hAxis = int(hAxisPct*_image.shape[0])
vAxis = int(vAxisPct*_image.shape[1])
croppedImage = _image[hAxis:, vAxis:-vAxis]
return croppedImage
#===============================================================================
# Output processed data
#===============================================================================
# Open the main camera and save an image
def saveCamImage(path):
'''
Give destination path as string
Open primary camera
Display the image in a window
Press s to save the image as 'camImage.jpg'
Press esc to quit
'''
capture = cv2.VideoCapture(0)
saveCount = 0
keyPressed = -1
while(keyPressed != 27):
ret, camImage = capture.read()
cv2.imshow("camImage", camImage)
keyPressed = cv2.waitKey(1)
if keyPressed == ord('s'):
cv2.imwrite(path + 'camImage' + str(saveCount) + '.jpg', camImage)
saveCount += 1
print 'image saved to workspace'
cv2.destroyAllWindows()
# Save facerec predictor to pickle file
def savePredictor(fileName, predictor):
if not predictor:
print 'Failed to save: The given predictor was None type.'
else:
pklFile = open(fileName, 'wb')
cPickle.dump(predictor, pklFile)
pklFile.close()
# A text file with paths to desired data
def writePathsToFile(outputFileName,fileNames,prefix='',suffix=''):
'''
All arguments must be strings
get pathToFiles and fileNames via fetchFiles()
or supply them via other suitable means
prefix and suffix are optional
Example:
writePathsToFiles('output.txt',
'abc123.jpg',
'/traindata ',
' 1 0 0 240 240')
The line written in output.txt will be:
/traindata abc123.jpg 1 0 0 240 240
'''
textFile = open(outputFileName,'w')
for _name in fileNames:
textFile.write(prefix + _name + suffix +'\n')
textFile.close()
# for writing color image to grayscale
def toGrayScale(pathToFiles,dstPath):
'''
get pathToFiles and fileNames via fetchFiles()
or supply them via other suitable means
saves a 1-channel 8bit grayscale image at dstPath.
'''
for path in pathToFiles:
grayImage = cv2.imread(path,0)
cv2.imwrite(dstPath,grayImage)
def drawMatches(img1,kp1,img2,kp2,matches):
'''
compare img1 and img2 for matching keypoints
get matches from KNN or Brute Force Matcher or FLANN
'''
h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]
view = np.zeros((max(h1, h2), w1 + w2, 3), np.uint8)
view[:h1, :w1, 0] = img1
view[:h2, w1:, 0] = img2
view[:, :, 1] = view[:, :, 0]
view[:, :, 2] = view[:, :, 0]
for m in matches:
# draw the keypoints
color = tuple([np.random.randint(0, 255) for item in xrange(3)])
pt1 = (int(kp1[m.queryIdx].pt[0]),int(kp1[m.queryIdx].pt[1]))
pt2 = (int(kp2[m.trainIdx].pt[0] + w1), int(kp2[m.trainIdx].pt[1]))
cv2.line(view, pt1, pt2, color)
return view