Итак, у меня есть большой 2D-массив, полученный из изображения в формате TIFF, в котором я хочу вычислить центр масс. Для этого я использую индексы изображения (в качестве координат) и среднюю функцию:
from PIL import Image
from numpy import *
Im = Image.open("32bit_grayscale.tif")
imArr = array(Im, dtype='float32')
indx = indices(imArr.shape)
cenMassX = average(indx[0,:,:],weights=imArr[:,:])
cenMassY = average(indx[1,:,:],weights=imArr[:,:])
На некоторых других подобных изображениях есть два отдельных центра масс, которые я хочу рассчитать. Обе области расчета разделены прямой наклонной линией, уравнение которой у меня есть.
Я хотел бы снова использовать метод average
, так как он очень эффективен, но мне нужно было бы установить максимум среза второй оси массива indx
в функцию текущего значения первой оси. Если бы строка была чем-то вроде y=slope*x+interY
, мне нужно было бы что-то вроде этого:
cenMassX_A = average(indx[0,:,:slope*row+interY],weights=imArr[:,:slope*row+interY])
cenMassY_A = average(indx[1,:,:slope*row+interY],weights=imArr[:,:slope*row+interY])
cenMassX_B = average(indx[0,:,slope*row+interY:],weights=imArr[:,slope*row+interY:])
cenMassY_B = average(indx[1,:,slope*row+interY:],weights=imArr[:,slope*row+interY:])
Где row
представляет текущее значение индекса первой оси (ось «x»). Не обращайте внимания на тот факт, что я могу выйти за пределы массива в зависимости от уравнения.
Я могу сделать это, используя циклы for
, но это очень неэффективно (в 20 раз) и не очень "питоново":
cenMassX_A = 0
cenMassY_A = 0
cumSum = 0
for row in range(0,imArr.shape[0]):
for col in range(0,int(round(slope*row+interY))):
cenMassX_A += row*imArr[row,col]
cenMassY_A += col*imArr[row,col]
cumSum += imArr[row,col]
cenMassX_A /= cumSum
cenMassY_A /= cumSum
cenMassX_B = 0
cenMassY_B = 0
cumSum = 0
for row in range(0,imArr.shape[0]):
for col in range(int(round(slope*row+interY)),imArr.shape[1]):
cenMassX_B += row*imArr[row,col]
cenMassY_B += col*imArr[row,col]
cumSum += imArr[row,col]
cenMassX_B /= cumSum
cenMassY_B /= cumSum
Итак, есть ли способ сделать это, или я застрял с for
циклами? Я читал о масках и скользящих окнах, но до сих пор не могу найти решение. Заранее спасибо!