Replacing cv2 face detection photo with overlayed image

Question:

I have used cv2 to detect my eyes from an uploaded image, but I’d like to paste an image on top of where cv2 detected my face.

View cv2 eye detection photo output here:

View cv2 eye detection photo output here

But instead of outputting the cv2 rectangles around my eyes, I’d like to replace it with an image. Is there a way to paste an image on top of where cv2 detected my eyes?

My python script

import os
import numpy as np
import cv2
from os.path import join, dirname, realpath
from flask import Flask, render_template, request, redirect, url_for, abort
from werkzeug.utils import secure_filename

def upload_files():
    uploaded_file = request.files['file']
    filename = secure_filename(uploaded_file.filename)
    if filename != '':
        file_ext = os.path.splitext(filename)[1]
        if file_ext not in app.config['UPLOAD_EXTENSIONS'] or 
                file_ext != validate_image(uploaded_file.stream):
            abort(400)
        uploaded_file.save('new.png')
   
    face_cascade = cv2.CascadeClassifier('/haarcascade_eye.xml')
    eye_cascade = cv2.CascadeClassifier('/haarcascade_eye.xml')

    img = cv2.imread('new.png')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
         cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
         roi_gray = gray[y:y+h, x:x+w]
         roi_color = img[y:y+h, x:x+w]
         eyes = eye_cascade.detectMultiScale(roi_gray)
         for (ex,ey,ew,eh) in eyes:
             cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
    cv2.imwrite("out.png", img)

Keep in mind that the script above produces this output:

photo output.

I would like to remove the rectangles and use cv2 to paste an image where cv2 detected my eyes.

Asked By: mattwelter

||

Answers:

I think that this is what you’re looking for:

import os
import numpy as np
import cv2
from os.path import join, dirname, realpath

def upload_files():
   
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')

    img = cv2.imread('face.jpg')
    img_to_place = cv2.imread('img.png')

    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    gray_to_place = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    img_h, img_w = gray.shape
    img_to_place_h, img_to_place_w = gray_to_place.shape

    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]
        eyes = eye_cascade.detectMultiScale(roi_gray)
        for (ex,ey,ew,eh) in eyes:
            resized_img = cv2.resize(img_to_place, (eh, ew), interpolation = cv2.INTER_AREA)
            resized_img_h, resized_img_w, _ = resized_img.shape

            roi_color[ey:ey+resized_img_h, ex:ex+resized_img_w, :] = resized_img

    cv2.imwrite('out.png', img)

upload_files()

Basically, you load the image you want to put in your eyes, resize it to ROI size, and put it in the coordinates of where the rectangle would be.

Example:

enter image description here

Answered By: Lucius
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.