zoukankan      html  css  js  c++  java
  • python 图片4通道转3通道 (转换RBGA图片成RGB) (python image 4 channels conver to 3 channels (convert RGBA image to RGB ))

    最近,在进行图像处理时候,拿到了用 adobe photoshop 处理的 png 图片, 当我用 ubuntu 电脑打开该图片的时候,就发现了图片出现了如下的阴影,查阅了资料才发现原来是因为在使用 adobe photoshop 设计图片的时候背景内容选择透明背景的原因,如果想要避免还要用代码进一步进行判断和处理,可以在生成图片的时候修改背景色为白色等.

    我在缩小该图片的时候发现图片全是黑色的,本以为没什么,但是后来在同事的指点下,发现这个问题是可以解决的,只要造成这个问题是因为导入的 png 图片包含了 alpha 通道,而我在读取该图片的时候没有进行相应的正确处理导致的.

    所以,我们先来大概了解下图像的 alpha 通道.

    (1) Alpha通道,范围0-1,用来存储这个像素点的透明度

    (2 ) 真正让图片变透明的不是A lpha 实际是 Alpha 所代表的数值和其他数值做了一次运算

    (3) Alpha 通道使用8位二进制数,就可以表示256级灰度,即256级的透明度。白色(值为255)的 Alpha 像素用以定义不透明的彩色像素,而黑色(值为0)的 Alpha 通道像素用以定义透明像素,介于黑白之间的灰度(值为0-255)的 Alpha 像素用以定义不同程度的半透明像素。

    (4) 将图片 a 绘制到另一幅图片 b 上,如果图片 a 没有 alpha 通道,那么就会完全将 b 图片的像素给替换掉。而如果有 alpha 通道,那么最后覆盖的结果值将是 c = a * alpha + b * (1 - alpha)

    参考资料: https://www.cnblogs.com/suogasus/p/5311264.html  https://blog.csdn.net/woniuye/article/details/89218461

    在了解了基本知识后,我查阅了很多资料想把 RGBA 图片抓换成 RGB 图片,看了很多都是使用图片库自带的图片类型转换库,比如 PIL 的 Image.open(img_path).convert('RGBA') 类似代码或者opencv使用 cv2.cvtColor(image, cv2.COLOR_RGBA2BGR) ,但是都不是我想要和效果,后来终于找到了正确的解决方法。

    参考资料: https://stackoverflow.com/questions/50331463/convert-rgba-to-rgb-in-python

    代码:

     1 import cv2
     2 import numpy as np
     3 import matplotlib.pyplot as plt
     4 
     5 
     6 def rgba2rgb(rgba, background=(255, 255, 255)):
     7     row, col, ch = rgba.shape
     8 
     9     if ch == 3:
    10         return rgba
    11 
    12     assert ch == 4, 'RGBA image has 4 channels.'
    13 
    14     # 生成一个三维画布图片
    15     rgb = np.zeros((row, col, 3), dtype='float32')
    16 
    17     # 获取图片每个通道数据
    18     r, g, b, a = rgba[:, :, 0], rgba[:, :, 1], rgba[:, :, 2], rgba[:, :, 3]
    19 
    20     # 把 alpha 通道的值转换到 0-1 之间
    21     a = np.asarray(a, dtype='float32') / 255.0
    22 
    23     # 得到想要生成背景图片每个通道的值
    24     R, G, B = background
    25 
    26     # 将图片 a 绘制到另一幅图片 b 上,如果有 alpha 通道,那么最后覆盖的结果值将是 c = a * alpha + b * (1 - alpha)
    27     rgb[:, :, 0] = r * a + (1.0 - a) * R
    28     rgb[:, :, 1] = g * a + (1.0 - a) * G
    29     rgb[:, :, 2] = b * a + (1.0 - a) * B
    30 
    31     # 把最终数据类型转换成 uint8
    32     return np.asarray(rgb, dtype='uint8')
    33 
    34 
    35 image_name_have_alpha = "huaxiao/tuxinghuaxiao/img/剪刀/0.png"
    36 
    37 image_have_alpha = cv2.imread(image_name_have_alpha, cv2.IMREAD_UNCHANGED)
    38 # 使用opencv自带的库把BGRA图片转换成BGR图片(注意,opencv读取进去的图片格式是 BGR)
    39 image_have_alpha_convert_bgr1 = cv2.cvtColor(image_have_alpha, cv2.COLOR_RGBA2BGR)
    40 # 使用自己的函数把BGRA图片转换成BGR图片,背景色设置为白色
    41 image_have_alpha_convert_bgr2 = rgba2rgb(image_have_alpha)
    42 # 使用自己的函数把BGRA图片转换成BGR图片,背景色设置为蓝色
    43 image_have_alpha_convert_bgr3 = rgba2rgb(image_have_alpha, background=(0, 0, 255))
    44 plt.figure()
    45 plt.subplot(2, 2, 1), plt.title("original image"), plt.imshow(image_have_alpha, "gray")
    46 plt.subplot(2, 2, 2), plt.title("use function of cv2"), plt.imshow(image_have_alpha_convert_bgr1, "gray")
    47 plt.subplot(2, 2, 3), plt.title("use function of myself"), plt.imshow(image_have_alpha_convert_bgr2, "gray")
    48 plt.subplot(2, 2, 4), plt.title("use function of myself"), plt.imshow(image_have_alpha_convert_bgr3, "gray")
    49 plt.show()

    结果如下:


    就这样解决了我的实际问题,不知道我说得全不全,如果大家觉得有什么不恰当的地方,欢迎指正和批评。

  • 相关阅读:
    Google Chrome 默认非安全端口列表
    js判断类型的方法
    博客园样式排版自定义
    easyloader.js源代码分析
    JQuery操作cookies
    js获取iframe里面的dom
    封装GetQueryString()方法来获取URL的value值
    js 获取系统时间:年月日 星期 时分秒(动态)
    vue 滚动加载数据
    props 父组件给子组件传递参数
  • 原文地址:https://www.cnblogs.com/ttweixiao-IT-program/p/14288425.html
Copyright © 2011-2022 走看看