在我們進入色度鍵控(綠色屏幕效果)之前,最好先了解使用Open CV實現這一目标的基本概念。
顔色阈值當我們将圖像作為X和Y的函數處理圖像時,我們将使用顔色信息來分離特定區域。我們将使用顔色阈值選擇感興趣的區域,
使用顔色阈值,我們可以删除屬于特定顔色範圍的圖像部分。常用的是藍/綠屏。
類似于綠色屏幕的藍色屏幕用于基于識别和替換大的藍色區域來對兩個圖像或視頻流進行分層。
我們現在要用藍屏來拍攝;那麼,它是如何工作的呢?
第一步是分離藍色背景并将藍色區域替換成你選擇的圖像。
ctree_bluescreen.jpg
我們将從藍色屏幕背景上的聖誕樹圖像開始。
我們首先必須識别藍色區域,然後我們将用我們選擇的背景圖像替換它。Python代碼如下:
import cv2 import matplotlib.pyplot as plt import numpy as np image = cv2.imread('images/ctree_bluescreen.jpg')
cv2.imread()用于讀取以圖像位置為參數的圖像,其中圖像ctree_bluescreen.jpg位于images文件夾中.
print('Image type: ', type(image),'Image Dimensions : ', image.shape)
輸出結果:
Image type: Image Dimesnsions: (720,1280,3)
OpenCV庫以數組的形式讀取圖像。圖像的形狀,其中包含三個值,表示圖像數組的維數,
image_copy = np.copy(image) image_copy = cv2.cvtColor(image_copy, cv2.COLOR_BGR2RGB) plt.imshow(image_copy)
上述Python代碼段的輸出
OpenCV将彩色圖像讀取為BGR(藍色、綠色、紅色)圖像,而不是RGB(紅色、藍色、綠色)圖像。因此,紅色和藍色的順序是相反的,pyplot反映了這種轉換,并産生了與原始圖像不同的顔色。
因此,在我們顯示圖像之前,讓我們制作原始圖像的副本,并使用Open CV将顔色從BGR更改為RGB。這樣,您将應用于副本的任何變換都不會影響原始圖像,因此更容易撤消步驟或嘗試新内容。
現在,在這個複制的圖像image_copy上,我們可以使用Open CV函數cvtColor()執行一個顔色轉換,它接受一個源圖像和顔色轉換代碼,在本例中,是BGR2RGB,然後輸出所需的圖像。
定義顔色阈值現在,我們需要創建一個顔色阈值來移除所需的藍色區域。
為了創建一個顔色阈值,我們需要為需要分離和删除的顔色定義下限和上限
Python代碼如下:
lower_blue = np.array([0, 0, 100]) ##[R value, G value, B value] upper_blue = np.array([120, 100, 255])
因此,我們定義了包含紅色、綠色和藍色的最小值的低阈值,這些值仍然被認為是藍屏背景的一部分。
在lower_blue 中,紅色和綠色,我們設置為0,這意味着沒有紅色或綠色是可以的。但是,藍色的最小值仍然很高,假設是100左右。
現在,對于upper_bluedefined的上限阈值允許更多的紅色和綠色,并設置藍色的最高值為255。在這個高低範圍内的任何顔色都将是強烈的藍色。這隻是一個估計。如果我們發現這個範圍沒有找到我們想要的藍色屏幕區域,我們可以返回并改變這些值。
創建一個Mask我們将使用剛剛創建的顔色邊界來創建一個圖像蒙版。
蒙版是一種非常常見的方法來分離選定的區域,并對該區域進行處理。我們可以使用Open CV的inRange()函數在藍色區域上創建一個蒙版。Python代碼如下:
mask = cv2.inRange(image_copy, lower_blue, upper_blue) plt.imshow(mask, cmap='gray')
inRange()函數接收上、下顔色範圍内的圖像,并通過詢問每個圖像像素的顔色值是否落在上、下顔色阈值範圍内來定義mask。如果它落在這個範圍内,mask将被允許顯示,如果不顯示,它将阻止它,并将像素變為黑色。
實際上,我們可以通過将其繪制為圖像來可視化蒙版。
plt.imshow(mask,cmap ='gray')
整個白色區域是圖像被允許顯示的地方,黑色區域将被遮擋。在數值方面,我們可以将這個mask看作一個二維網格,其尺寸與圖像的720像素高度和816像素寬度相同。
mask中的每個坐标對于白色的值是255,對于黑色的值是0,有點像灰度圖像。當我們看這個mask的時候,我們可以看到它有一個白色的區域(藍色的屏幕是背景),黑色的區域是聖誕樹。
現在,我們需要做的第一件事是讓聖誕樹顯示出來,擋住藍色屏幕的背景。Python代碼如下:
masked_image = np.copy(image_copy) masked_image[mask != 0] = [0, 0, 0] plt.imshow(masked_image)
首先,我們将制作另一個圖像副本,稱為maksed_image,我更改圖像副本,以防我以後想要更改mask。
然後我們将使用選擇mask區域不等于零的圖像部分mask != 0 。為了阻止這個背景區域,我們将像素設置為黑色。現在,當我們顯示結果時,應該顯示聖誕樹區域是唯一應該顯示的區域。
plt.imshow(masked_image)
藍屏背景消失了,我們甚至可以改變我們的顔色阈值來去除任何少量的藍色點,我們可以嘗試通過增加highest green值和減少low blue值,這應該可以捕捉到更大範圍的藍色。
Mask和添加背景圖像現在,我們隻有最後一步是将背景應用于此圖像。這個過程非常相似。Python代碼如下:
background_image = cv2.imread('images/treeBackground.jpg') background_image = cv2.cvtColor(background_image, cv2.COLOR_BGR2RGB) crop_background = background_image[0:720, 0:1280] crop_background[mask == 0] = [0, 0, 0] plt.imshow(crop_background)
首先,我們将讀取圖像并轉換成RGB顔色。我們還會裁剪它,使它的大小也為720 x 1280像素,我們将這個圖像稱為crop_background,然後我們應用mask,這次使用相反的mask,這意味着我們想要背景顯示而不是聖誕樹區域。
為了确保我們的mask正确,我們将繪制生成的圖像。
plt.imshow(crop_background)
最後,我們隻需要将這兩個圖像相加。
final_image = crop_background masked_image plt.imshow(final_image)
現在,當我們繪制完整的圖像時,我得到了具有新背景的聖誕樹
plt.imshow(final_image)
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!