基于OpenCV性别识别

本文探讨了基于OpenCV的性别识别问题,主要算法包括SVM、BP神经网络、LDA和PCA。重点关注了Fisherfaces(LDA)方法在OpenCV官方文档中的应用,以及PCA+LDA在性别识别中的提升。尽管某些资源声称有高识别率,但在实际应用中,由于数据集限制,识别效果可能降低。通过自行采集和处理数据,以及对比PCA和PCA+LDA的效果,发现PCA在某些情况下可能提供更高的准确率。
摘要由CSDN通过智能技术生成

描述

所谓性别识别就是判断检测出来的脸是男性还是女性,是个二元分类问题。识别所用的算法可以是SVM,BP神经网络,LDA,PCA,PCA+LDA等等。OpenCV官网给出的文档是基于Fisherfaces检测器(LDA)方法实现的。链接:http://docs.opencv.org/modules/contrib/doc/facerec/tutorial/facerec_gender_classification.html#id5 。这篇博文(http://www.bytefish.de/blog/gender_classification/)中也是采用OpenCV官网的方法,据称有98%的正确率,我在百度图片找了一些数据测试了下,只有大概50%多的识别率。原因是他的数据集是经过严格标定的,好像是眼睛的是对齐的。实际应用中不太可能会遇到这种情况吧。CSDN还有两篇博客也介绍到这个性格识别(http://blog.csdn.net/kklots/article/details/8247738 http://blog.csdn.net/kklots/article/details/9285505)文章写得很好,一看就是大牛。博文中也是测试了LDA的方法,正确率也是出奇的低。采用的是PCA+LDA的方法。通过改进能达到接近90%的正确率。博文指出PCA+LDA比单纯的LDA和PCA识别率都高,但我对博文中的PCA+LDA程序和官网的PCA程序测试了下,发现PCA的正确率会高那么一两个点。难道又是数据的问题?

数据

采集数据一方面可以采用开源的人脸库,另一方面可以自己去百度图片下载图片。去百度或谷歌图片分别搜索“男明星头像”“女明星头像”的关键字批量下载,这里当然需要批量下载利器。然后利用人脸检测器过滤检测出头像,然后归一化检测出来的图像,保存在本地。这样基本的数据集就有了。当然我也会附上我采集的数据和工程文件(特此声明,所有图片均来自网络)

测试程序

创建CSV文件的python代码:

import sys
import os.path


if __name__ == "__main__":

    if len(sys.argv) != 3:
        print "usage: create_csv <base_path> <SAVE_FILE_NAME>"
        sys.exit(1)

    BASE_PATH=sys.argv[1]
    FILE_NAME = sys.argv[2]
    SEPARATOR=";"
    fh = open(FILE_NAME,'w')

    label = 0
    for dirname, dirnames, filenames in os.walk(BASE_PATH):
        for subdirname in dirnames:
            subject_path = os.path.join(dirname, subdirname)
            for filename in os.listdir(subject_path):
                abs_path = "%s/%s" % (subject_path, filename)
                ##print "%s%s%d" % (abs_path, SEPARATOR, label)
                ##print "%s  %s" % (dirname, subject_path)

                fh.write(abs_path)
                fh.write(SEPARATOR)
                if dirname.find("female") > 0 :
                    label = 1
                else:
                    label = 0
                fh.write(str(label))
                fh.write("\n")
    fh.close()

测试性别识别的程序

// gender.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
#include <math.h>
int g_howManyPhotoForTraining   =   260;
//每个人取出8张作为训练
int g_photoNumberOfOnePerson    =   279;
//ORL数据库每个人10张图像
using namespace cv;
using namespace std;

static Mat norm_0_255(InputArray _src) {
    Mat src = _src.getMat();
    // 创建和返回一个归一化后的图像矩阵:
    Mat dst;
    switch(src.channels()) {
case1:
        cv::normalize(_src, dst, 0,255, NORM_MINMAX, CV_8UC1);
        break;
case3:
        cv::normalize(_src, dst, 0,255, NORM_MINMAX, CV_8UC3);
        break;
    default:
        src.copyTo(dst);
        break;
    }
    return dst;
}
//使用CSV文件去读图像和标签,主要使用stringstream和getline方法
static void read_csv(
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值