def generateTransforms(self, detection): # Transform the face affine = pv.AffineFromRect(detection, self.tile_size) w, h = self.tile_size if self.perturbations: # Randomly rotate, translate and scale the images center = pv.AffineTranslate(-0.5 * w, -0.5 * h, self.tile_size) rotate = pv.AffineRotate(random.uniform(-pi / 8, pi / 8), self.tile_size) scale = pv.AffineScale(random.uniform(0.9, 1.1), self.tile_size) translate = pv.AffineTranslate(random.uniform(-0.05 * w, 0.05 * w), random.uniform(-0.05 * h, 0.05 * h), self.tile_size) inv_center = pv.AffineTranslate(0.5 * w, 0.5 * h, self.tile_size) affine = inv_center * translate * scale * rotate * center * affine #affine = affine*center*rotate*scale*translate*inv_center lx = self.left_center.X() - self.subtile_size[0] / 2 ly = self.left_center.Y() - self.subtile_size[1] / 2 rx = self.right_center.X() - self.subtile_size[0] / 2 ry = self.right_center.Y() - self.subtile_size[1] / 2 laffine = pv.AffineFromRect( pv.Rect(lx, ly, self.subtile_size[0], self.subtile_size[1]), self.subtile_size) * affine raffine = pv.AffineFromRect( pv.Rect(rx, ry, self.subtile_size[0], self.subtile_size[1]), self.subtile_size) * affine return laffine, raffine
def annotateFrame(self,frame,color='white'): ''' Renders optical flow information to the frame. @param frame: the frame that will be annotated @type frame: pv.Image @keyword type: @ktype type: "TRACKING" ''' w,h = self.tile_size rect = pv.Rect(0,0,w,h) affine = pv.AffineFromRect(rect,frame.size) for pt in affine.transformPoints(self.tracks[:self.n]): frame.annotatePoint(pt,color=color) for pt in affine.transformPoints(self.tracks[self.n:]): frame.annotatePoint(pt,color='red') for pt in affine.transformPoints(self.bad_points): frame.annotatePoint(pt,color='gray') if self.homography != None: matrix = pv.OpenCVToNumpy(self.homography) perspective = pv.PerspectiveTransform(matrix,frame.size) for pt in self.tracks[:self.n]: # Transform the point multiple times to amplify the track # for visualization old = perspective.invertPoint(pt) old = perspective.invertPoint(old) old = perspective.invertPoint(old) frame.annotateLine(pt,old,color=color)
def extract(self, img, face_records): '''Extract a template that allows the face to be matched.''' # Compute the 512D vector that describes the face in img identified by #shape. im = pv.Image(img[:, :, ::-1]) for face_record in face_records.face_records: rect = pt.rect_proto2pv(face_record.detection.location) x, y, w, h = rect.asTuple() # Extract view rect = pv.Rect() cx, cy = x + 0.5 * w, y + 0.5 * h tmp = 1.5 * max(w, h) cw, ch = tmp, tmp crop = pv.AffineFromRect(pv.CenteredRect(cx, cy, cw, ch), (256, 256)) pvim = pv.Image(img[:, :, ::-1]) # convert rgb to bgr pvim = crop(pvim) view = pt.image_pv2proto(pvim) face_record.view.CopyFrom(view) tile = pvim.resize((224, 224)) tile = tile.resize((112, 112)) face_im = tile.asOpenCV2() face_im = face_im[:, :, ::-1] # Convert BGR to RGB features = self.fr_model.get_embedding(face_im) face_descriptor = pv.meanUnit(features.flatten()) face_record.template.data.CopyFrom( pt.vector_np2proto(face_descriptor))
def _initialize(self,frame,rect): ''' A private method that initializes the filter and prepares this instance of a MOSSETrack to receive new frames. @param frame: A source video frame to _initialize from. @type frame: pv.Image @param rect: A rectangle defining the object to be tracked in "frame". @type rect: pv.Rect ''' start = time.time() self.rect = copy.deepcopy(rect) affine = pv.AffineFromRect(rect,self.tile_size) pt = affine.transformPoint(self.rect.center()) if self.strategy == INIT_ONE_TRANSFORM: tmp = affine.transformImage(frame) self.filter.addTraining(tmp,pt) self.input = tmp elif self.strategy == INIT_NINE_TRANSFORM: for scale in [-1,0,1]: scale = pv.AffineRotate(scale*self.dscale,self.tile_size,center=pt) for rotate in [-1,0,1]: rot = pv.AffineRotate(rotate*self.drotate,self.tile_size,center=pt) pt = (scale*rot*affine).transformPoint(self.rect.center()) tmp = (scale*rot*affine).transformImage(frame) self.filter.addTraining(tmp,pt) self.input = tmp self.corr = np.zeros(self.tile_size,dtype=np.float64) self.frame = 0 stop = time.time() self.update_time = stop-start self.best_estimate = rect.center()
def detect(self, im): ''' @returns: a list of tuples where each tuple contains (registered_image, detection_rect, left_eye, right_eye) ''' result = [] rects = self.face_detector.detect(im) # Anotate Faces for rect in rects: # Transform the face affine = pv.AffineFromRect(rect, self.tile_size) cropped = affine.transformImage(im) for _ in range(self.n_iter): cropped = pv.meanStd(cropped) # Find the eyes data = cropped.asMatrix2D().flatten() data = np.array(data, 'd').flatten() data = self.normalize.normalizeVector(data) pleye = self.left_locator.predict(data) preye = self.right_locator.predict(data) pleye = affine.invertPoint(pleye) preye = affine.invertPoint(preye) # Seccond Pass affine = pv.AffineFromPoints(pleye, preye, self.left_eye, self.right_eye, self.tile_size) cropped = affine.transformImage(im) #affine = AffineFromPoints(pleye,preye,self.left_eye,self.right_eye,self.tile_size) #reg = affine.transformImage(im) reg = cropped if self.validate != None and not self.validate(reg): # Validate the face. if self.annotate: im.annotateRect(rect, color='red') im.annotatePoint(pleye, color='red') im.annotatePoint(preye, color='red') continue if self.annotate: reg.annotatePoint(self.left_eye, color='green') reg.annotatePoint(self.right_eye, color='green') im.annotatePoint(pleye, color='green') im.annotatePoint(preye, color='green') im.annotateRect(rect, color='green') result.append((reg, rect, pleye, preye)) return result
def addTraining(self, left_eye, right_eye, im): '''Train an eye detector givin a full image and the eye coordinates.''' # determine the face rect true_rect = face_from_eyes(left_eye, right_eye) # run the face detector rects = self.face_detector.detect(im) # find the best detection if there is one for pred_rect in rects: if is_success(pred_rect, true_rect): # Transform the face affine = pv.AffineFromRect(pred_rect, self.tile_size) w, h = self.tile_size if self.perturbations: # Randomly rotate, translate and scale the images center = pv.AffineTranslate(-0.5 * w, -0.5 * h, self.tile_size) rotate = pv.AffineRotate(random.uniform(-pi / 8, pi / 8), self.tile_size) scale = pv.AffineScale(random.uniform(0.9, 1.1), self.tile_size) translate = pv.AffineTranslate( random.uniform(-0.05 * w, 0.05 * w), random.uniform(-0.05 * h, 0.05 * h), self.tile_size) inv_center = pv.AffineTranslate(0.5 * w, 0.5 * h, self.tile_size) affine = inv_center * translate * scale * rotate * center * affine #affine = affine*center*rotate*scale*translate*inv_center cropped = affine.transformImage(im) cropped = pv.meanStd(cropped) # Mark the eyes leye = affine.transformPoint(left_eye) reye = affine.transformPoint(right_eye) # Add training data to locators self.training_labels.append((leye, reye)) self.normalize.addTraining(0.0, cropped) #self.left_locator.addTraining(cropped,leye) #self.right_locator.addTraining(cropped,reye) # Just use the first success return # The face was not detected self.detection_failures += 1
def test_from_rect(self): transform = pv.AffineFromRect(pv.Rect(100, 100, 300, 300), (100, 100)) _ = transform.transformImage(self.test_image) #im_a.show() pt = transform.transformPoint(pv.Point(320, 240)) self.assertAlmostEqual(pt.X(), 73.333333333333329) self.assertAlmostEqual(pt.Y(), 46.666666666666671) pt = transform.invertPoint(pv.Point(50., 50.)) self.assertAlmostEqual(pt.X(), 250.0) self.assertAlmostEqual(pt.Y(), 250.0)
def extract(self,img,face_records): '''Extract a template that allows the face to be matched.''' # Compute the 128D vector that describes the face in img identified by # shape. In general, if two face descriptor vectors have a Euclidean # distance between them less than 0.6 then they are from the same # person, otherwise they are from different people. Here we just print # the vector to the screen. # TODO: Make this an option JITTER_COUNT = 5 for face_record in face_records.face_records: rect = pt.rect_proto2pv(face_record.detection.location) x,y,w,h = rect.asTuple() # Extract view rect = pv.Rect() cx,cy = x+0.5*w,y+0.5*h tmp = 1.5*max(w,h) cw,ch = tmp,tmp crop = pv.AffineFromRect(pv.CenteredRect(cx,cy,cw,ch),(256,256)) #print (x,y,w,h,cx,cy,cw,ch,crop) pvim = pv.Image(img[:,:,::-1]) # convert rgb to bgr pvim = crop(pvim) view = pt.image_pv2proto(pvim) face_record.view.CopyFrom(view) # Extract landmarks l,t,r,b = [int(tmp) for tmp in [x,y,x+w,y+h]] d = dlib.rectangle(l,t,r,b) shape = self.shape_pred(img, d) #print('s',dir(shape)) #print(shape.parts()[0]) for i in range(len(shape.parts())): loc = shape.parts()[i] landmark = face_record.landmarks.add() landmark.landmark_id = "point_%02d"%i landmark.location.x = loc.x landmark.location.y = loc.y #print('fr',face_record) #print('shape:',face_records.face_records[0].landmarks) face_descriptor = self.face_rec.compute_face_descriptor(img, shape, JITTER_COUNT) face_descriptor = np.array(face_descriptor) vec = face_descriptor.flatten() face_record.template.data.CopyFrom(pt.vector_np2proto(vec))
def test_affine_Matrix3D(self): im = pv.Image(pv.BABOON) test_im = pv.Image(im.asMatrix3D()) affine = pv.AffineFromRect(pv.CenteredRect(256,256,128,128),(64,64)) # Transform the images im = affine(im) test_im = affine(test_im) # Correlate the resulting images vec1 = pv.unit(im.asMatrix3D().flatten()) vec2 = pv.unit(test_im.asMatrix3D().flatten()) score = np.dot(vec1,vec2) self.assertGreater(score, 0.998)
def extract(self, img, face_records): '''Extract a template that allows the face to be matched.''' # Compute the 512D vector that describes the face in img identified by #shape. #print(type(img),img.shape) img = img[:, :, :: -1] #convert from rgb to bgr. There is BGRtoRGB conversion in get_embedding for face_record in face_records.face_records: #print(face_record) if face_record.detection.score != -1: landmarks = np.zeros((5, 2), dtype=np.float) for i in range(0, len(face_record.landmarks)): vals = face_record.landmarks[i] landmarks[i, 0] = vals.location.x landmarks[i, 1] = vals.location.y _img = self.preprocess.norm_crop(img, landmark=landmarks) #print(_img.shape) embedding = self.fr_model.get_embedding(_img).flatten() embedding_norm = np.linalg.norm(embedding) normed_embedding = embedding / embedding_norm #print(normed_embedding.shape) # Extract view x, y, w, h = pt.rect_proto2pv( face_record.detection.location).asTuple() cx, cy = x + 0.5 * w, y + 0.5 * h tmp = 1.5 * max(w, h) cw, ch = tmp, tmp crop = pv.AffineFromRect(pv.CenteredRect(cx, cy, cw, ch), (256, 256)) #print (x,y,w,h,cx,cy,cw,ch,crop) pvim = pv.Image(img[:, :, ::-1]) # convert rgb to bgr pvim = crop(pvim) view = pt.image_pv2proto(pvim) face_record.view.CopyFrom(view) else: normed_embedding = np.zeros(512, dtype=float) face_record.template.data.CopyFrom( pt.vector_np2proto(normed_embedding))
def locateEyes(self, im, face_rects, ilog=None): ''' Finds the eyes in the image. @param im: full sized image @param face_rects: list of rectangle which are the output from the cascade face detector. ''' cvim = im.asOpenCVBW() faces = [] for rect in face_rects: faceim = cv.GetSubRect(cvim, rect.asOpenCV()) cv.Resize(faceim, self.bwtile) affine = pv.AffineFromRect(rect, (128, 128)) #cv.cvCvtColor( self.cvtile, self.bwtile, cv.CV_BGR2GRAY ) leye, reye, lcp, rcp = self.fel.locateEyes(self.bwtile) le = pv.Point(leye) re = pv.Point(reye) leye = affine.invertPoint(le) reye = affine.invertPoint(re) faces.append([rect, leye, reye]) if ilog != None: ilog.log(pv.Image(self.bwtile), label="FaceDetection") lcp = pv.OpenCVToNumpy(lcp).transpose() lcp = lcp * (lcp > 0.0) rcp = pv.OpenCVToNumpy(rcp).transpose() rcp = rcp * (rcp > 0.0) ilog.log(pv.Image(lcp), label="Left_Corr") ilog.log(pv.Image(rcp), label="Right_Corr") tmp = pv.Image(self.bwtile) tmp.annotatePoint(le) tmp.annotatePoint(re) ilog.log(tmp, "EyeLocations") return faces
def crop(self, rect, size=None, interpolation=None, return_affine=False): ''' Crops an image to the given rectangle. Rectangle parameters are rounded to nearest integer values. High quality resampling. The default behavior is to use cv.GetSubRect to crop the image. This returns a slice the OpenCV image so modifying the resulting image data will also modify the data in this image. If a size is provide a new OpenCV image is created for that size and cv.Resize is used to copy the image data. If the bounds of the rectangle are outside the image, an affine transform (pv.AffineFromRect) is used to produce the croped image to properly handle regions outside the image. In this case the downsampling quality may not be as good. # @param rect: a Rectangle defining the region to be cropped. @param size: a new size for the returned image. If None the result is not resized. @param interpolation: None = Autoselect or one of CV_INTER_AREA, CV_INTER_NN, CV_INTER_LINEAR, CV_INTER_BICUBIC @param return_affine: If True, also return an affine transform that can be used to transform points. @returns: a cropped version of the image or if return affine a tuple of (image,affine) @rtype: pv.Image ''' # Notes: pv.Rect(0,0,w,h) should return the entire image. Since pixel values # are indexed by zero this means that upper limits are not inclusive: x from [0,w) # and y from [0,h) x,y,w,h = rect.asTuple() x = int(np.round(x)) y = int(np.round(y)) w = int(np.round(w)) h = int(np.round(h)) # Check the bounds for cropping if size is None: size = (w,h) affine = pv.AffineFromRect(pv.Rect(x,y,w,h),size) im = affine(self) if return_affine: return im,affine else: return im
def findFaces(self, im): eye_processing = self.eye_menuitem.IsChecked() self.detect_time = time.time() rects = self.face_detector.detect(im) self.detect_time = time.time() - self.detect_time self.eye_time = time.time() if eye_processing: faces = self.fel.locateEyes(im, rects) else: faces = [] for rect in rects: affine = pv.AffineFromRect(rect, (1, 1)) leye = affine.invertPoint(AVE_LEFT_EYE) reye = affine.invertPoint(AVE_RIGHT_EYE) faces.append([rect, leye, reye]) self.eye_time = time.time() - self.eye_time self.current_faces = faces return faces
def crop(self, rect, size=None, interpolation=None, return_affine=False): ''' Crops an image to the given rectangle. Rectangle parameters are rounded to nearest integer values. High quality resampling. The default behavior is to use cv.GetSubRect to crop the image. This returns a slice the OpenCV image so modifying the resulting image data will also modify the data in this image. If a size is provide a new OpenCV image is created for that size and cv.Resize is used to copy the image data. If the bounds of the rectangle are outside the image, an affine transform (pv.AffineFromRect) is used to produce the croped image to properly handle regions outside the image. In this case the downsampling quality may not be as good. # @param rect: a Rectangle defining the region to be cropped. @param size: a new size for the returned image. If None the result is not resized. @param interpolation: None = Autoselect or one of CV_INTER_AREA, CV_INTER_NN, CV_INTER_LINEAR, CV_INTER_BICUBIC @param return_affine: If True, also return an affine transform that can be used to transform points. @returns: a cropped version of the image or if return affine a tuple of (image,affine) @rtype: pv.Image ''' # Notes: pv.Rect(0,0,w,h) should return the entire image. Since pixel values # are indexed by zero this means that upper limits are not inclusive: x from [0,w) # and y from [0,h) x, y, w, h = rect.asTuple() x = int(np.round(x)) y = int(np.round(y)) w = int(np.round(w)) h = int(np.round(h)) # Check the bounds for cropping if x < 0 or y < 0 or x + w > self.size[0] or y + h > self.size[1]: if size is None: size = (w, h) affine = pv.AffineFromRect(pv.Rect(x, y, w, h), size) im = affine(self) if return_affine: return im, affine else: return im # Get the image as opencv cvim = self.asOpenCV() # Set up ROI subim = cv.GetSubRect(cvim, (x, y, w, h)) affine = pv.AffineTranslate(-x, -y, (w, h)) if size is None: size = (w, h) # Copy to new image new_image = cv.CreateImage(size, cvim.depth, cvim.nChannels) if interpolation is None: if size[0] < w or size[1] < y: # Downsampling so use area interpolation interpolation = cv.CV_INTER_AREA else: # Upsampling so use linear interpolation = cv.CV_INTER_CUBIC # Resize to the correct size cv.Resize(subim, new_image, interpolation) affine = pv.AffineNonUniformScale( float(size[0]) / w, float(size[1]) / h, size) * affine # Return the result as a pv.Image if return_affine: return pv.Image(new_image), affine else: return pv.Image(new_image)
def raw_detections(self, im): ''' Run the face detectors with additional quality parameters. ''' W, H = im.size scale = 1.0 / self.prescale im = im.scale(self.prescale) faces = self.fd(im) faces = [[scale * rect, 'FACE'] for rect in faces] heads = self.hd(im) # Approximate face locations from head detections hfaces = [] for each in heads: # Get the center of the head location x, y, w, _ = each.asCenteredTuple() y = y - 0.10 * w w = 0.33 * w hfaces.append([scale * pv.CenteredRect(x, y, w, w), 'HEAD']) # Compute when face and head detections overlap for face in faces: best_overlap = 0.0 for head in hfaces: best_overlap = max(best_overlap, face[0].similarity(head[0])) if best_overlap > 0.7: face.append(1.0) else: face.append(0.0) # Compute when face and head detections overlap for head in hfaces: best_overlap = 0.0 for face in faces: best_overlap = max(best_overlap, head[0].similarity(face[0])) if best_overlap > 0.7: head.append(1.0) else: head.append(0.0) detections = faces + hfaces # Compute some simple statistics for each in detections: tile = pv.AffineFromRect(self.prescale * each[0], (128, 128))(im) #tile.show() # face vs head detection each.append(1.0 * (each[1] == 'FACE')) # size relative to image each.append(np.sqrt(each[0].area()) / np.sqrt(W * H)) each.append(np.sqrt(each[0].area()) / np.sqrt(W * H)**2) # scaled contrast each.append(tile.asMatrix2D().std() / 255.0) each.append((tile.asMatrix2D().std() / 255.0)**2) # scaled brightness each.append(tile.asMatrix2D().mean() / 255.0) each.append((tile.asMatrix2D().mean() / 255.0)**2) # relative rgb intensity rgb = tile.asMatrix3D() t = rgb.mean() + 0.001 # grand mean regularized # rgb relative to grand mean r = -1 + rgb[0, :, :].mean() / t g = -1 + rgb[1, :, :].mean() / t b = -1 + rgb[2, :, :].mean() / t # create a quadradic model with interactions for rgb each += [r, g, b, r * r, r * g, r * b, g * g, g * b, b * b] return detections
def processDetections(each): im, results, options = each if results.done(): recs = results.result().face_records i = 0 for face in recs: global FACE_COUNT FACE_COUNT += 1 # Filter faces based on min size size = min(face.detection.location.width, face.detection.location.height) if size < options.min_size: continue # Filter faces based on attributes if not processAttributeFilter(face, options): continue # Process Detections if options.detections_csv is not None: global DETECTIONS_CSV global DETECTIONS_FILE import csv if DETECTIONS_CSV == None: DETECTIONS_FILE = open(options.detections_csv, 'w') DETECTIONS_CSV = csv.writer(DETECTIONS_FILE) DETECTIONS_CSV.writerow([ 'source', 'frame', 'detect_id', 'type', 'score', 'x', 'y', 'w', 'h' ]) DETECTIONS_CSV.writerow([ face.source, face.frame, i, face.detection.detection_class, face.detection.score, face.detection.location.x, face.detection.location.y, face.detection.location.width, face.detection.location.height ]), DETECTIONS_FILE.flush() # Process Detections if options.attributes_csv is not None: global ATTRIBUTES_CSV global ATTRIBUTES_FILE import csv if ATTRIBUTES_CSV == None: ATTRIBUTES_FILE = open(options.attributes_csv, 'w') ATTRIBUTES_CSV = csv.writer(ATTRIBUTES_FILE) ATTRIBUTES_CSV.writerow([ 'source', 'frame', 'detect_id', 'type', 'score', 'x', 'y', 'w', 'h', 'attribute', 'value' ]) attributes = list(face.attributes) attributes.sort(key=lambda x: x.key) for attribute in attributes: key = attribute.key value = attribute.fvalue ATTRIBUTES_CSV.writerow([ face.source, face.frame, i, face.detection.detection_class, face.detection.score, face.detection.location.x, face.detection.location.y, face.detection.location.width, face.detection.location.height, key, value, ]), ATTRIBUTES_FILE.flush() # Save Images with Detections # Save Detected Faces face_out_dir = "" if options.face_log: if not os.path.exists(options.face_log): os.makedirs(options.face_log, exist_ok=True) #print(face.detection.location) rect = pt.rect_proto2pv(face.detection.location) rect = rect.rescale(1.5) affine = pv.AffineFromRect(rect, (128, 128)) try: pvim = pv.Image(im[:, :, ::-1]) view = affine(pvim) #print('Face',rect) #print(view) base_name, ext = os.path.splitext( os.path.basename(face.source)) out_path = os.path.join( options.face_log, os.path.basename(base_name) + '_face_%03d' % (face.detection.detection_id, ) + ext) view.save(out_path) print('Saving face:', out_path) except: print("WARNING: Image not processed correctly:", face.source) out_path = os.path.join( options.face_log, os.path.basename(base_name) + '_orig' + ext) if not os.path.lexists(out_path): os.symlink(os.path.abspath(face.source), out_path) #print(options.face_log) #pass i += 1 return False return True
def extract(self, img, face_records): '''Extract a template that allows the face to be matched.''' # Compute the 128D vector that describes the face in img identified by # shape. In general, if two face descriptor vectors have a Euclidean # distance between them less than 0.6 then they are from the same # person, otherwise they are from different people. Here we just print # the vector to the screen. im = pv.Image(img[:, :, ::-1]) for face_record in face_records.face_records: rect = pt.rect_proto2pv(face_record.detection.location) x, y, w, h = rect.asTuple() # Extract view rect = pv.Rect() cx, cy = x + 0.5 * w, y + 0.5 * h tmp = 1.5 * max(w, h) cw, ch = tmp, tmp crop = pv.AffineFromRect(pv.CenteredRect(cx, cy, cw, ch), (256, 256)) pvim = pv.Image(img[:, :, ::-1]) # convert rgb to bgr pvim = crop(pvim) view = pt.image_pv2proto(pvim) face_record.view.CopyFrom(view) # Extract landmarks l, t, r, b = [int(tmp) for tmp in [x, y, x + w, y + h]] d = dlib.rectangle(l, t, r, b) shape = self.shape_pred(img, d) for i in range(len(shape.parts())): loc = shape.parts()[i] landmark = face_record.landmarks.add() landmark.landmark_id = "point_%02d" % i landmark.location.x = loc.x landmark.location.y = loc.y # Get detection rectangle and crop the face #rect = pt.rect_proto2pv(face_record.detection.location).rescale(1.5) #tile = im.crop(rect) tile = pvim.resize((224, 224)) #tile.show(delay=1000) face_im = tile.asOpenCV2() face_im = face_im[:, :, ::-1] # Convert BGR to RGB #mat_ = cv2.cvtColor(mat,cv2.COLOR_RGB2GRAY) #mat = cv2.cvtColor(mat_,cv2.COLOR_GRAY2RGB) #img = image.load_img('../image/ajb.jpg', target_size=(224, 224)) from keras_vggface import utils from keras.preprocessing import image face_im = image.img_to_array(face_im) face_im = np.expand_dims(face_im, axis=0) face_im = utils.preprocess_input(face_im, version=2) # or version=2 # Needed in multithreaded applications with self.graph.as_default(): tmp = self.recognizer.predict(face_im) face_descriptor = pv.meanUnit(tmp.flatten()) #print('shape:',face_records.face_records[0].landmarks) #face_descriptor = self.face_rec.compute_face_descriptor(img, shape, JITTER_COUNT) #face_descriptor = np.array(face_descriptor) #vec = face_descriptor.flatten() face_record.template.data.CopyFrom( pt.vector_np2proto(face_descriptor))