1

I am running this code to detect the nose and get its position in real time. I was able to detect the face and draw the points of the landmarks.However I couldn't figure out how I can get the positions of a specific landmark in terms of x and y. Can anyone please help me

here is my code

import cv2 as cv
import mediapipe as mp
import time

cap = cv.VideoCapture(0)
if not cap.isOpened():
    print("camera-failed")
    exit()
pTime = 0
mpDraw = mp.solutions.drawing_utils
mpFaceMesh = mp.solutions.face_mesh
faceMesh = mpFaceMesh.FaceMesh(max_num_faces=1)
drawSpec = mpDraw.DrawingSpec(thickness=1,circle_radius=1)
while True:
    ret, img = cap.read()
    imgRGB = cv.cv2.cvtColor(img, cv.COLOR_BGRA2RGB)
    results = faceMesh.process(imgRGB)
    if results.multi_face_landmarks:
        for faceLms in results.multi_face_landmarks:
            mpDraw.draw_landmarks(img,faceLms,mpFaceMesh.FACEMESH_CONTOURS,
                                  drawSpec,drawSpec)
            for id, lm in enumerate(faceLms.landmark):
                print(lm)
                ih, iw, ic = img.shape
                x,y,z= int(lm.x*iw),int(lm.y*ih),int(lm.z*ic)
                print(id,x,y,z)


    cTime = time.time()
    fps = 1/(cTime-pTime)
    pTime = cTime
    cv.putText(img, f'FPS: {int(fps)}',(20,70), cv.FONT_HERSHEY_PLAIN,
               3,(0,255,0),3)
    if not ret:
        print("Error exiting...")
        break
        exit()
    cv.imshow( "image",img)
    if cv.waitKey(1) == ord('q'):
        break
cap.release()
cv.destroyAllWindows()

1 Answers1

0

You have already obtained pixel coordinates x, y here:

for id, lm in enumerate(faceLms.landmark):
    print(lm)
    ih, iw, ic = img.shape
    x,y,z= int(lm.x*iw),int(lm.y*ih),int(lm.z*ic)
    print(id,x,y,z)

MediaPipe does not provide absolute coordinates (because it has no means to do so since it also depends on the intrinsic properties of the camera). If you want to get the values of specific landmarks, you can filter them by IDs:

for id, lm in enumerate(faceLms.landmark):
    print(lm)
    ih, iw, ic = img.shape
    x,y,z= int(lm.x*iw),int(lm.y*ih),int(lm.z*ic)
    print(id,x,y,z)

    if id in [5, 4]: # simply check the ID
        cv.circle(img, (x, y), radius=3, color=(225, 0, 100), thickness=1)

Refer to the official landmark map in order to find out the IDs of the landmark that are of interest to you: MediaPipe FaceMesh landmark IDs (Landmarks 4,5 represent the nose tip, but there are many more landmarks related to the nose).

Also, please note that you code contains a typo (you have probably fixed it already): cv.cv2.cvtColor should be cv.cvtColor.

Stefan
  • 355
  • 2
  • 6