簡體   English   中英

在Python中使用OpenCV將圖像與另一個包含黑色像素的非矩形圖像重疊

[英]Overlaying an image with another non-rectangular image containing black pixels using OpenCV in Python

我想以編程方式疊加圖像,例如,非常熟悉的Windows XP牆紙:

Windows XP壁紙

另一個包含黑色像素的非矩形圖像,例如標准的大光標圖標:

在此處輸入圖片說明

復制-從牧養的碼其中都使用OpenCV的逐位掩碼魔法我趕到教程:

import cv2 as cv

# Load two images
img1 = cv.imread('bliss.png') # The image I want the overlay to be diplayed on.
img2 = cv.imread('cursor.png') # The image I want to overlay with, containing black pixels.

# I want to put logo on top-left corner, So I create a ROI.
rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols ]

# Now create a mask of logo and create its inverse mask also.
img2gray = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img2gray, 20, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)

# Now black-out the area of logo in ROI.
img1_bg = cv.bitwise_and(roi, roi, mask = mask_inv)

# Take only region of logo from logo image.
img2_fg = cv.bitwise_and(img2, img2, mask = mask)

# Put logo in ROI and modify the main image
dst = cv.add(img1_bg, img2_fg)
img1[0:rows, 0:cols ] = dst
cv.imshow('res',img1)
cv.waitKey(0)
cv.destroyAllWindows()

在嘗試為cv.threshold找到正確的參數(包括thres和maxval參數以及閾值類型 )的幼稚排列過程中,我總是發現原始圖像中存在大量黑色像素,這些像素在重疊圖像中丟失了。 在下面左側的放大圖片中,您可以看到覆蓋的光標,而右側是原始復制的光標:

在此處輸入圖片說明

我認為這種像素損失是由於灰度轉換和/或逆(?)遮罩引起的,但無法確定上面代碼中的更改方式或更改方式。 在上面鏈接的教程中,我使用了不包含黑色像素的圖像作為疊加層,結果看起來不錯。 有沒有辦法對包含黑色像素的圖像進行同樣的處理?

這里的問題是,您丟失了cv.threshold(img2gray, 20, 255, cv.THRESH_BINARY) cursor.png中的黑色像素。 其余的僅是白色像素,因此您的遮罩太小了。 由於cursor.png中存儲了透明度信息,因此可以將其alpha通道用作蒙版。

這是您的代碼,進行了相應的修改(我刪除了所有注釋;注釋顯示了我的更改):

import cv2 as cv

img1 = cv.imread('bliss.png')
img2 = cv.imread('cursor.png', cv.IMREAD_UNCHANGED)         # Added cv.IMREAD_UNCHANGED parameter to maintain alpha channel information

alpha = img2[:, :, 3]                                       # Save alpha channel for later use
_, alpha = cv.threshold(alpha, 5, 255, cv.THRESH_BINARY)    # Threshold alpha channel to prevent gradual transparency
img2 = cv.cvtColor(img2, cv.COLOR_BGRA2BGR)                 # Remove alpha channel information, so that code below still works

rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols ]

                                                            # img2gray no longer needed
mask = alpha                                                # Mask is just the alpha channel saved above
mask_inv = cv.bitwise_not(mask)

img1_bg = cv.bitwise_and(roi, roi, mask = mask_inv)

img2_fg = cv.bitwise_and(img2, img2, mask = mask)

dst = cv.add(img1_bg, img2_fg)
img1[0:rows, 0:cols ] = dst
cv.imshow('res',img1)
cv.waitKey(0)
cv.destroyAllWindows()

希望輸出圖像看起來像您期望的那樣:

輸出量

暫無
暫無

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

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