가우시안 가장자리 탐지의 라플라 시안의 파이썬 구현
-
21-12-2019 - |
문제
나는 가우시안 가장자리 검출의 라플라 시안의 등가 구현을 찾고 있습니다.
MATLAB의
다음 함수를 사용합니다 [BW,threshold] = edge(I,'log',...)
.
파이썬에서 가우시안의 라플라 시안을 계산하는 기능이 있습니다.그것은 가장자리를 확실히 다시주는 것이 아닙니다.
scipy.ndimage.filters.gaussian_laplace
.
온라인 구현 또는 코드에 대한 모든 포인터
감사합니다
해결책
MATLAB EDGE ()가 해야하는
- 계산 로그
- 로그 에 횡단을 계산합니다.
- 로컬 로그 차이 에 대한 임계 값 계산
- 에지 픽셀= 제로 크로스팅 && 로컬 차이> 임계 값
Scipy의 로그 필터는 위의 1 단계 만 수행합니다. 위의 2 ~ 4 단계를 모방하는 다음 스 니펫을 구현했습니다.
import scipy as sp
import numpy as np
import scipy.ndimage as nd
import matplotlib.pyplot as plt
from skimage import data
# lena = sp.misc.lena() this function was deprecated in version 0.17
img = data.camera() # use a standard image from skimage instead
LoG = nd.gaussian_laplace(img , 2)
thres = np.absolute(LoG).mean() * 0.75
output = sp.zeros(LoG.shape)
w = output.shape[1]
h = output.shape[0]
for y in range(1, h - 1):
for x in range(1, w - 1):
patch = LoG[y-1:y+2, x-1:x+2]
p = LoG[y, x]
maxP = patch.max()
minP = patch.min()
if (p > 0):
zeroCross = True if minP < 0 else False
else:
zeroCross = True if maxP > 0 else False
if ((maxP - minP) > thres) and zeroCross:
output[y, x] = 1
plt.imshow(output)
plt.show()
.
이것은 물론 속도가 느리고 아마도 아마도 나는 아마도 python이기도하지만 그 아이디어를 보여 주어야합니다.개선하는 방법에 대한 제안도 환영합니다.
다른 팁
ycyeh의 코드로 조금 연주했습니다 (그것을 제공 해 주셔서 감사합니다).내 응용 프로그램에서는 바이너리 0 및 1S보다 단순한 최소 최대 범위에 비례하는 출력 값을 사용하여 출력 값을 사용하여 더 나은 결과를 얻었습니다.(i는 또한 더 이상 가상도가 필요하지 않지만 결과에 임계 값을 쉽게 적용 할 수 있습니다.) 또한 루프를 숫자가 빠른 실행을 위해 숫자를 변경했습니다.
import numpy as np
import scipy.misc
import cv2 # using opencv as I am not too familiar w/ scipy yet, sorry
def laplace_of_gaussian(gray_img, sigma=1., kappa=0.75, pad=False):
"""
Applies Laplacian of Gaussians to grayscale image.
:param gray_img: image to apply LoG to
:param sigma: Gauss sigma of Gaussian applied to image, <= 0. for none
:param kappa: difference threshold as factor to mean of image values, <= 0 for none
:param pad: flag to pad output w/ zero border, keeping input image size
"""
assert len(gray_img.shape) == 2
img = cv2.GaussianBlur(gray_img, (0, 0), sigma) if 0. < sigma else gray_img
img = cv2.Laplacian(img, cv2.CV_64F)
rows, cols = img.shape[:2]
# min/max of 3x3-neighbourhoods
min_map = np.minimum.reduce(list(img[r:rows-2+r, c:cols-2+c]
for r in range(3) for c in range(3)))
max_map = np.maximum.reduce(list(img[r:rows-2+r, c:cols-2+c]
for r in range(3) for c in range(3)))
# bool matrix for image value positiv (w/out border pixels)
pos_img = 0 < img[1:rows-1, 1:cols-1]
# bool matrix for min < 0 and 0 < image pixel
neg_min = min_map < 0
neg_min[1 - pos_img] = 0
# bool matrix for 0 < max and image pixel < 0
pos_max = 0 < max_map
pos_max[pos_img] = 0
# sign change at pixel?
zero_cross = neg_min + pos_max
# values: max - min, scaled to 0--255; set to 0 for no sign change
value_scale = 255. / max(1., img.max() - img.min())
values = value_scale * (max_map - min_map)
values[1 - zero_cross] = 0.
# optional thresholding
if 0. <= kappa:
thresh = float(np.absolute(img).mean()) * kappa
values[values < thresh] = 0.
log_img = values.astype(np.uint8)
if pad:
log_img = np.pad(log_img, pad_width=1, mode='constant', constant_values=0)
return log_img
def _main():
"""Test routine"""
# load grayscale image
img = scipy.misc.face() # lena removed from newer scipy versions
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# apply LoG
log = laplace_of_gaussian(img)
# display
cv2.imshow('LoG', log)
cv2.waitKey(0)
if __name__ == '__main__':
_main()
. 제휴하지 않습니다 StackOverflow