LearnOpencv進階系列一之Alpha通道混合

一、圖像通道介紹

圖像在計算機中是以數字矩陣形式存儲的,我們常見的圖像是JPEG格式,後綴為JPEG或者JPG,此種圖像對應的矩陣有三個通道,代表著每個像素有R紅,G綠,B藍三個顏色分量。另一種常見的無損壓縮圖像格式為PNG,不同於JPEG,此格式的圖像在計算機中有四個通道,第四個通道Alpha代表透明度。本文要做的就是將一個PNG圖像的前景(RGB通道部分疊加到另一個背景圖像上,類似於PS的摳圖操作)

二、如何利用OpenCV實現?

下面來看下代碼實現部分,首先是python的實現:

import numpy as np
import cv2

foreGroundImage = cv2.imread("foreGroundAsset.png",-1)

## 先將通道分離
b,g,r,a = cv2.split(foreGroundImage)

#得到PNG圖像前景部分,在這個圖片中就是除去Alpha通道的部分
foreground = cv2.merge((b,g,r))

#得到PNG圖像的alpha通道,即alpha掩模
alpha = cv2.merge((a,a,a))

background = cv2.imread("backGround.jpg")

#因為下面要進行乘法運算故將數據類型設為float,防止溢出
foreground = foreground.astype(float)
background = background.astype(float)

cv2.imwrite("alpha.jpg",alpha)
#將alpha的值歸一化在0-1之間,作為加權係數
alpha = alpha.astype(float)/255

cv2.imshow("alpha",alpha)
cv2.waitKey(0)

#將前景和背景進行加權,每個像素的加權係數即為alpha掩模對應位置像素的值,前景部分為1,背景部分為0
foreground = cv2.multiply(alpha,foreground)
background = cv2.multiply(1-alpha,background)

outImage = foreground + background

cv2.imwrite("outImage.jpg",outImage)

cv2.imshow("outImg",outImage/255)
cv2.waitKey(0)

同樣,給出C++的實現代碼:

#include opencv2/opencv.hpp
using namespace cv;
using namespace std;
int main()
{
// 讀圖像
Mat foreground = imread("puppets.png");
Mat background = imread("ocean.png");
Mat alpha = imread("puppets_alpha.png");
// 為做乘法不溢出,將格式轉換為32F的,代表32維浮點數
foreground.convertTo(foreground, CV_32FC3);
background.convertTo(background, CV_32FC3);
// 將alpha掩模的值歸一化在0-1之間
alpha.convertTo(alpha, CV_32FC3, 1.0/255); //
// 保存合成圖像
Mat ouImage = Mat::zeros(foreground.size(), foreground.type());
// 前景乘以alpha
multiply(alpha, foreground, foreground);
// 背景乘以1-alpha
multiply(Scalar::all(1.0)-alpha, background, background);
// 相加
add(foreground, background, ouImage);
// 顯示圖像
imshow("alpha blended image", ouImage/255);
waitKey(0);
return 0;
}

結果示意:

PNG圖像

背景JPEG圖像

合成圖像

alpha掩模,即為程序中的alpha=cv2.merge((a,a,a))

三、結語&下一章預告

本節的內容比較簡單,下一節介紹如何檢測圖像中具有的特殊色塊,比如一塊橡皮之類的東西。

致力於分享OpenCV有趣且實用的案例~

微信公眾號:一支程序媛

掃我呀~~

關注回復 計算機視覺演算法 可以獲取免費學習資源(樓主就是靠這些資源拿到百度,阿里等校招offer的哦~)

CSDN博客:

【zkyzq的博客】openGL_三維場景漫遊_C++ - CSDN博客?

blog.csdn.net


推薦閱讀:

TAG:圖像處理 | OpenCV | Python |