簡體   English   中英

試圖讓天真的 numpy 圖像處理代碼更快

[英]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.

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