3

I have a program that detects floors, so the floors I detect are removed and become a transparent png, but there are still black lines around the edges

before adding threshold

enter image description here

enter image description here

src = cv2.imread(file_name)
    
tmp = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
_,alpha = cv2.threshold(tmp,0, 255, cv2.THRESH_BINARY)
 b, g, r = cv2.split(src)
 rgba = [b,g,r, alpha]
 dst = cv2.merge(rgba,1)
    

1 Answers1

4

You can mitigate the effect of the black transition line in Python/OpenCV/Skimage by antialiasing the alpha channel as follows:

  • Read the image with alpha
  • Extract the bgr base image
  • Extract the alpha channel
  • Gaussian blur the alpha channel (choose the blur amount so as to match the black transition)
  • Stretch the dynamic range of the alpha channel so that 255 -> 255 and mid-gray goes to 0 and save as mask. (Choose the mid-gray level to mitigate further)
  • Put the resulting mask image into the alpha channel of the bgr image
  • Save the results

Input:

enter image description here

import cv2
import numpy as np
import skimage.exposure

# load image with alpha
img = cv2.imread('room.png', cv2.IMREAD_UNCHANGED)

# extract only bgr channels
bgr = img[:, :, 0:3]

# extract alpha channel
alpha = img[:, :, 3]

# apply Gaussian blur to alpha
blur = cv2.GaussianBlur(alpha, (0,0), sigmaX=5, sigmaY=5, borderType = cv2.BORDER_DEFAULT)

# stretch so that 255 -> 255 and 192 -> 0
mask = skimage.exposure.rescale_intensity(blur, in_range=(192,255), out_range=(0,255)).astype(np.uint8)

# put mask into alpha channel
result = np.dstack((bgr, mask))

# save result
cv2.imwrite('room_new_alpha.png', result)

# display result, though it won't show transparency
cv2.imshow("bgr", bgr)
cv2.imshow("alpha", alpha)
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:

enter image description here

fmw42
  • 46,825
  • 10
  • 62
  • 80
  • 1
    Instead of using `skimage.exposure.rescale_intensity`, can one use `cv2.normalize`? Just asking to avoid dependency on multiple libraries. Good idea BTW +1 – Jeru Luke Apr 12 '22 at 14:24
  • 2
    I do not think cv2.normalize has the functionality needed. normType=NORM_MINMAX will stretch min and max to the alpha and beta values, but you have no control of the input values to use for the stretch. It automatically just uses the min and max values. rescale_intensity is much easier to use and has the full functionality of allowing you to choose the input value or take the min and max values and to specify the output values, all in an easy to use interface. – fmw42 Apr 12 '22 at 16:00