[PYTHON] numpy에서 가우스 커널 행렬을 효율적으로 계산하는 방법은 무엇입니까?
PYTHONnumpy에서 가우스 커널 행렬을 효율적으로 계산하는 방법은 무엇입니까?
def GaussianMatrix(X,sigma):
row,col=X.shape
GassMatrix=np.zeros(shape=(row,row))
X=np.asarray(X)
i=0
for v_i in X:
j=0
for v_j in X:
GassMatrix[i,j]=Gaussian(v_i.T,v_j.T,sigma)
j+=1
i+=1
return GassMatrix
def Gaussian(x,z,sigma):
return np.exp((-(np.linalg.norm(x-z)**2))/(2*sigma**2))
이것이 나의 현재 방법입니다. 이 작업을 수행하기 위해 행렬 연산을 사용할 수있는 방법이 있습니까? X는 데이터 포인트입니다.
해결법
-
==============================
1.예를 들어 가우스 커널을 사용 하시겠습니까? 이미지 스무딩? 그렇다면 scipy에 gaussian_filter () 함수가 있습니다 :
예를 들어 가우스 커널을 사용 하시겠습니까? 이미지 스무딩? 그렇다면 scipy에 gaussian_filter () 함수가 있습니다 :
또는 다음과 같이 작동해야합니다.
import numpy as np import scipy.stats as st def gkern(kernlen=21, nsig=3): """Returns a 2D Gaussian kernel array.""" interval = (2*nsig+1.)/(kernlen) x = np.linspace(-nsig-interval/2., nsig+interval/2., kernlen+1) kern1d = np.diff(st.norm.cdf(x)) kernel_raw = np.sqrt(np.outer(kern1d, kern1d)) kernel = kernel_raw/kernel_raw.sum() return kernel
입력:
import matplotlib.pyplot as plt plt.imshow(gkern(21), interpolation='none')
산출:
-
==============================
2.간단한 2D dirac 함수를 가우스 필터링 할 수 있습니다. 결과는 사용 된 필터 함수입니다.
간단한 2D dirac 함수를 가우스 필터링 할 수 있습니다. 결과는 사용 된 필터 함수입니다.
import numpy as np import scipy.ndimage.filters as fi def gkern2(kernlen=21, nsig=3): """Returns a 2D Gaussian kernel array.""" # create nxn zeros inp = np.zeros((kernlen, kernlen)) # set element at the middle to one, a dirac delta inp[kernlen//2, kernlen//2] = 1 # gaussian-smooth the dirac, resulting in a gaussian filter mask return fi.gaussian_filter(inp, nsig)
-
==============================
3.나 자신이 내 이미지 처리에 대한 대답을 사용했지만 다른 모듈에도 너무 많이 의존하고있다. 게다가, 수락 된 대답은 때로는 많은 제로 엔트리를 가진 커널을 생성합니다.
나 자신이 내 이미지 처리에 대한 대답을 사용했지만 다른 모듈에도 너무 많이 의존하고있다. 게다가, 수락 된 대답은 때로는 많은 제로 엔트리를 가진 커널을 생성합니다.
따라서, 여기 내 컴팩트 솔루션입니다 :
import numpy as np def gkern(l=5, sig=1.): """ creates gaussian kernel with side length l and a sigma of sig """ ax = np.arange(-l // 2 + 1., l // 2 + 1.) xx, yy = np.meshgrid(ax, ax) kernel = np.exp(-(xx**2 + yy**2) / (2. * sig**2)) return kernel / np.sum(kernel)
-
==============================
4.2D 가우스 커널 행렬은 numpy 브로드 캐스트로 계산할 수 있습니다.
2D 가우스 커널 행렬은 numpy 브로드 캐스트로 계산할 수 있습니다.
def gaussian_kernel(size=21, sigma=3): """Returns a 2D Gaussian kernel. Parameters ---------- size : float, the kernel size (will be square) sigma : float, the sigma Gaussian parameter Returns ------- out : array, shape = (size, size) an array with the centered gaussian kernel """ x = np.linspace(- (size // 2), size // 2) x /= np.sqrt(2)*sigma x2 = x**2 kernel = np.exp(- x2[:, None] - x2[None, :]) return kernel / kernel.sum()
작은 커널 크기의 경우이 속도는 상당히 빠릅니다.
참고 : 이렇게하면 허용되는 답변과 관련하여 시그마 매개 변수를보다 쉽게 변경할 수 있습니다.
-
==============================
5.linalg.norm은 축 매개 변수를 취합니다. 약간의 실험을 통해 모든 행 조합에 대한 표준을 계산할 수 있음을 발견했습니다.
linalg.norm은 축 매개 변수를 취합니다. 약간의 실험을 통해 모든 행 조합에 대한 표준을 계산할 수 있음을 발견했습니다.
np.linalg.norm(x[None,:,:]-x[:,None,:],axis=2)
x를 모든 차이의 3d 배열로 확장하고 마지막 차원에서 표준을 취합니다.
따라서 Gaussian에 축 매개 변수를 추가하여 코드에 적용 할 수 있습니다.
def Gaussian(x,z,sigma,axis=None): return np.exp((-(np.linalg.norm(x-z, axis=axis)**2))/(2*sigma**2)) x=np.arange(12).reshape(3,4) GaussianMatrix(x,1)
생산하다
array([[ 1.00000000e+00, 1.26641655e-14, 2.57220937e-56], [ 1.26641655e-14, 1.00000000e+00, 1.26641655e-14], [ 2.57220937e-56, 1.26641655e-14, 1.00000000e+00]])
어울리는:
Gaussian(x[None,:,:],x[:,None,:],1,axis=2) array([[ 1.00000000e+00, 1.26641655e-14, 2.57220937e-56], [ 1.26641655e-14, 1.00000000e+00, 1.26641655e-14], [ 2.57220937e-56, 1.26641655e-14, 1.00000000e+00]])
-
==============================
6.FuzzyDuck의 대답을 개선하려고합니다. 나는이 접근법이 더 짧고 이해하기 쉽다고 생각한다. 여기에서는 signal.scipy.gaussian을 사용하여 2D 가우스 커널을 얻습니다.
FuzzyDuck의 대답을 개선하려고합니다. 나는이 접근법이 더 짧고 이해하기 쉽다고 생각한다. 여기에서는 signal.scipy.gaussian을 사용하여 2D 가우스 커널을 얻습니다.
import numpy as np from scipy import signal def gkern(kernlen=21, std=3): """Returns a 2D Gaussian kernel array.""" gkern1d = signal.gaussian(kernlen, std=std).reshape(kernlen, 1) gkern2d = np.outer(gkern1d, gkern1d) return gkern2d
matplotlib.pyplot을 사용하여 플로팅 :
import matplotlib.pyplot as plt plt.imshow(gkern(21), interpolation='none')
-
==============================
7.테디 하르 탕토의 대답을 토대로 자신의 1 차원 가우스 함수를 계산 한 다음 np.outer를 사용하여 2 차원을 계산할 수 있습니다. 매우 빠르고 효율적인 방법.
테디 하르 탕토의 대답을 토대로 자신의 1 차원 가우스 함수를 계산 한 다음 np.outer를 사용하여 2 차원을 계산할 수 있습니다. 매우 빠르고 효율적인 방법.
아래의 코드를 사용하여 모든 차원에 대해 다른 Sigmas를 사용할 수도 있습니다.
import numpy as np def generate_gaussian_mask(shape, sigma, sigma_y=None): if sigma_y==None: sigma_y=sigma rows, cols = shape def get_gaussian_fct(size, sigma): fct_gaus_x = np.linspace(0,size,size) fct_gaus_x = fct_gaus_x-size/2 fct_gaus_x = fct_gaus_x**2 fct_gaus_x = fct_gaus_x/(2*sigma**2) fct_gaus_x = np.exp(-fct_gaus_x) return fct_gaus_x mask = np.outer(get_gaussian_fct(rows,sigma), get_gaussian_fct(cols,sigma_y)) return mask
-
==============================
8.나는 numpy만을 사용하여 시도했다. 여기 코드가있다.
나는 numpy만을 사용하여 시도했다. 여기 코드가있다.
def get_gauss_kernel(size=3,sigma=1): center=(int)(size/2) kernel=np.zeros((size,size)) for i in range(size): for j in range(size): diff=np.sqrt((i-center)**2+(j-center)**2) kernel[i,j]=np.exp(-(diff**2)/2*sigma**2) return kernel/np.sum(kernel)
다음 전화
plt.imshow(get_gauss_kernel(5,1))
from https://stackoverflow.com/questions/29731726/how-to-calculate-a-gaussian-kernel-matrix-efficiently-in-numpy by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 장고 관리자의 다른 선택 필드를 기반으로 선택 필드 옵션을 제한하는 방법 (0) | 2018.10.21 |
---|---|
[PYTHON] 토네이도 셀러리 통합 해킹 (0) | 2018.10.21 |
[PYTHON] 파이썬 버전 전환 (0) | 2018.10.21 |
[PYTHON] PIL 색상을 대체하는 가장 좋은 방법은 무엇입니까? (0) | 2018.10.21 |
[PYTHON] 파이썬에서 opencv를 사용하여 이미지의 회전 사각형 영역을 교정하는 방법은 무엇입니까? (0) | 2018.10.21 |