简体   繁体   English

如何标记OpenCV中两个阵列中都存在的功能?

[英]How to mark features which are present in both arrays in OpenCV?

I'm trying to write a Python 3.7 script to detect faces and features using the OpenCV Haar classifier files which stores images as n-dimensional Numpy arrays. 我正在尝试编写一个Python 3.7脚本来使用OpenCV Haar分类器文件检测面部和特征,该文件将图像存储为n维Numpy数组。 Right now I'm only working with two features: - The entire face - The eyes Both of these are obtained using two different classifiers. 现在,我仅使用两个功能:-整个脸部-眼睛这两个都是使用两个不同的分类器获得的。 The Code detects the presence of both these features in the image and then marks them with a rectangle using the cv2.rectangle() function inside a for loop for each feature ie, one for detected faces and one for detected eyes. 代码检测图像中这两个特征的存在,然后使用for循环内的cv2.rectangle()函数为每个特征将它们标记为矩形,例如,一个用于检测到的脸部,一个用于检测到的眼睛。

I want the script to mark the eye-rectangles ONLY if those points were found in the face array as well as the eye array. 我只希望脚本在面部阵列和眼睛阵列中找到这些点时才标记眼睛矩形。 numpy.intersect1d() only finds intersection within one-dimensional arrays. numpy.intersect1d()仅在一维数组中找到交集。

I've even tried 我什至尝试过

for x,y,w,h in eyes and x,y,w,h in faces:

and all it does is return this error message: 它所做的就是返回此错误消息:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Any help would be greatly appreciated. 任何帮助将不胜感激。

This is being attempted on Windows 10 64-bit, the code is written in Pycharm 2019, OpenCV is imported as CV2. 这是在Windows 10 64位上尝试的,代码是用Pycharm 2019编写的,OpenCV被导入为CV2。

# Creating the cascade classifier objects.
face_cascade = 
cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier("haarcascade_eye.xml")

# Entering and displaying the original image.
img = cv2.imread("filename.jpg", 1)
cv2.imshow("Original Images",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# Convert the image to Black and White and store in a variable.
gry_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(gry_img, scaleFactor = 1.05, minNeighbors = 8)
eyes = eye_cascade.detectMultiScale(gry_img, scaleFactor = 1.30, minNeighbors = 12)

# Now, we mark the detected features with a rectangle on the original image.
for x,y,w,h in faces:
    img = cv2.rectangle(img, (x,y), (x+w, y+h), (255, 21, 21), 3) # Blue.


for x,y,w,h in eyes:
    img = cv2.rectangle(img, (x,y), (x+w, y+h), (255, 255, 24), 3) # Cyan.

cv2.imshow("Detected Faces and Eyes",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

I need the eye-features to be marked only if they were ALSO found in the face-features array. 我只需要在人脸特征数组中也找到人眼特征时对其进行标记。

A better approach to solve this problem is already suggested in the OpenCV docs . OpenCV文档中已经提出了解决此问题的更好方法。 It suggests that instead of passing the whole image for detecting the eyes, you should first detect the face, then crop the image, and use this cropped image for eyes detection. 它建议您应该先检测面部,然后裁剪图像,然后将裁剪后的图像用于眼睛检测,而不是通过整个图像来检测眼睛。 For cropping the face image you can use numpy slicing as: 为了裁剪人脸图像,您可以使用numpy切片:

for x,y,w,h in faces:
    face_img = gry_img[y:y+h, x:x+w]
    # Now detect the eyes in this `face_img` only.
    eyes = eye_cascade.detectMultiScale(face_img, scaleFactor = 1.30, minNeighbors = 12)

Oh boy, do I feel stupid now. 哦,男孩,我现在觉得很蠢。 Well here goes: 好吧:

As ZdaR said, the OpenCV documentation does indeed give a perfect example on how to achieve the result I required, the gist of which is: 正如ZdaR所说,OpenCV文档确实为如何实现所需的结果提供了一个完美的例子,其要旨是:

for x,y,w,h in faces:
    face_img = gry_img[y:y+h, x:x+w]
    # Now detect the eyes in this `face_img` only.
    eyes = eye_cascade.detectMultiScale(face_img, scaleFactor = 1.30, minNeighbors = 12)

What I needed to do other than this, apparently was to crop the original image to the face coordinates as well for the eye-features to be drawn upon. 除此以外,我需要做的显然是将原始图像也裁剪到面部坐标上,以吸引人的眼睛特征。 I'm still not sure if this should work, but for now it seems that adding that extra line does work. 我仍然不确定这是否行得通,但是目前看来,添加额外的行确实行得通。

Code that finally worked: 最终有效的代码:

faces = face_cascade.detectMultiScale(gry_img, scaleFactor = 1.05, minNeighbors = 10)
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y),(x + w, y + h), (255, 0, 0), 3)
    gry_eye = gry_img[y:y+h, x:x+w]
    eye_img = img[y:y + h, x:x + w]
    eyes = eye_cascade.detectMultiScale(gry_eye, scaleFactor = 1.05, minNeighbors = 5)
    for (x, y, w, h) in eyes:
        cv2.rectangle(eye_img, (x, y), (x + w, y + h), (255, 255, 24), 3)

Well, this has been a learning experience. 好吧,这是一种学习经验。 Thanks to ZdaR for the help! 感谢ZdaR的帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 opencv 考勤系统将学生标记为存在于 csv 问题 - opencv attendance system mark student as present in csv problem 如何标记学生在场/缺席python - How to mark a student present/absent python 如何将 NumPy 特征和标签 arrays 转换为 TensorFlow 数据集,可用于 Z20F35E630DAF44DF854C3。 - How to convert NumPy features and labels arrays to TensorFlow Dataset which can be used for model.fit()? 如何使用分水岭 opencv 在图像上标记标签 - how to mark the labels on image using watershed opencv 如何使用 Opencv 缩小/扩大面部特征? - How to shrink/expand facial features using Opencv? OpenCV:如何使用cv2.CascadeClassifier获得功能? - OpenCV: How to get features with cv2.CascadeClassifier? Python - 比较两列功能,返回两者不相同的值 - Python - Compare two columns of features, return values which are not common to both 如何从列表中提取 numpy arrays(对),该列表受条件取决于对中的两个元素? - How to extract numpy arrays (pairs) from a list which are subjected to condition depending on both the elements in pair? 如何为python版本2和3构建OpenCV? - How to build OpenCV for both python versions 2 and 3? 如何使用opencv-python标记中心并计算图像的直径? - How to mark the center and calculate the diameter of an image using opencv - python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM