ho11laqe's picture
init
ecf08bc
raw
history blame
5.71 kB
from scipy import ndimage
from scipy.ndimage.filters import convolve
from scipy import misc
import numpy as np
import cv2
class cannyEdgeDetector:
def __init__(self, imgs, sigma=5, kernel_size=10, weak_pixel=75, strong_pixel=255, lowthreshold=0.05,
highthreshold=0.15):
self.imgs = imgs
self.imgs_final = []
self.img_smoothed = None
self.gradientMat = None
self.thetaMat = None
self.nonMaxImg = None
self.thresholdImg = None
self.weak_pixel = weak_pixel
self.strong_pixel = strong_pixel
self.sigma = sigma
self.kernel_size = kernel_size
self.lowThreshold = lowthreshold
self.highThreshold = highthreshold
return
def gaussian_kernel(self, size, sigma=1):
size = int(size) // 2
x, y = np.mgrid[-size:size + 1, -size:size + 1]
normal = 1 / (2.0 * np.pi * sigma ** 2)
g = np.exp(-((x ** 2 + y ** 2) / (2.0 * sigma ** 2))) * normal
return g
def sobel_filters(self, img):
Kx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], np.float32)
Ky = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], np.float32)
Ix = ndimage.filters.convolve(img, Kx)
Iy = ndimage.filters.convolve(img, Ky)
G = np.hypot(Ix, Iy)
G = G / G.max() * 255
theta = np.arctan2(Iy, Ix)
return (G, theta, Ix, Iy)
def non_max_suppression(self, img, D):
M, N = img.shape
Z = np.zeros((M, N), dtype=np.int32)
angle = D * 180. / np.pi
angle[angle < 0] += 180
for i in range(1, M - 1):
for j in range(1, N - 1):
try:
q = 255
r = 255
# angle 0
if (0 <= angle[i, j] < 22.5) or (157.5 <= angle[i, j] <= 180):
q = img[i, j + 1]
r = img[i, j - 1]
# angle 45
elif (22.5 <= angle[i, j] < 67.5):
q = img[i + 1, j - 1]
r = img[i - 1, j + 1]
# angle 90
elif (67.5 <= angle[i, j] < 112.5):
q = img[i + 1, j]
r = img[i - 1, j]
# angle 135
elif (112.5 <= angle[i, j] < 157.5):
q = img[i - 1, j - 1]
r = img[i + 1, j + 1]
if (img[i, j] >= q) and (img[i, j] >= r):
Z[i, j] = img[i, j]
else:
Z[i, j] = 0
except IndexError as e:
pass
return Z
def threshold(self, img):
highThreshold = img.max() * self.highThreshold;
lowThreshold = highThreshold * self.lowThreshold;
M, N = img.shape
res = np.zeros((M, N), dtype=np.int32)
weak = np.int32(self.weak_pixel)
strong = np.int32(self.strong_pixel)
strong_i, strong_j = np.where(img >= highThreshold)
zeros_i, zeros_j = np.where(img < lowThreshold)
weak_i, weak_j = np.where((img <= highThreshold) & (img >= lowThreshold))
res[strong_i, strong_j] = strong
res[weak_i, weak_j] = weak
return (res)
def hysteresis(self, img):
M, N = img.shape
weak = self.weak_pixel
strong = self.strong_pixel
for i in range(1, M - 1):
for j in range(1, N - 1):
if (img[i, j] == weak):
try:
if ((img[i + 1, j - 1] == strong) or (img[i + 1, j] == strong) or (img[i + 1, j + 1] == strong)
or (img[i, j - 1] == strong) or (img[i, j + 1] == strong)
or (img[i - 1, j - 1] == strong) or (img[i - 1, j] == strong) or (
img[i - 1, j + 1] == strong)):
img[i, j] = strong
else:
img[i, j] = 0
except IndexError as e:
pass
return img
def detect(self):
imgs_final = []
for i, img in enumerate(self.imgs):
cv2.imwrite('output/0img.png', img)
self.img_smoothed = convolve(img, self.gaussian_kernel(self.kernel_size, self.sigma))
self.img_smoothed = self.img_smoothed/np.max(self.img_smoothed)*255
cv2.imwrite('output/1smoothed.png', self.img_smoothed)
self.gradientMat, self.thetaMat, Ix, Iy = self.sobel_filters(self.img_smoothed)
cv2.imwrite('output/2Ix.png', Ix)
cv2.imwrite('output/2Iy.png', Iy)
cv2.imwrite('output/4deltaI.png', self.gradientMat.astype(float))
cv2.imwrite('output/5theta.png', self.thetaMat.astype(float) / np.max(self.thetaMat) * 255)
self.nonMaxImg = self.non_max_suppression(self.gradientMat, self.thetaMat)
cv2.imwrite('output/6nonmax.png', self.nonMaxImg)
self.thresholdImg = self.threshold(self.nonMaxImg)
cv2.imwrite('output/7threshold.png', self.thresholdImg)
img_final = self.hysteresis(self.thresholdImg)
self.imgs_final.append(img_final)
return self.imgs_final
if __name__ == '__main__':
image_path = '/home/ho11laqe/PycharmProjects/data_raw/sar_images/test/Mapple_2011-06-02_TSX_7_1_110.png'
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)[:1000,-1000:].astype(np.float32)
detector = cannyEdgeDetector([img], sigma=20)
edge = detector.detect()
cv2.imwrite('output/8edge.png', edge[0])