最近,在進行圖像處理時候,拿到了用 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()
結果如下:
就這樣解決了我的實際問題,不知道我說得全不全,如果大家覺得有什么不恰當的地方,歡迎指正和批評。