Search code examples
pythonnumpypython-imaging-library

Given a target aspect ratio, how to crop into image, framing around a found face


I have 800x800 portrait image and want to crop into it, finding the face and "framing it" in the centre, while maintaining a 3:4 aspect ratio (outline select box).

So I almost need to calculate some kind of "centre point" of the calculated top, bottom, left and right and crop into that point (red dots).

enter image description here

I believe I'm someway off reaching this goal as my python isn't particularly good - here's what I have so far:

cropped_face_image = numpy.array(PIL.Image.open(BytesIO(image.content)))[
    top:bottom, left:right
]
pil_image = PIL.Image.fromarray(cropped_face_image)
pil_image.show()

This just hard-crops the face from the image.


Solution

  • You could do something like this:

    from PIL import Image
    im = Image.open('FlKyDm.png.jpeg')
    top, bottom, left, right = 95, 177 , 70, 150
    
    # Calculate centre of face and box
    centreX, centreY = int((left+right)/2), int((top+bottom)/2)
    
    # Calculate face width
    faceW = right - left
    
    # Calculate half width of box and half height of box
    boxHalfW = faceW
    boxHalfH = int((boxHalfW * 4) / 3)
    
    # Crop accordingly
    res = im.crop((centreX-boxHalfW, centreY-boxHalfH, centreX+boxHalfW, centreY+boxHalfH))
    res.save('result.jpg')
    

    enter image description here