Search code examples
pythonopencvimage-processingcomputer-visiontransparency

Make an image background transparent


I have an image with an orange and a white background. I want to make the white background transparent. The code below uses grabcut to make a mask. I then split the image into rgb channels and apply the mask on the alpha channel. You'll see from images below that post-grabcut and mask images are OK. I haven't been able to figure out how to apply the mask to the alpha channel. Suggestions appreciated.

    im = cv2.imread(sourceimagefile)
    cv2.imshow('original',im)
    mask = np.zeros(im.shape[:2],np.uint8)
    rect = (box[0][0], box[0][1], box[0][2]-box[0][0], box[0][3]-box[0][1])
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    cv2.grabCut(im,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
    if len(np.where((mask==3)|(mask==1))[0])>0:
        mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
        mask2 = np.repeat(mask2[:,:,np.newaxis],3,axis=2)
    else:
        mask2 = np.zeros_like(im)
        mask2[box[0][1]:box[0][3],box[0][0]:box[0][2],:] = 1
    im2 = im*mask2
    cv2.imshow('post-grabcut',im2)
    minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(mask)
    flag, mask = cv2.threshold(mask, maxVal-1, 255, cv2.cv.CV_THRESH_BINARY)
    cv2.imshow("mask", mask)
    b, g, r = cv2.split(im2)
    img_RGBA = cv2.merge((b, g, r, mask))
    cv2.imshow("final",img_RGBA)

originalpost-grabcutmaskfinal


Solution

  • according to an older SO question, imshow doesn't actually support alpha channels http://jepsonsblog.blogspot.com/2012/10/overlay-transparent-image-in-opencv.html but this is an old post and support MAY have been added, but i do not know for sure