【问题标题】:How to create a transparent mask in opencv-python如何在 opencv-python 中创建透明蒙版
【发布时间】:2019-06-02 14:02:18
【问题描述】:

我有白色背景的标志(任意形状的标志)图像,我想获得具有透明背景的标志图像。

我设法创建了一个蒙版并将其应用于图像,并认为使蒙版透明是可行的。我在这里和其他地方搜索了很多,但没有任何帮助。

import cv2
import numpy as np

file_name = "/path/to/input/img/Unbenannt.jpg" # can be also .png

img = cv2.imread(file_name)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th, threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)

_, roi, _ = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

mask = np.zeros(img.shape, img.dtype)

cv2.fillPoly(mask, roi, (255,)*img.shape[2], )

masked_image = cv2.bitwise_and(img, mask)

cv2.imwrite("/path/to/output/mask_test.png", masked_image)

输入:

电流输出:

如前所述,我想让背景透明。

非常感谢您的帮助。

【问题讨论】:

  • 您好,谢谢您的回答。是的,以前见过。但它一开始还是没有用。无论如何,我同时想通了,并将在考试阶段之后(〜二月中旬)在这里发布解决方案;)

标签: transparency mask opencv-python


【解决方案1】:

对于较新的 OpenCV 版本

import cv2
import numpy as np

file_name = "/path/to/img.png"

def cut(img):
  # crop image
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  th, threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)

  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
  morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)

  cnts, _ = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  cnt = sorted(cnts, key=cv2.contourArea)[-1]
  x,y,w,h = cv2.boundingRect(cnt)
  new_img = img[y:y+h, x:x+w]

  return new_img        

def transBg(img):   
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  th, threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)

  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
  morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)

  roi, _ = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

  mask = np.zeros(img.shape, img.dtype)

  cv2.fillPoly(mask, roi, (255,)*img.shape[2], )

  masked_image = cv2.bitwise_and(img, mask)

  return masked_image

def fourChannels(img):
  height, width, channels = img.shape
  if channels < 4:
    new_img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
    return new_img

  return img

s_img = cv2.imread(file_name, -1)

# set to 4 channels
s_img = fourChannels(s_img)

# remove white background
s_img = cut(s_img)

# set background transparent
s_img = transBg(s_img)

cv2.imwrite("/path/to/store/img.png", s_img)

【讨论】:

    【解决方案2】:

    我发现我必须将图像转换为 BGRA 才能获得透明背景。我还添加了一种将图像剪切到其边界矩形的方法。正如所承诺的,工作代码:

    import cv2
    import numpy as np
    
    file_name = "/path/to/img.png"
    
    def cut(img):
      # crop image
      gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
      th, threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)
    
      kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
      morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)
    
      _, cnts, _ = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
      cnt = sorted(cnts, key=cv2.contourArea)[-1]
      x,y,w,h = cv2.boundingRect(cnt)
      new_img = img[y:y+h, x:x+w]
    
      return new_img        
    
    def transBg(img):   
      gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
      th, threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)
    
      kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
      morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)
    
      _, roi, _ = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
      mask = np.zeros(img.shape, img.dtype)
    
      cv2.fillPoly(mask, roi, (255,)*img.shape[2], )
    
      masked_image = cv2.bitwise_and(img, mask)
    
      return masked_image
    
    def fourChannels(img):
      height, width, channels = img.shape
      if channels < 4:
        new_img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
        return new_img
    
      return img
    
    s_img = cv2.imread(file_name, -1)
    
    # set to 4 channels
    s_img = fourChannels(s_img)
    
    # remove white background
    s_img = cut(s_img)
    
    # set background transparent
    s_img = transBg(s_img)
    
    cv2.imwrite("/path/to/store/img.png", s_img)
    

    输入是:

    输出是透明背景的图像:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-25
      • 1970-01-01
      • 2012-03-07
      • 2014-03-27
      • 2016-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多