Search code examples
pythonimageopencvpython-imaging-libraryaffinetransform

Why the image color is changed after affine transform using PIL?


I am using image.transform in the Python Imaging Library to apply affine transform to a image of face detection to calibration the face accordding to the position of eyes. The result is right but the color of the image is changed like below. Why? The code is following. The last two line is the call of tranform function.

def ScaleRotateTranslate(image, angle, center = None, new_center = None, scale = None, resample=Image.NEAREST):
    if (scale is None) and (center is None):
        return image.rotate(angle=angle, resample=resample)
    nx,ny = x,y = center
    sx=sy=1.0
    if new_center:
        (nx,ny) = new_center
    if scale:
        (sx,sy) = (scale, scale)
    cosine = math.cos(angle)
    sine = math.sin(angle)
    a = cosine/sx
    b = sine/sx
    c = x-nx*a-ny*b
    d = -sine/sy
    e = cosine/sy
    f = y-nx*d-ny*e
    return image.transform(image.size, Image.AFFINE, (a,b,c,d,e,f), resample=resample)

def Distance(p1,p2):
    dx = p2[0] - p1[0]
    dy = p2[1] - p1[1]
    return math.sqrt(dx*dx+dy*dy)



image_center = ((eye_left[0]+eye_right[0])/2,(eye_left[1]+eye_right[1])/2)
rotatedImg = ScaleRotateTranslate(pilIm,center=image_center,angle=rotation)

enter image description here

enter image description here


Solution

  • Tried this:

    import Image
    import math
    
    def ScaleRotateTranslate(image, angle, center = None, new_center = None, scale = None, resample=Image.NEAREST):
        if (scale is None) and (center is None):
            return image.rotate(angle=angle, resample=resample)
        nx,ny = x,y = center
        sx=sy=1.0
        if new_center:
            (nx,ny) = new_center
        if scale:
            (sx,sy) = (scale, scale)
        cosine = math.cos(angle)
        sine = math.sin(angle)
        a = cosine/sx
        b = sine/sx
        c = x-nx*a-ny*b
        d = -sine/sy
        e = cosine/sy
        f = y-nx*d-ny*e
        return image.transform(image.size, Image.AFFINE, (a,b,c,d,e,f), resample=resample)
    
    def Distance(p1,p2):
        dx = p2[0] - p1[0]
        dy = p2[1] - p1[1]
        return math.sqrt(dx*dx+dy*dy)
    
    
    pilIm = Image.open('/Users/carlos/Downloads/image.jpg').convert('RGB');
    eye_left = (10,10)
    eye_right = (40,30)
    rotation = 0.3;
    
    image_center = ((eye_left[0]+eye_right[0])/2,(eye_left[1]+eye_right[1])/2)
    rotatedImg = ScaleRotateTranslate(pilIm,center=image_center,angle=rotation)
    rotatedImg.save('out.jpg')
    

    Got this:

    enter image description here

    So I guess, the answer is it works for me. Try checking your installation of PIL and that you're using RGB encoding.