gpt4 book ai didi

python ,OpenCV : classify gender using ORB features and KNN

转载 作者:太空宇宙 更新时间:2023-11-03 11:31:20 25 4
gpt4 key购买 nike

任务:将人脸图像分类为女性或男性。提供带标签的训练图像,从网络摄像头获取测试图像。

使用:Python 2.7、OpenCV 2.4.4

我正在使用 ORB 从灰度图像中提取特征,希望将其用于训练 K 最近邻分类器。每个训练图像都是不同的人,因此每个图像的关键点和描述符的数量明显不同。我的问题是我无法理解 KNN 和 ORB 的 OpenCV 文档。我看过其他关于 ORB、KNN 和 FLANN 的 SO 问题,但它们并没有太大帮助。

ORB给出的描述符到底是什么性质?它与通过 BRIEF、SURF、SIFT 等获得的描述符有何不同?

KNN 中的每个训练样本的特征描述符似乎应该具有相同的大小。如何确保每个图像的描述符大小相同?更一般地说,应该以什么格式将特征呈现给 KNN,以便使用给定的数据和标签进行训练?数据应该是 int 还是 float?可以是炭吗?

可以找到训练数据here .

我还使用来自 opencv 示例的 haarcascade_frontalface_alt.xml

目前,KNN 模型仅获得 10 张图像进行训练,以查看我的程序是否无误地通过,但事实并非如此。

这是我的代码:

import cv2
from numpy import float32 as np.float32

def chooseCascade():
# TODO: Option for diferent cascades
# HAAR Classifier for frontal face
_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
return _cascade

def cropToObj(cascade,imageFile):
# Load as 1-channel grayscale image
image = cv2.imread(imageFile,0)

# Crop to the object of interest in the image
objRegion = cascade.detectMultiScale(image) # TODO: What if multiple ojbects in image?

x1 = objRegion[0,0]
y1 = objRegion[0,1]
x1PlusWidth = objRegion[0,0]+objRegion[0,2]
y1PlusHeight = objRegion[0,1]+objRegion[0,3]

_objImage = image[y1:y1PlusHeight,x1:x1PlusWidth]

return _objImage

def recognizer(fileNames):
# ORB contructor
orb = cv2.ORB(nfeatures=100)

keyPoints = []
descriptors = []

# A cascade for face detection
haarFaceCascade = chooseCascade()

# Start processing images
for imageFile in fileNames:
# Find faces using the HAAR cascade
faceImage = cropToObj(haarFaceCascade,imageFile)

# Extract keypoints and description
faceKeyPoints, faceDescriptors = orb.detectAndCompute(faceImage, mask = None)

#print faceDescriptors.shape
descRow = faceDescriptors.shape[0]
descCol = faceDescriptors.shape[1]

flatFaceDescriptors = faceDescriptors.reshape(descRow*descCol).astype(np.float32)

keyPoints.append(faceKeyPoints)
descriptors.append(flatFaceDescriptors)

print descriptors

# KNN model and training on descriptors
responses = []
for name in fileNames:
if name.startswith('BF'):
responses.append(0) # Female
else:
responses.append(1) # Male

knn = cv2.KNearest()
knnTrainSuccess = knn.train(descriptors,
responses,
isRegression = False) # isRegression = false, implies classification

# Obtain test face image from cam
capture = cv2.VideoCapture(0)
closeCamera = -1
while(closeCamera < 0):
_retval, _camImage = capture.retrieve()

# Find face in camera image
testFaceImage = haarFaceCascade.detectMultiScale(_camImage) # TODO: What if multiple faces?

# Keyponts and descriptors of test face image
testFaceKP, testFaceDesc = orb.detectAndCompute(testFaceImage, mask = None)
testDescRow = testFaceDesc.shape[0]
flatTestFaceDesc = testFaceDesc.reshape(1,testDescRow*testDescCol).astype(np.float32)

# Args in knn.find_nearest: testData, neighborhood
returnedValue, result, neighborResponse, distance = knn.find_nearest(flatTestFaceDesc,3)

print returnedValue, result, neighborResponse, distance


# Display results
# TODO: Overlay classification text
cv2.imshow("testImage", _camImage)

closeCamera = cv2.waitKey(1)
cv2.destroyAllWindows()


if __name__ == '__main__':
fileNames = ['BF09NES_gray.jpg',
'BF11NES_gray.jpg',
'BF13NES_gray.jpg',
'BF14NES_gray.jpg',
'BF18NES_gray.jpg',
'BM25NES_gray.jpg',
'BM26NES_gray.jpg',
'BM29NES_gray.jpg',
'BM31NES_gray.jpg',
'BM34NES_gray.jpg']

recognizer(fileNames)

目前,我在 knn.train() 行遇到错误,其中 descriptors 未被检测为 numpy 数组。

另外,这种做法是不是完全错误?我应该使用其他方式进行性别分类吗?我对 opencv facerec 演示中的 fisherface 和 eigenface 示例不满意,所以请不要将我指向那些。

非常感谢任何其他帮助。谢谢。

--- 编辑 ---

我已经尝试了一些事情并得出了答案。

我仍然希望 SO 社区中的某个人可以通过提出一个想法来帮助我,这样我就不必将内容硬编码到我的解决方案中。我还怀疑 knn.match_nearest() 没有做我需要它做的事情。

正如预期的那样,识别器根本不准确,并且很容易因旋转、光照等原因而产生错误分类。非常感谢任何有关改进此方法的建议。

我用于训练的数据库是:Karolinska Directed Emotional Faces

最佳答案

我对所描述方法的有效性/可行性存有一些疑问。这是您可能要考虑的另一种方法。 gen 文件夹的内容是@ http://www1.datafilehost.com/d/0f263abc .正如您将注意到的,当数据量变大时(~10k 训练样本),模型的大小可能变得 Not Acceptable (~100-200mb)。那么您将需要研究 pca/lda 等。

import cv2
import numpy as np
import os

def feaCnt():
mat = np.zeros((400,400,3),dtype=np.uint8)
ret = extr(mat)
return len(ret)

def extr(img):
return sobel(img)

def sobel(img):
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
klr = [[-1,0,1],[-2,0,2],[-1,0,1]]
kbt = [[1,2,1],[0,0,0],[-1,-2,-1]]
ktb = [[-1,-2,-1],[0,0,0],[1,2,1]]
krl = [[1,0,-1],[2,0,-2],[1,0,-1]]
kd1 = [[0,1,2],[-1,0,1],[-2,-1,0]]
kd2 = [[-2,-1,0],[-1,0,1],[0,1,2]]
kd3 = [[0,-1,-2],[1,0,-1],[2,1,0]]
kd4 = [[2,1,0],[1,0,-1],[0,-1,-2]]
karr = np.asanyarray([
klr,
kbt,
ktb,
krl,
kd1,
kd2,
kd3,
kd4
])
gray=cv2.resize(gray,(40,40))
res = np.float32([cv2.resize(cv2.filter2D(gray, -1,k),(15,15)) for k in karr])
return res.flatten()


root = 'C:/data/gen'

model='c:/data/models/svm/gen.xml'
imgs = []
idx =0
for path, subdirs, files in os.walk(root):
for name in files:
p =path[len(root):].split('\\')
p.remove('')
lbl = p[0]
fpath = os.path.join(path, name)
imgs.append((fpath,int(lbl)))
idx+=1

samples = np.zeros((len(imgs),feaCnt()),dtype = np.float32)
labels = np.zeros(len(imgs),dtype = np.float32)

i=0.
for f,l in imgs:
print i
img = cv2.imread(f)
samples[i]=extr(img)
labels[i]=l
i+=1

svm = cv2.SVM()
svmparams = dict( kernel_type = cv2.SVM_POLY,
svm_type = cv2.SVM_C_SVC,
degree=3.43,
gamma=1.5e-4,
coef0=1e-1,
)
print 'svm train'
svm.train(samples,labels,params=svmparams)
svm.save(model)
print 'done'

result = np.float32( [(svm.predict(s)) for s in samples])
correct=0.
total=0.

for i,j in zip(result,labels):
total+=1
if i==j:
correct+=1
print '%f'%(correct/total)

关于 python ,OpenCV : classify gender using ORB features and KNN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19224300/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com