Skip to content

Tutorials

Pig’s nose (Instagram face filter) – Opencv with Python

Access community, courses and source codes
Logo

AI Vision Academy

Access the code of this tutorial, computer vision courses and an exclusive community on AI Vision Academy

  • Access to over 50+ source codes from Pysource.com/blog
  • Dedicated video courses about computer vision
  • Access to an exclusive community of professionals
  • Real-World AI Projects – Get hands-on experience building practical AI Computer Vision solutions with a structured path.
  • Monthly Coaching Calls – get support and any of your questions answered

Subscribe to our newsletter to learn more

We’re going to see in this video how to create Instagram Face Filters using Opencv with Python.

Import the libaries and load the detectors (for face and face landmark points).

import cv2
import numpy as np
import dlib
from math import hypot

# Loading Camera and Nose image and Creating mask
cap = cv2.VideoCapture(0)
nose_image = cv2.imread("pig_nose.png")
_, frame = cap.read()
rows, cols, _ = frame.shape
nose_mask = np.zeros((rows, cols), np.uint8)

# Loading Face detector
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

We then run the while loop to get the frames in real time from the camera, we detect the face and face landmark points.

while True:
    _, frame = cap.read()
    nose_mask.fill(0)
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = detector(frame)
    for face in faces:
        landmarks = predictor(gray_frame, face)

Inside the loop we find the coordinate of the nose, the width and the height.
We define the position when we want to put the new cartoon pig’s nose.

        # Nose coordinates
        top_nose = (landmarks.part(29).x, landmarks.part(29).y)
        center_nose = (landmarks.part(30).x, landmarks.part(30).y)
        left_nose = (landmarks.part(31).x, landmarks.part(31).y)
        right_nose = (landmarks.part(35).x, landmarks.part(35).y)

        nose_width = int(hypot(left_nose[0] - right_nose[0],
                           left_nose[1] - right_nose[1]) * 1.7)
        nose_height = int(nose_width * 0.77)

        # New nose position
        top_left = (int(center_nose[0] - nose_width / 2),
                              int(center_nose[1] - nose_height / 2))
        bottom_right = (int(center_nose[0] + nose_width / 2),
                       int(center_nose[1] + nose_height / 2))

Finally we replace the are of the nose (of our face) with the nose of the pig from the image.

And we display everything on the screen.

        # Adding the new nose
        nose_pig = cv2.resize(nose_image, (nose_width, nose_height))
        nose_pig_gray = cv2.cvtColor(nose_pig, cv2.COLOR_BGR2GRAY)
        _, nose_mask = cv2.threshold(nose_pig_gray, 25, 255, cv2.THRESH_BINARY_INV)

        nose_area = frame[top_left[1]: top_left[1] + nose_height,
                    top_left[0]: top_left[0] + nose_width]
        nose_area_no_nose = cv2.bitwise_and(nose_area, nose_area, mask=nose_mask)
        final_nose = cv2.add(nose_area_no_nose, nose_pig)

        frame[top_left[1]: top_left[1] + nose_height,
                    top_left[0]: top_left[0] + nose_width] = final_nose

        cv2.imshow("Nose area", nose_area)
        cv2.imshow("Nose pig", nose_pig)
        cv2.imshow("final nose", final_nose)



    cv2.imshow("Frame", frame)



    key = cv2.waitKey(1)
    if key == 27:
        break

7 comments

  1. Thanks a lot for this great tutorial. I would like your help in understanding how to rotate the pig’s nose when we rotate our face.
    Thanks and regards
    Deepanjan

  2. Hey there! Thanks for this brilliant tutorial. Loved it!
    Anyway, I had a small doubt: I want to create a same filter that includes a ‘nose ring’ as an object to be placed on either sides of the nose. However, I wa able to create such an example successfully by following your tutorial. But, is there a way in which I can change the ‘x-scale’ of the object according to the rotation of one’s face? I mean, can I make the filter process dynamic for 3D movements? Like, if I look on the left side, the object should either be cut on the hidden portion or the size on the hidden side should decrease accordingly. Please let me know if there is something related to this. Thanks anyway!

Join the discussion