Python: OpenCVを使用して、アメ横を行き交う人々の顔にモザイクをかける

今までやってきたことを応用して、アメ横を行き交う人々の顔にモザイクをかけていきます。

  • Python: OpenCVを使用して動画を読み込んで、何もせず書き込む1
  • Python: OpenCVを使用して動画を読み込んで、何もせず書き込む2
  • Python: OpenCVを使用して顔検出をする
  • すべてのフレームについて、それぞれ顔検出をし、モザイクをかけていきます。

    import cv2
    import numpy as np
    
    cascade = cv2.CascadeClassifier('/usr/local/lib64/python3.7/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')
    
    def mosaic(img):
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        rects = cascade.detectMultiScale(gray, 1.1, 1, 0, (5,5))
        if len(rects) > 0:
            for rect in rects:
                x, y, w, h = rect
                face = img[y:y+h, x:x+w]
                dst = cv2.GaussianBlur(face, (25, 25), 10)
                img[y:y+h, x:x+w] = dst
        return img
                
    cap = cv2.VideoCapture('./img.MOV')
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
    out = cv2.VideoWriter('output.m4v', fourcc, fps, (height, width))
    
    while True:
        ret, frame = cap.read()
        if ret:
            frame270 = np.rot90(frame, 3)
            out.write(mosaic(frame270))
        else:
            break
    
    cap.release()
    out.release()
    

    実行してみましたが、角度によって顔として検出されない場合があり、モザイクがチカチカしてしまいます。そこで、少し強引な手法ですが、顔検出した位置について、その後の15フレームについてモザイクをかけるようにしました。

    import cv2
    import numpy as np
    
    cascade = cv2.CascadeClassifier('/usr/local/lib64/python3.7/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')
    
    def mosaic(img, rects_list):
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        rects = cascade.detectMultiScale(gray, 1.1, 1, 0, (5,5))
        rects_list.append(rects)
        for rects in rects_list:
            for rect in rects:
                x, y, w, h = rect
                face = img[y:y+h, x:x+w]
                dst = cv2.GaussianBlur(face, (25, 25), 10)
                img[y:y+h, x:x+w] = dst
        return img, rects
                
    cap = cv2.VideoCapture('./img.MOV')
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
    out = cv2.VideoWriter('output.m4v', fourcc, fps, (height, width))
    
    rects_list = []
    while True:
        ret, frame = cap.read()
        if ret:
            frame270 = np.rot90(frame, 3)
            mosaiced_frame, rects = mosaic(frame270, rects_list[-15:])
            rects_list.append(rects)
            out.write(mosaiced_frame)
        else:
            break
    
    cap.release()
    out.release()
    

    結果は以下の通りです。


    無事モザイクをかけることができました。

    コメントする

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です