10

我想知道是否有一种方法可以模糊 haarcascade 人脸分类器自动识别的人脸。

使用下面的代码,我可以检测人脸,裁剪这张脸周围的图像或在上面画一个矩形。

image = cv2.imread(imagepath)

# Specify the trained cascade classifier
face_cascade_name = "./haarcascade_frontalface_alt.xml"

# Create a cascade classifier
face_cascade = cv2.CascadeClassifier()

# Load the specified classifier
face_cascade.load(face_cascade_name)

#Preprocess the image
grayimg = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
grayimg = cv2.equalizeHist(grayimg)

#Run the classifiers
faces = face_cascade.detectMultiScale(grayimg, 1.1, 2, 0|cv2.cv.CV_HAAR_SCALE_IMAGE, (30, 30))

print "Faces detected"

if len(faces) != 0:            # If there are faces in the images
    for f in faces:         # For each face in the image

        # Get the origin co-ordinates and the length and width till where the face extends
        x, y, w, h = [ v for v in f ]

        # Draw rectangles around all the faces
        cv2.rectangle(image, (x,y), (x+w,y+h), (255,255,255))
        sub_face = image[y:y+h, x:x+w]
        for i in xrange(1,31,2):
            cv2.blur(sub_face, (i,i))
        face_file_name = "./face_" + str(y) + ".jpg"
        cv2.imwrite(face_file_name, sub_face)

但我想模糊人们的脸,使他们无法被识别。

你知道如何做到这一点吗?

谢谢你的帮助

阿尔诺

4

3 回答 3

20

我终于成功地做了我想做的事。要做到这一点,请按照 Hammer 的建议应用 gaussianblur。代码是:

image = cv2.imread(imagepath)
result_image = image.copy()

# Specify the trained cascade classifier
face_cascade_name = "./haarcascade_frontalface_alt.xml"

# Create a cascade classifier
face_cascade = cv2.CascadeClassifier()

# Load the specified classifier
face_cascade.load(face_cascade_name)

#Preprocess the image
grayimg = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
grayimg = cv2.equalizeHist(grayimg)

#Run the classifiers
faces = face_cascade.detectMultiScale(grayimg, 1.1, 2, 0|cv2.cv.CV_HAAR_SCALE_IMAGE, (30, 30))

print "Faces detected"

if len(faces) != 0:         # If there are faces in the images
    for f in faces:         # For each face in the image

        # Get the origin co-ordinates and the length and width till where the face extends
        x, y, w, h = [ v for v in f ]

        # get the rectangle img around all the faces
        cv2.rectangle(image, (x,y), (x+w,y+h), (255,255,0), 5)
        sub_face = image[y:y+h, x:x+w]
        # apply a gaussian blur on this new recangle image
        sub_face = cv2.GaussianBlur(sub_face,(23, 23), 30)
        # merge this blurry rectangle to our final image
        result_image[y:y+sub_face.shape[0], x:x+sub_face.shape[1]] = sub_face
        face_file_name = "./face_" + str(y) + ".jpg"
        cv2.imwrite(face_file_name, sub_face)

# cv2.imshow("Detected face", result_image)
cv2.imwrite("./result.png", result_image)

阿尔诺

于 2013-08-06T12:28:08.360 回答
11

您的代码的整个结尾可以替换为:

img[startX:endX, startY:endY] = cv2.blur(img[startX:endX, startY:endY], (23, 23))

代替 :

    # Get the origin co-ordinates and the length and width till where the face extends
    x, y, w, h = [ v for v in f ]

    # get the rectangle img around all the faces
    cv2.rectangle(image, (x,y), (x+w,y+h), (255,255,0), 5)
    sub_face = image[y:y+h, x:x+w]
    # apply a gaussian blur on this new recangle image
    sub_face = cv2.GaussianBlur(sub_face,(23, 23), 30)
    # merge this blurry rectangle to our final image
    result_image[y:y+sub_face.shape[0], x:x+sub_face.shape[1]] = sub_face

特别是因为你不要求有一个圆形面具,它(对我来说)更容易阅读。

PS:抱歉没有发表评论,没有足够的声誉来做这件事。即使该帖子已有 5 年历史,我想这可能是值得的,因为为这个特定问题找到了它..

于 2019-04-12T08:25:22.337 回答
0

注意:神经网络(如 Resnet)现在比 HAAR Cascade 更准确地检测人脸,并且它们现在也集成在 OpenCV 中。它可能比使用这个问题中提到的解决方案更好。

但是,模糊/像素化面部的代码仍然适用。


您还可以通过添加包含面部区域 RGB 值平均值的正方形来像素化面部区域。

执行此操作的函数可能是这样的:

def pixelate_image(image: np.ndarray, nb_blocks=5, in_place=False) -> np.ndarray:
    """Return a pixelated version of a picture (need to be fed with a face to pixelate)"""
    # To pixelate, we will split into a given number of blocks
    # For each block, we will compute the average of RGB values of the block
    # And then we can just replace with a rectangle of this color
    # divide the input image into NxN blocks
    if not in_place:
        image = np.copy(image)
    h, w = image.shape[:2]
    blocks = tuple(
        np.linspace(0, d, nb_blocks + 1, dtype="int") for d in (w, h)
    )

    for i, j in product(*[range(1, len(s)) for s in blocks]):
        # compute the starting and ending (x, y)-coordinates
        # for the current block
        start = blocks[0][i - 1], blocks[1][j - 1]
        end = blocks[0][i], blocks[1][j]
        # extract the ROI using NumPy array slicing, compute the
        # mean of the ROI, and then draw a rectangle with the
        # mean RGB values over the ROI in the original image
        roi = image[start[1]:end[1], start[0]:end[0]]
        bgr = [int(x) for x in cv2.mean(roi)[:3]]
        cv2.rectangle(image, start, end, bgr, -1)

    return image

然后你只需要在这样的函数中使用它(更新到 Python 3pathlib并输入提示):

from pathlib import Path
from typing import Union

import cv2
import numpy as np

PathLike = Union[Path, str]

face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")

def pixelate_faces_haar(img_path: PathLike, dest: Path):
    """Pixelate faces of people with OpenCV and save to a destination file"""
    img = cv2.imread(str(img_path))
    # To use cascade, we need to use Grayscale images
    # We can then detect faces
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.1, 4)

    for (x, y, width, height) in faces:
        roi = img[y:y+height, x:x+width]
        pixelate_image(roi, 15, in_place=True)

    dest.parent.mkdir(parents=True, exist_ok=True)
    cv2.imwrite(str(dest), img)
    print(f"Saved pixelated version of {img_path} to {dest}")```
于 2021-10-07T14:40:13.190 回答