[英]OpenCV - Splitting and merging alpha channels slow
我正在使用 Python OpenCV 來分割通道並像這樣刪除黑色背景......
b_channel, g_channel, r_channel = cv2.split(image_1)
alpha_channel = np.zeros_like(gray)
for p in range(alpha_channel.shape[0]):
for q in range(alpha_channel.shape[1]):
if b_channel[p][q]!=0 or g_channel[p][q]!=0 or r_channel[p][q]!=0:
alpha_channel[p][q] = 255
merged = cv2.merge((b_channel, g_channel, r_channel, alpha_channel))
這是可行的,但在僅 200kb 的圖像上完成大約需要 10 秒
有沒有更有效的方法來做到這一點,或者我可以使用我擁有的代碼獲得一些速度提升?
使用for
循環遍歷像素實際上非常緩慢且效率低下。 另外,根據此處的文檔,
cv2.split()是一項昂貴的操作(就時間而言)。 因此,僅在需要時才這樣做。 否則請進行Numpy索引。
您可以嘗試使用numpy進行矢量化和索引編制,如下所示:
# create the image with alpha channel
img_rgba = cv2.cvtColor(img, cv2.COLOR_RGB2RGBA)
# mask: elements are True any of the pixel value is 0
mask = (img[:, :, 0:3] != [0,0,0]).any(2)
#assign the mask to the last channel of the image
img_rgba[:,:,3] = (mask*255).astype(np.uint8)
對於您正在做的事情,使用cv2.bitwise_or似乎是最快的方法:
image_1 = img
# your method
start_time = time.time()
b_channel, g_channel, r_channel = cv2.split(image_1)
alpha_channel = np.zeros_like(gray)
for p in range(alpha_channel.shape[0]):
for q in range(alpha_channel.shape[1]):
if b_channel[p][q]!=0 or g_channel[p][q]!=0 or r_channel[p][q]!=0:
alpha_channel[p][q] = 255
elapsed_time = time.time() - start_time
print('for cycles: ' + str(elapsed_time*1000.0) + ' milliseconds')
# my method
start_time = time.time()
b_channel, g_channel, r_channel = cv2.split(image_1)
alpha_channel2 = cv2.bitwise_or(g_channel,r_channel)
alpha_channel2 = cv2.bitwise_or(alpha_channel2, b_channel)
_,alpha_channel2 = cv2.threshold(alpha_channel2,0,255,cv2.THRESH_BINARY)
elapsed_time2 = time.time() - start_time
print('bitwise + threshold: '+ str(elapsed_time2*1000.0) + ' milliseconds')
# annubhav's method
start_time = time.time()
img_rgba = cv2.cvtColor(image_1, cv2.COLOR_RGB2RGBA)
# mask: elements are True any of the pixel value is 0
mask = (img[:, :, 0:3] != [0,0,0]).any(2)
#assign the mask to the last channel of the image
img_rgba[:,:,3] = (mask*255).astype(np.uint8)
elapsed_time3 = time.time() - start_time
print('anubhav: ' + str(elapsed_time3*1000.0) + ' milliseconds')
周期:2146.300792694092毫秒
按位+閾值:4.959583282470703毫秒
anubhav:27.924776077270508毫秒
讓我們考慮一個使用cv2.split
的函數,我們知道它的效率非常低,我們可以繼續調整或裁剪圖像的某個部分,然后對其進行計算。 在我必須使用cv2.split
計算圖像的色彩度的情況下,我繼續調整大小並裁剪圖像以使cv2.split
工作。
cv2.split
計算def image_colorfulness(self,image):
# split the image into its respective RGB components
(B, G, R) = cv2.split(image.astype("float"))
print(f'Split Image to B G R {(B, G, R)}')
# compute rg = R - G
rg = np.absolute(R - G)
print(f'Computed RG to {rg}')
# compute yb = 0.5 * (R + G) - B
yb = np.absolute(0.5 * (R + G) - B)
# compute the mean and standard deviation of both `rg` and `yb`
print('Performing Absolute')
(rbMean, rbStd) = (np.mean(rg), np.std(rg))
(ybMean, ybStd) = (np.mean(yb), np.std(yb))
# combine the mean and standard deviations
print('Performing Standard Deviation')
stdRoot = np.sqrt((rbStd ** 2) + (ybStd ** 2))
meanRoot = np.sqrt((rbMean ** 2) + (ybMean ** 2))
# derive the "colorfulness" metric and return it
return stdRoot + (0.3 * meanRoot)
def crop_square(self, img, size, interpolation=cv2.INTER_AREA):
h, w = img.shape[:2]
min_size = np.amin([h,w])
# Centralize and crop
crop_img = img[int(h/2-min_size/2):int(h/2+min_size/2), int(w/2-min_size/2):int(w/2+min_size/2)]
resized = cv2.resize(crop_img, (size, size), interpolation=interpolation)
return resized
img = cv2.imread(image_path)
resize_img = self.crop_square(img, 300)
## perform your calculation on the resized_img and continue with the original img then
colorness = self.image_colorfulness(resize_img)
如果您不想裁剪而只調整圖像大小,可以通過查看square_crop
函數中的這行代碼來實現。
resized = cv2.resize(crop_img, (size, size), interpolation=interpolation)
5.0 MB *.PNG
圖像,然后在cv2.split
中使用標准圖像輸入,它在8 Minutes中處理。在圖像調整大小之后,調整大小的圖像上的時間減少到0.001 ms
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.