PCA求取特征脸

本文介绍了一个基于OpenCV的PCA图像识别实战案例,通过读取ORL数据集中的图像,进行灰度转换,然后使用PCA算法进行特征提取和降维。文章详细展示了如何使用OpenCV的PCA类进行计算,包括样本数据的输入、PCA计算、特征向量的读取和转换,以及特征脸的显示。
摘要由CSDN通过智能技术生成
#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
#include <string>

using namespace cv;
using namespace std;

void main() {

	int nsamples = 0;    //样本(图片)个数
	int w = 92;          //图片宽度(假定所有样本已知且统一)
	int h = 112;         //图片高度(假定所有样本已知且统一)

	string datasetfile;  //样本集文件路径
	string file;         //样本文件路径

	ifstream infile;

	Mat img, gray;
	Mat input;           //一个样本
	Mat inputs;          //样本数据矩阵
	Mat result;

	PCA pca;

	//1.输入样本数据
	cout << "Input the path of dataset file: ";
	cin >> datasetfile;
	infile.open(datasetfile.c_str());

	if (infile) {
		do {
			getline(infile, file);
			img = imread(file);

			cvtColor(img, gray, CV_BGR2GRAY);
			input = gray.reshape(1, 1);
			inputs.push_back(input);

			getline(infile, file);
		} while (!infile.eof());

		//2.进行PCA的相关计算

		//opencv的PCA类输入矩阵的数据类型要求为float型,既CV_32FC1或CV_64FC1
		inputs.convertTo(inputs, CV_32FC1);

		//最后的参数10,保留前10个最大的特征值及其对应的特征向量
		pca(inputs, Mat(), CV_PCA_DATA_AS_ROW, 10);

		//读取协方差矩阵的特征向量,并转换成样本(图片)的原尺寸h*w
		//row(0)表示读取第一个(特征值最大)的特征向量
		result = pca.eigenvectors.row(0);
		result = result.reshape(result.channels(), h);

		//将向量元素值的范围从浮点值映射到0~255,并将数据类型转换成unsigned char
		normalize(result, result, 0, 255, NORM_MINMAX, CV_8UC1);

		//显示一张特征脸
		imshow("eigenface1", result);
		waitKey();
	}
	else {
		cout << "error: unable to open input dataset file "<< endl;
	}
}

数据集文件样式(采用ORL数据集):
在这里插入图片描述
实验结果:
在这里插入图片描述

PCA(Principal Component Analysis)是一种常用的数据降维方法,而特征脸PCA在图像处理中的应用。下面是PCA特征脸的Python实现: 1.导入必要的库和数据 ```python import numpy as np import cv2 import os # 读取图像数据 def read_images(path, sz=None): 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: if not filename.endswith('.pgm'): continue filepath = os.path.join(subject_path, filename) im = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE) if sz is not None: im = cv2.resize(im, sz) X.append(np.asarray(im, dtype=np.uint8)) y.append(c) except IOError as e: print("I/O error({0}): {1}".format(e.errno, e.strerror)) except: print("Unexpected error:", sys.exc_info()[0]) raise c = c+1 return [X,y] ``` 2.计算特征脸 ```python # 计算特征脸 def compute_eigenface(X): # 将图像数据转换为矩阵 X = np.asarray(X) # 计算均值脸 mean_face = X.mean(axis=0) # 将每个样本向量减去均值脸 X = X - mean_face # 计算协方差矩阵 cov = np.dot(X.T, X) # 计算特征值和特征向量 eigenvalues, eigenvectors = np.linalg.eig(cov) # 将特征向量按照特征值从大到小排序 idx = eigenvalues.argsort()[::-1] eigenvectors = eigenvectors[:,idx] # 取前k个特征向量 k = 10 topk_evecs = eigenvectors[:,:k] # 计算特征脸 eigenface = np.dot(X, topk_evecs) return eigenface, topk_evecs, mean_face ``` 3.计算训练样本在特征脸空间的投影 ```python # 计算训练样本在特征脸空间的投影 def compute_eigen_train_sample(normTrainFaceMat, eigenface): eigen_train_sample = np.dot(normTrainFaceMat, eigenface) return eigen_train_sample ``` 4.计算测试样本在特征脸空间的投影 ```python # 计算测试样本在特征脸空间的投影 def compute_eigen_test_sample(normTestFaceMat, eigenface): eigen_test_sample = np.dot(normTestFaceMat, eigenface) return eigen_test_sample ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值