我创建了一个可以识别和裁剪人脸的 Python 代码。但问题是它随机裁剪面部,而不是按照包含所有面部的原始图像中的顺序。 请注意:代码从上到右按顺序裁剪面部,直到到达最后一个面部。
请将代码放在名为 (输入图像) 的文件夹中,其中包含包含收集的人脸的图像。 并创建一个名为 Output Images 的文件夹来存储裁剪后的脸部。 使用人脸识别xml文件 haarcascade_frontalface_default.xml text
代码:
import os
import cv2
import numpy as np
import os, os.path
# Load the cascade classifier
#download this here https://raw.githubusercontent.com/opencv/opencv/4.x/data/haarcascades/haarcascade_frontalface_default.xml just go there and ctrl + s
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
#rename a file
#for dirname in os.listdir("."):
# if os.path.isdir(dirname):
# for i, filename in enumerate(os.listdir(dirname)):
# os.rename(dirname + "/" + filename, dirname + "/" + str(i) + ".jpg")
# Read the input image
img = cv2.imread("Input Images/image.jpg")
#let's double the size of our image
img_double=cv2.resize(img,None,fx=1,fy=1,interpolation=cv2.INTER_CUBIC)
# let's do the resizing by exact dimensions
image_resize=cv2.resize(img,(600,700),interpolation=cv2.INTER_AREA)
# Convert into grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Detect faces
faces = face_cascade.detectMultiScale( gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(150, 150), )
# loop over all detected faces
if len(faces) > 0:
for i, (x,y,w,h) in enumerate(faces):
#face = img[y:y+h, x:x+w]
face = img[y-65:y+h+40,x-40:x+w+55]
# cv2.imshow(f"Cropped Face {i}", face)
cv2.imwrite("Output Images/" f'0{i}.jpg', face)
print(f"0{i}.jpg is saved")
# concatenate image Vertically
#Verti = np.concatenate((img, img), axis=0)
# Number of all detected faces
print("[INFO] Found {0} Faces.".format(len(faces)))
# display the image with detected faces
cv2.imshow('scaling_exact',image_resize)
cv2.waitKey(0)
cv2.destroyAllWindows()
请要求:代码从上到右按顺序裁剪面部,直到到达最后一个面部。 示例
这是一个排序任务。
假设您已找到所有面部框,现在计算每个框的中心。我们将与这些中心点合作。
您会假设这些点形成一个网格。
您不知道行数,因此您必须计算。
为此,我们将 Y 坐标聚类为 k=1..N 个簇,对于最小的 k,使得所有簇都具有“低”方差。如果一个簇必须保存多于一行,则其方差将明显大于保存单行的簇。
对于该阈值,我将在此处使用
200
,因为行之间的距离比该阈值更远,并且每行中 Y 的变化远低于该阈值。
import numpy as np
from sklearn.cluster import KMeans
# some points I picked out of your picture
boxes = np.array([
[ 90, 166, 180, 312],
[ 485, 205, 148, 258],
[ 853, 183, 182, 288],
[1229, 220, 186, 294],
[1647, 222, 158, 256],
[2024, 178, 132, 250],
[ 71, 894, 162, 280],
[ 460, 867, 166, 302],
[ 849, 921, 174, 336],
[1254, 918, 180, 318],
[1612, 932, 204, 304],
[2009, 905, 188, 302],
[ 86, 1643, 152, 298],
[ 435, 1600, 210, 284],
[ 825, 1569, 208, 336],
[1256, 1616, 170, 304],
[1605, 1586, 182, 284],
[2008, 1606, 190, 292],
[ 71, 2310, 160, 284],
[ 448, 2313, 214, 274],
[ 836, 2387, 168, 278],
[1237, 2362, 172, 298],
[1624, 2346, 180, 260],
[2020, 2327, 174, 232]])
points = boxes[:, 0:2] + boxes[:, 2:4] / 2
np.random.shuffle(points)
def find_least_k(values, threshold):
for k in range(1, len(values) + 1):
kmeans = KMeans(n_clusters=k, random_state=0).fit(values.reshape(-1, 1))
centers = kmeans.cluster_centers_.flatten()
labels = kmeans.labels_
stddevs = np.array([values[labels == i].std() for i in range(k)])
if stddevs.max() < threshold:
return k, centers, labels
Y_values = points[:, 1]
best_k, centers, labels = find_least_k(Y_values, threshold=200)
# sorting the rows
permutation = np.argsort(centers)
invperm = np.argsort(permutation)
centers = centers[permutation]
labels = invperm[labels]
points_by_row = [
points[labels == i]
for i in range(best_k)
]
points_sorted = np.array([
row[np.argsort(row[:, 0])]
for row in points_by_row
])
输入、输出: