我目前正在进行我的机器人学毕业设计项目,决定创建一个能够复制人类情感的开源机器人。机器人已经完全设置好并准备接收指令,但我还在忙于编写代码。我目前基于这个方法进行编码。想法是从低帧率视频 feeds(使用RPi Camera V2)中提取68个面部特征点,将这些特征点输入到训练好的SVM分类器中,并根据检测到的表情(愤怒、厌恶、恐惧、快乐、悲伤、惊讶和中性)返回0到6之间的数字。我正在使用RPi Camera拍摄的一些图片测试我的模型能力,以下是我目前在代码方面所做的工作:
# import the necessary packagesfrom imutils import face_utilsimport dlibimport cv2import numpy as npimport timeimport argparseimport osimport sysif sys.version_info >= (3, 0): import _pickle as cPickleelse: import cPicklefrom sklearn.svm import SVCfrom sklearn.metrics import accuracy_scorefrom data_loader import load_data from parameters import DATASET, TRAINING, HYPERPARAMSdef get_landmarks(image, rects): if len(rects) > 1: raise BaseException("TooManyFaces") if len(rects) == 0: raise BaseException("NoFaces") return np.matrix([[p.x, p.y] for p in predictor(image, rects[0]).parts()])# initialize dlib's face detector (HOG-based) and then create# the facial landmark predictorprint("Initializing variables...")p = "shape_predictor_68_face_landmarks.dat"detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor(p)# path to pretrained modelpath = "saved_model.bin"# load pretrained modelprint("Loading model...")model = cPickle.load(open(path, 'rb'))# initialize final image height & widthheight = 48width = 48# initialize landmarks variable as empty arraylandmarks = []# load the input image and convert it to grayscaleprint("Loading image...")gray = cv2.imread("foo.jpg")# detect faces in the grayscale imageprint("Detecting faces in loaded image...")rects = detector(gray, 0)# loop over the face detectionsprint("Looping over detections...")for (i, rect) in enumerate(rects): # determine the facial landmarks for the face region, then # convert the facial landmark (x, y)-coordinates to a NumPy # array shape = predictor(gray, rect) shape = face_utils.shape_to_np(shape) # loop over the (x, y)-coordinates for the facial landmarks # and draw them on the image for (x, y) in shape: cv2.circle(gray, (x, y), 2, (0, 255, 0), -1)# show the output image with the face detections + facial landmarksprint("Storing saved image...")cv2.imwrite("output.jpg", gray)print("Image stored as /'output.jpg/'")# arrange landmarks in arrayprint("Collecting and arranging landmarks...")# scipy.misc.imsave('temp.jpg', image)# image2 = cv2.imread('temp.jpg')face_rects = [dlib.rectangle(left=1, top=1, right=47, bottom=47)]landmarks = get_landmarks(gray, face_rects)# load dataprint("Loading collected data into predictor...")print("Extracted landmarks: ", landmarks)landmarks = np.array(landmarks.flatten())# predict expressionprint("Making prediction")predicted = model.predict(landmarks)
然而,在运行代码后,一切似乎都正常,直到这一点:
Making predictionTraceback (most recent call last): File "face.py", line 97, in <module> predicted = model.predict(landmarks) File "/usr/local/lib/python2.7/dist-packages/sklearn/svm/base.py", line 576, in predict y = super(BaseSVC, self).predict(X) File "/usr/local/lib/python2.7/dist-packages/sklearn/svm/base.py", line 325, in predict X = self._validate_for_predict(X) File "/usr/local/lib/python2.7/dist-packages/sklearn/svm/base.py", line 478, in _validate_for_predict (n_features, self.shape_fit_[1]))ValueError: X.shape[1] = 136 should be equal to 2728, the number of features at training time
我在这个网站上搜索了类似的问题,但由于这是非常特定的用途,我并没有找到我需要的东西。我已经在设计和研究上花了相当长的时间,但找到所有需要的代码片段来使代码工作花费了我最多的时间,我希望尽快完善这个概念,因为展示日期很快就要到了。任何和所有的贡献都是非常受欢迎的!
回答:
解决了!原来我的模型是使用HOG特征和Dlib landmarks的组合进行训练的,但是我只将landmarks输入到预测器中,导致了大小差异。