2017-12-12 8 views
1

이미지의 각 열에 대해 질량 중심을 찾으려고합니다. 나는 현재 scipy.ndimage.measurements.center_of_mass 모듈과 간단한 반복을 사용한다. 현재 코드는 다음과 같습니다.축을 따라 이미지의 중심 찾기

def get_y_vec(img): 

    out = [] 

    for col in img.T: 
     out.append(np.around(measurements.center_of_mass(col)[0], 1)) 

    out = np.array(out) 

    return out 

이 방법은 효과가 있지만 꽤 느립니다. 동일한 결과물을 달성하기위한보다 효과적인 대안이 있습니까?

편집 : 더 빨리 배를이지만, 내 이미지가 상당히 큰

get_com = lambda m: np.round(np.sum(np.arange(m.shape[0])*m)/np.sum(m), 1) 


def get_y_vec(img): 

    out = np.apply_along_axis(get_com, 0, img) 

    return out 

와 내가 같은 느낌 :

난 그냥 질량 중심은 매우 간단 수학과 같은 기록 될 수 있다는 것을 깨달았 np.apply_along_axis 또는 반복을 사용하는 대신 완전히 벡터화 된 솔루션을 제안 할 수 있습니다.

+0

두 번 계산할 필요가 없습니다 -'com'을 사용하지 않는 것 같다. – kazemakase

+0

@kazemakase 미안하지만, 코드에서 실제로 두 번 계산하지 않습니다. 나는 지금 질문을 편집 할 것이다. – ymoiseev

+0

너무 나쁘지 만, 이것은 쉬운 최적화 였을 것입니다. 입력 'img'는 어떤 모양입니까 (일반적인 모양과 값 범위)? – kazemakase

답변

1

두 번째 버전은 약간 빠르지 만 벡터화를 사용하면 더 빨리 만들 수 있습니다. (apply_along_axis는 루프 숨겨)는 모든 치수 및 축 방향의 무게 중심의 이미지를 처리 ​​할 수 ​​있기 때문에

def get_y_vec(img, axis=0): 
    n = img.shape[axis] 
    s = [1] * img.ndim 
    s[axis] = -1 
    i = np.arange(n).reshape(s) 
    return np.round(np.sum(img * i, axis=axis)/np.sum(img, axis=axis), 1) 

코드는 필요한 것보다 약간 더 복잡하다. 기본 아이디어는 arange으로 색인 벡터를 만들고 이미지 값을 가중치로 사용하여 색인에 대한 가중 합계를 수행하는 것입니다 (정확히 OP의 두 번째 해법과 동일).

열만 함께 작동하는 간단한 버전은 다음과 같을 것이다 : 축을 따라 방송 및 요약 :

def get_y_vec(img): 
    n = img.shape[0] 
    i = np.arange(n).reshape([n, 1]) 
    return np.round(np.sum(img * i, axis=0)/np.sum(img, axis=0), 1) 

이 NumPy와 두 벡터화 기능을 활용합니다. 먼저 인덱스 배열은 이미지와 같은 수의 행이 있지만 하나의 열만 만들어집니다. img * i에서 벡터는 이미지의 모든 열과 자동으로 곱해진다 (이것은 방송이다). 그런 다음 axis=0을 전달하여 sum에 각 열에 대해 독립적으로 작업하도록 지시하여 각 열에 대해 하나의 값을 얻습니다.

타이밍 비교 :

10 loops, best of 3: 71.8 ms per loop # scipy 
10 loops, best of 3: 42.7 ms per loop # apply_along_axis 
100 loops, best of 3: 1.67 ms per loop # vectorized 

40 배의 속도 향상이 나쁘지 :)

벤치 마크 코드 (IPython)하지 않는 것 :

img = np.random.randint(256, size=(200, 1800)) 
%timeit get_y_vec(img) 
+0

정말 고마워요. 코드 작동 방식을 설명해 주시겠습니까? – ymoiseev

+1

몇 가지 설명으로 답변을 업데이트했습니다. 코드가 단어보다 쉽게 ​​나옵니다. 어쨌든 도움이되기를 바랍니다 :) – kazemakase