2011-12-20 3 views
4

레이블이있는 영역 주위에 픽셀 수가 많은 배열을 유지하려면 어떻게해야합니까?부스러기 레이블 침식

간단한 경우에 침식을 제거합니다. 그 접근법은 라벨이 닿으면 작동하지 않습니다. A에서 B을 얻으려면 어떻게해야합니까?

A = array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
      [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
      [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
      [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
      [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
      [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0], 
      [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
      [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
      [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
      [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) 

B = array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
      [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
      [0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0], 
      [0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0], 
      [0, 0, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0], 
      [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0], 
      [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], 
      [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], 
      [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], 
      [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) 

많은 라벨이있는 대형 어레이로 작업하기 때문에 각 라벨에 별도의 침식 옵션이 없습니다.

답변

2

새 응답

사실, 난 단지 더 좋은 방법이 생각 : 전체 예를 들어

B = A * (np.abs(scipy.ndimage.laplace(A)) > 0) 

:이 모든 경우에 작동해야한다고 생각

import numpy as np 
import scipy.ndimage 

A = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
       [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) 

B = A * (np.abs(scipy.ndimage.laplace(A)) > 0) 

(A과 같은 "레이블이 지정된"배열은, 어떤 비율로든 ...).

B = scipy.ndimage.laplace(A) 
B = np.abs(B, B) # Preform abs in-place 
B /= B # This will produce a divide by zero warning that you can safely ignore 
B *= A 

이 버전은 훨씬 더 자세한하지만, 훨씬 적은 메모리를 사용한다 : 당신이 성능에 대해 걱정하는 경우

, 당신은 메모리 오버 헤드를 줄일 수있는 몇 조각으로이 분할 할 수 있습니다.

내가 평소 scipy.ndimage의 기능을 한 번에 그것을 할 수있는 좋은 방법을 생각할 수 없다 올드 대답. (나는 tophat 필터가 당신이 원하는대로해야한다고 생각하지만, 나는 그것을 이해할 수 없다.)

그러나 언급 한 것처럼 몇 가지 개별적인 침식을하는 것은 옵션이다.

find_objects을 사용하여 각 레이블의 하위 영역을 추출한 다음 매우 작은 배열에서도 적절한 성능을 얻은 다음 하위 영역에서 침식을 수행해야합니다.

예를 들어

:

import numpy as np 
import scipy.ndimage 

A = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
       [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
       [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) 

regions = scipy.ndimage.find_objects(A) 

mask = np.zeros_like(A).astype(np.bool) 

for val, region in enumerate(regions, start=1): 
    if region is not None: 
     subregion = A[region] 
     mask[region] = scipy.ndimage.binary_erosion(subregion == val) 

B = A.copy() 
B[mask] = 0 

이 수율 :

array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
     [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0], 
     [0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0], 
     [0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0], 
     [0, 0, 2, 0, 0, 2, 2, 2, 2, 0, 0, 0], 
     [0, 0, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0], 
     [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], 
     [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], 
     [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], 
     [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) 

이 성능은 큰 배열에 대한 합리적인해야하지만 다른 표시 객체에 걸쳐 얼마나 큰 면적의에 크게 의존하는 것 및 레이블이있는 개체의 수를 ....

+0

레이블 배열이 희소하므로 잘 작동합니다. 사실 오늘 아침 일하러가는 길에 똑같은 생각이 들었습니다. – ajwood

+0

사실, 방금 더 좋은 길을 생각했습니다. (일부 상황에서는 원래의 대답이 더 빠를 수도 있지만 ...) 편집 내용을 확인하십시오. –