Я написал функцию для обработки изображения, в которой я извлекаю много патчей, а затем обрабатываю их с помощью той же функции (func) для создания нового изображения. Однако это очень медленно из-за двух циклов, функции, количества патчей и размера патчей. Я не знаю, как я могу ускорить этот код.
Функция, как показано ниже.
# code1
def filter(img, func, ksize, strides=1):
height,width = img.shape
f_height,f_width = ksize
new_height = height - f_height + 1
new_width = width - f_width + 1
new_img = np.zeros((new_height,new_width))
for i in range(new_height):
for j in range(new_width):
patch = img[i:i+f_height,j:j+f_width]
new_img[i][j] = func(patch)
return new_img
func может быть очень гибким и занимать много времени. Я беру один например. Функция ниже хочет вычислить центральную точку патча, делящего медиану патча. Однако я не хочу, чтобы те пиксели, значение которых равно 255, вычисляли медиану (255 — это значение по умолчанию для недопустимых пикселей). Поэтому я использую замаскированный массив в numpy. Маскированный массив замедляет код в несколько раз, и я понятия не имею, как это оптимизировать.
# code2
def relative_median_and_center_diff(patch, in_the_boundary, rectangle, center_point):
mask = patch == 255
mask[center_point] = True
masked_patch = np.ma.array(patch, mask=mask)
count = masked_patch.count()
if count <= 1:
return 0
else:
return patch[center_point]/(np.ma.median(masked_patch)+1)
идеи, которые я пробовал или получил:
- Я использовал некоторую функцию numpy для извлечения патчей перед циклом, ожидая, что это может быть быстрее, чем
patch = img[i:i+f_height,j:j+f_width]
. Я нашел функции для извлечения исправлений из патчи определенного размера из образа в питоне эффективно Сначала я попробовал view_as_windows из skimage.util.shape. Код был изменен, как показано ниже. Это занимает больше времени, чем code1. Я также попробовал sklearn.feature_extraction.image.extract_patches_2d и обнаружил, что это быстрее, чем code3, но все же медленнее, чем code1. (Кто-нибудь может сказать мне, почему это так?)
# code3
def filter(img, func, ksize, strides=1):
height,width = img.shape
f_height,f_width = ksize
new_height = height - f_height + 1
new_width = width - f_width + 1
new_img = np.zeros((new_height,new_width))
from skimage.util.shape import view_as_windows
patches = view_as_windows(img, (f_height,f_width))
for i in range(new_height):
for j in range(new_width):
patch = patches[i,j]
new_img[i][j] = func(patch)
return new_img
Эта операция немного похожа на свертку или фильтр, за исключением функции func. Интересно, как эти библиотеки справляются с этим, и не могли бы вы, ребята, дать мне некоторые подсказки.
Можем ли мы избежать двух петель в этой ситуации? Может быть, это может ускорить код.
У меня есть гпу. Могу ли я изменить код, чтобы запустить его на gpus и заставить его обрабатывать патчи параллельно, чтобы сделать его быстрее?
Измените код на C. Это последнее, что я хочу сделать, потому что, возможно, это немного беспорядочно.
Можете ли вы, ребята, дать мне некоторые идеи или некоторые предложения?