[英]Trying to make naive numpy image processing code faster
我正在嘗試將包含彩色符號的圖像轉換為右側所示的像素藝術(見下圖),其中每個彩色符號(占用多個像素)將更改為符號顏色的一個像素。
到目前為止,我已經編寫了一個非常簡單的算法,它只是循環遍歷所有像素,而且非常緩慢。 我相信我可以讓它更快,例如使用本機 numpy 操作,但我一直無法找到方法。 有小費嗎?
(我也開始嘗試簡單地調整圖像大小,但找不到可以使其工作的重采樣算法)。
def resize(img, new_width):
width, height = img.shape[:2]
new_height = height*new_width//width
new_image = np.zeros((new_width, new_height,4), dtype=np.uint8)
x_ratio, y_ratio = width//new_width, height//new_height
for i in range(new_height):
for j in range(new_width):
sub_image = img[i*y_ratio:(i+1)*y_ratio, j*x_ratio:(j+1)*x_ratio]
found = False
for row in sub_image:
for pixel in row:
if any(pixel!=[0,0,0,0]):
new_image[i,j]=pixel
break
if found:
break
return new_image
import cv2
import numpy as np
img=cv2.imread('zjZA8.png')
h,w,c=img.shape
new_img=np.zeros((h//7,w//7,c), dtype='uint8')
for k in range(c):
for i in range(h//7):
for j in range(w//7):
new_img[i,j,k]=np.max(img[7*i:7*i+7,7*j:7*j+7,k])
cv2.imwrite('out3.png', new_img)
左邊是 np.mean 的結果,中心 - 源圖像,右邊 - np.max 的結果
請測試此代碼:
img=cv2.imread('zjZA8.png')
h,w,c=img.shape
bgr=[0,0,0]
bgr[0], bgr[1],bgr[2] =cv2.split(img)
for k in range(3):
bgr[k].shape=(h*w//7, 7)
bgr[k]=np.mean(bgr[k], axis=1)
bgr[k].shape=(h//7, 7, w//7)
bgr[k]=np.mean(bgr[k], axis=1)
bgr[k].shape=(h//7,w//7)
bgr[k]=np.uint8(bgr[k])
out=cv2.merge((bgr[0], bgr[1],bgr[2]))
cv2.imshow('mean_image', out)
修改我的代碼以使用本機 np.nonzero 操作就可以了。 我在 1645x1645 圖像(new_width=235)上從 ~8s 下降到 ~0.32s,我還嘗試在此之上使用 numba。 但開銷最終使它變慢。
def resize(img, new_width):
height, width = img.shape[:2]
new_height = height*new_width//width
new_image = np.ones((new_height, new_width,3), dtype=np.uint8)
x_ratio, y_ratio = width//new_width, height//new_height
for i in range(new_height):
for j in range(new_width):
sub_image = img[i*y_ratio:(i+1)*y_ratio, j*x_ratio:(j+1)*x_ratio]
non_zero = np.nonzero(sub_image)
if non_zero[0].size>0:
new_image[i, j]=sub_image[non_zero[0][0],non_zero[1][0]][:3]
return new_image
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.