簡體   English   中英

opencv:如何將所有黑色像素轉換為透明並將其保存為 png 文件

[英]opencv: how to convert all black pixels to transparent and save it to png file

圖像如下,我希望所有黑色像素都是透明的並將其保存為 png 文件。

在此處輸入圖像描述

根據文檔

可以使用此 function 保存具有 alpha 通道的 PNG 圖像。 為此,請創建 8 位(或 16 位)4 通道圖像 BGRA,Alpha 通道位於最后。 完全透明的像素應該將 alpha 設置為 0,完全不透明的像素應該將 alpha 設置為 255/65535(參見下面的代碼示例)。

透明圖像帶有一個額外的通道,我們稱之為alpha通道,並在 opencv 中用BGRA表示。 您需要做的就是創建一個BGRA格式的掩碼圖像。 然后檢測圖像中的所有黑色像素,並為這些黑色像素分配蒙版圖像的alpha通道為 0。

注意:使用 opencv imshow或其他您將無法看到透明圖像,因為 opencv 無法顯示 alpha 通道。 所以你需要用imwritepng 格式寫出來。

注意:使任何像素透明意味着將其 Alpha 通道指定為 0。

這是我的意思的output:

在此處輸入圖像描述

由於我對 python 不熟悉,所以我在 C++ 中編寫了步驟。 對此感到抱歉。

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>


int main()
{


    cv::Mat img = cv::imread("/ur/input/img.png",cv::IMREAD_COLOR);

    cv::Mat mask = cv::Mat::zeros(cv::Size(img.cols,img.rows),CV_8UC4);

    cv::namedWindow("Input",0);
    cv::namedWindow("Output",0);


    for(int i=0; i<mask.cols; i++)
    {
        for(int j=0; j<mask.rows; j++)
        {

            if(img.at<cv::Vec3b>(cv::Point(i,j))[0] == 0 &&
                    img.at<cv::Vec3b>(cv::Point(i,j))[1] == 0 &&
                    img.at<cv::Vec3b>(cv::Point(i,j))[2] == 0)
            {
                mask.at<cv::Vec4b>(cv::Point(i,j))[0] = img.at<cv::Vec3b>(cv::Point(i,j))[0];
                mask.at<cv::Vec4b>(cv::Point(i,j))[1] = img.at<cv::Vec3b>(cv::Point(i,j))[1];
                mask.at<cv::Vec4b>(cv::Point(i,j))[2] = img.at<cv::Vec3b>(cv::Point(i,j))[2];
                mask.at<cv::Vec4b>(cv::Point(i,j))[3] = 0;
            }
            else {
                mask.at<cv::Vec4b>(cv::Point(i,j))[0] = img.at<cv::Vec3b>(cv::Point(i,j))[0];
                mask.at<cv::Vec4b>(cv::Point(i,j))[1] = img.at<cv::Vec3b>(cv::Point(i,j))[1];
                mask.at<cv::Vec4b>(cv::Point(i,j))[2] = img.at<cv::Vec3b>(cv::Point(i,j))[2];
                mask.at<cv::Vec4b>(cv::Point(i,j))[3] = 255;
            }

        }
    }




    cv::imshow("Input",img);
    cv::imshow("Output",mask);


    cv::imwrite("/ur/writing/dir/transparent.png",mask);
    cv::waitKey(0);



    return 0;
}

您可以像這樣快速和矢量化它:

import cv2
import numpy as np

# Load image as Numpy array
na = cv2.imread('I5jKW.png')

# Find non-black pixels and make them 255 and correct type to match "na"
alpha = np.sum(na, axis=-1)>0
alpha = np.uint8(alpha*255)

# Stack alpha layer with existing image to go from BGR to BGRA, i.e. 3-channels to 4
res = np.dstack((na,alpha))

# Save result
cv2.imwrite('result.png', res)

這是在 Python/OpenCV/Numpy 中執行此操作的另一種方法。

import cv2
import numpy as np

# load image
img = cv2.imread('girl_on_black.png')

# threshold on black to make a mask
color = (0,0,0)
mask = np.where((img==color).all(axis=2), 0, 255).astype(np.uint8)

# put mask into alpha channel
result = img.copy()
result = cv2.cvtColor(result, cv2.COLOR_BGR2BGRA)
result[:, :, 3] = mask

# save resulting masked image
cv2.imwrite('girl_on_black_transparent.png', result)

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

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM