SciTech-BigDataAIML-CV+CG-Digital Image Processing-编辑与合成RGBA图片与视频:RGB图片转换成RGBA:增加Alpha Mask(透明遮罩, 即Alpha Channel透明度通道)

层层堆叠RGBA图片层就可实时修改图片与视频流

用AI自动生成RGBA格式的PNG图片;一层层堆叠。
这也是Adobe Photoshop的Mask原理?

https://learnopencv.com/alpha-blending-using-opencv-cpp-python/
we will learn how to alpha blend two images and overlay a transparent PNG image over another image in OpenCV.
We are sharing code in both C++ and Python.

What is Alpha Blending?
Alpha blending is the process of overlaying a foreground image with transparency over a background image. Transparency is often the fourth channel of an image ( e.g. in a transparent PNG),
but it can also be a separate image. This transparency mask is often called the alpha mask or the alpha matte.

BGRA与BGR

  • BGRColor(颜色)数值化R(红色)G(绿色)B(蓝色) 三Channel(分量)每分量数值取值范围0-255
    通过组合这三个Color Channel(颜色分量)的不同数值,可以得到各种各样的颜色。

  • BGRA 的Color(颜色)数有R(红色)G(绿色)B(蓝色)A(透明度)四种分量.
    注意:PNG格式图片,才有BGRA
    BGR颜色模型的一种扩展只增加一个表示透明度(Alpha)透明分量(A)
    A代表Alpha通道,该通道决定像素的透明度,取值范围也是0-255。0: 透明度100%(rgb的色彩), 255:透明度0。
    因此 通过调整Alpha通道分量取值,可实现图像的半透明效果

图片尺寸

“图片长1920、宽1080”:略写的 单位pixels(像素点总数).
数字图片的“长宽”并非物理意义的长度单位,而是在图片“横”和“竖”这两个维度上包含的像素个数
比如,1920×1080的图片是由横向1920个像素、纵向1080个像素(合计2,073,600个像素)构成的。

图片分辨率(Image Resolution):

Pixel Density(像素密度):指 单位面积上的 像素数量单位dpi(dots per inch, 像素点/英寸)。

手机屏幕像素密度PPI

很大程度由 分辨率屏幕尺寸 决定,
引入概念: PPI(屏幕像素密度), 即屏幕斜对角线单位英寸像素点数
\(\large PPI = \frac{\sqrt{ HorizontalPixels_{pixel}^{2} + VerticalPixels_{pixel}^{2}} }{LengthOfDiagonalLine_{inch}}\)
PPI值越大,屏幕越清晰。

总结:

  • 屏幕尺寸: 屏幕对角线长度
    单位:英寸,1英寸等于2.54厘米

  • 分辨率: 横纵向方向像素的大小
    纵向像素横向像素,如1920px1080px
    单位:像素(px)

  • 像素密度: 指每英寸屏幕所拥有的像素的数量
    单位:dpi

  • 三者关系

  • 像素密度=Sqrt(横向像素数横向像素数+纵向像素数纵向像素数)/屏幕尺寸(对角线的长度inch)

  • 图像用的内存空间大小:分辨率 * 位深 / 8
    例如:一幅图像分辨率:1024768, 24位(所有通道位深的加和. 即38bit),则其用到的内存大小如下:
    大小 = 1024 * 768 * 24 / 8 = 2359296 byte = 2304 KB

  • 分辨率:宽 * 高

  • 位深度:指定图像的每个像素可以使用的颜色信息数量。如8bit 或 10bit
    每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就更逼真。

实例 为RGB图片增加Alpha Mask(透明遮罩)

#! /usr/bin/env python


import os, sys
import itertools as it
import collections as ct
import cv2 as cv
import numpy as np
import pandas as pd


img_path = "./Signature.jpg"

# 计算每个 Color Channel 的 Most Common 色彩数值
def calculate_top_color(image):
    a = image.copy()
    cnt = ct.Counter(a)
    topTen = cnt.most_common(10)
    topTenColors = [k for k, v in topTen]
    topColor = np.array(topTenColors).mean()
    return topColor

def replace_color(image, top=None, threshold=5, color=255):
    color_threshold = threshold
    a = image.copy()
    s = pd.Series(image.flatten())
    rows, cols = image.shape
    topColor = top or calculate_top_color(s)
    # topColor = top or int(s.describe()['50%'])
    colorMin = topColor - color_threshold
    colorMax = topColor + color_threshold
    # print(s.describe(), "\n", "TopColor: %s, %s\n" % (topColor, topColor))
    for x in range(rows):
        for y in range(cols):
            val = a.item(x, y)
            if colorMin <= val < colorMax:
                a.itemset((x, y), color)
    return a


# 如果rgb三Color Channel的色彩数值全都是“目标色彩数值”
# 则将Alpha Channel分量的色彩数值设置为 0:“100%透明,将显示背景色彩”
# 不然Alpha Channel分量的色彩数值设置为 255:“0%透明,将显示此像素色彩”
def compositeAlphaMask(r, g, b, a, color, alpha0, alpha1):
    rows, cols = b.shape
    for x in range(rows):
        for y in range(cols):
            vb, vg, vr = b.item(x, y), g.item(x, y), r.item(x, y)
            if vb == color and vg == color and vr == color:
                a.itemset((x, y), alpha1)
            else:
                a.itemset((x, y), alpha0)
    return a

# 将BGR图片统一转换为BGRA的格式,拆分出每个Color Channel处理完再合成BGRA的产出PNG图片
def remove_top_color(img, top=None, threshold=18, color=255, alpha=0):
    if img.shape[-1] == 3:
        img = cv.cvtColor(img, cv.COLOR_BGR2BGRA)

    b, g, r, a = img[:, :, 0], img[:, :, 1], img[:, :, 2], img[:, :, 3]

    print("\nProcessing Color Channel: BLUE")
    b = replace_color(b, top, threshold, color)

    print("\nProcessing Color Channel: GREEN")
    g = replace_color(g, top, threshold, color)

    print("\nProcessing Color Channel: RED")
    r = replace_color(r, top, threshold, color)

    (alpha0, alpha1) = (0, 255) if alpha == 0 else (255, 0)
    compositeAlphaMask(r, g, b, a, color, alpha0, alpha1)

    img_bgr = cv.merge((b, g, r))
    img_bgra = cv.merge((b, g, r, a))
    return img_bgr, img_bgra


if __name__ == "__main__":
    threshold = int(sys.argv[1]) if len(sys.argv) > 1 else 18
    # Load the image first
    img0 = cv.imread(img_path)
    assert img0 is not None, ("file could not be read, check with os.path.exists('%s')" % img_path)

    # import pdb;pdb.set_trace()
    cv.imwrite("Original.png", img0)
    img_bgr, img_bgra = remove_top_color(img0, threshold=threshold, alpha=1)
    cv.imwrite("OutputBGRA.png", img_bgra)

posted @   abaelhe  阅读(94)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示