Python scikit-learn提供自定义培训数据

时间:2016-03-24 10:12:04

标签: python numpy scikit-learn

我开始使用scikit-learn来进行面部识别。我已经尝试了提供的示例here并且正常工作。我现在正在尝试使用自己的包含图像的自定义数据来测试面部识别。我正在使用here的面部数据库。我现在坚持将这些图像作为训练集加载到我的程序中。我使用下面的代码加载所有图片:

    # get the training data


def read_images(path, sz=None):
    """Reads the images in a given folder, resizes images on the fly if size is given.

    Args:
        path: Path to a folder with subfolders representing the subjects (persons).
        sz: A tuple with the size Resizes 

    Returns:
        A list [X,y]

            X: The images, which is a Python list of numpy arrays.
            y: The corresponding labels (the unique number of the subject, person) in a Python list.
    """
    c = 0
    X, y = [], []
    for dirname, dirnames, filenames in os.walk(path):
        for subdirname in dirnames:
            subject_path = os.path.join(dirname, subdirname)
            for filename in os.listdir(subject_path):
                try:
                    im = Image.open(os.path.join(subject_path, filename))
                    im = im.convert("L")
                    # resize to given size (if given)
                    if (sz is not None):
                        im = im.resize(sz, Image.ANTIALIAS)
                    X.append(np.asarray(im, dtype=np.uint8))
                    y.append(c)
                except IOError, (errno, strerror):
                    print("I/O error({0}): {1}".format(errno, strerror))
                except:
                    print("Unexpected error:", sys.exc_info()[0])
                    raise
            c = c+1
    return [X, y]

if __name__ == '__main__':
    if len(sys.argv) < 3:
        print('No image supplied.')
        sys.exit()

    # Now read in the image data. This must be a valid path!
    [X, y] = read_images(sys.argv[1])

    print(len(X), len(y))

    X_train = np.vstack(X)
    print(X_train)
    y_train = np.array(y)

    image_path = sys.argv[2]
    image = np.array(cv2.imread(image_path), dtype=np.uint8)
    if np.ndim(image) == 3:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    image = cv2.equalizeHist(image)
    # create a CLAHE object (Arguments are optional).
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    image = clahe.apply(image)

    # detect face in this image
    detector = FaceDetector()
    X_test = []
    for i, d in enumerate(detector.detect(image)):
        x, y, w, h = d.left(), d.top(), d.right() - \
            d.left(), d.bottom() - d.top()
        a = image[y:(y+h), x:(x+w)]
        b = cv2.resize(a, (130, 130), interpolation=cv2.INTER_CUBIC)
        X_test.append(np.asarray(b, dtype=np.uint8))

    X_test = np.vstack(X_test)

    ##########################################################################
    # Compute a PCA (eigenfaces) on the face dataset (treated as unlabeled
    # dataset): unsupervised feature extraction / dimensionality reduction

    n_components = 150

    print('Extracting the top {} eigenfaces from faces'.format(n_components))
    t0 = time()
    pca = RandomizedPCA(n_components=n_components, whiten=True).fit(X_train)
    print("done in %0.3fs" % (time() - t0))

    print("Projecting the input data on the eigenfaces orthonormal basis")
    t0 = time()
    X_train_pca = pca.transform(X_train)
    **X_test_pca = pca.transform(X_test)**
    print("done in %0.3fs" % (time() - t0))

    ##########################################################################
    # Train a SVM classification model

    print("Fitting the classifier to the training set")
    t0 = time()
    param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5],
                  'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }
    clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)
    clf = clf.fit(X_train_pca, y_train)
    print("done in %0.3fs" % (time() - t0))
    print("Best estimator found by grid search:")
    print(clf.best_estimator_)

    ##########################################################################
    # Quantitative evaluation of the model quality on the test set

    print("Predicting people's names on the test set")
    t0 = time()
    y_pred = clf.predict(X_test_pca)
    print("done in %0.3fs" % (time() - t0))

在此之后,我还会得到一个针对上述示例运行的测试图像: 产生错误的行是 X_test_pca = pca.transform(X_test)

错误是:

ValueError: operands could not be broadcast together with shapes (130,130) (92,)

我怀疑这与我的数据格式不正确有关。

1 个答案:

答案 0 :(得分:0)

这是因为您的X_train,您已用于训练您的pca,即行:

pca = RandomizedPCA(n_components=n_components, whiten=True).fit(X_train)

,有92个原始列/功能,而您的X_test有130个功能。您可以在此行手动为测试数据提供130的大小:

b = cv2.resize(a, (130, 130), interpolation=cv2.INTER_CUBIC)

一旦你纠正了这一点,你应该没事。