100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > python canny优化_基于python的自适应阈值的Canny边缘检测

python canny优化_基于python的自适应阈值的Canny边缘检测

时间:2018-11-04 06:07:40

相关推荐

python canny优化_基于python的自适应阈值的Canny边缘检测

canny边缘检测的接口在opencv中给出,直接调用:

ret = cv2.canny(img,t1,t2)

您可以获取边缘检测结果. 其中,t1,t2是需要手动设置的阈值. 许多文献研究了自动阈值设置方法,即该算法可以在运行过程中自适应地找到更好的分割阈值t1

本文基于python3,并复制了一种自适应阈值分割方法.

输入图片为:

输出结果的比较如下: 左图直接使用canny,右图使用本文程序进行自适应分割.

缺点是它是自下而上重写的改进的自适应阈值canny边缘检测,包括非最大抑制之类的过程. . 消耗能量需要很长时间. 上面的输入图像需要27.38s. 我不知道其他学者如何研究自适应阈值Canny边缘检测方法的耗时情况. . 下采样已在程序的预处理过程中完成. 如果没有下采样,则将花费更长的时间.

以下代码:

主程序. py:

import numpy as np

import cv2, time, math

from scipy.signal import convolve2d as conv2

from matplotlib import pyplot as plt

from bilateralfilt import bilatfilt

from dog import deroGauss

import time

#...........................................................................................

def get_edges(I,sd):

dim = I.shape

Idog2d = np.zeros((nang,dim[0],dim[1]))

for i in range(nang):

dog2d = deroGauss(5,sd,angles[i])

Idog2dtemp = abs(conv2(I,dog2d,mode='same',boundary='fill'))

Idog2dtemp[Idog2dtemp<0]=0

Idog2d[i,:,:] = Idog2dtemp

return Idog2d

#...........................................................................................

def nonmaxsup(I,gradang):

dim = I.shape

Inms = np.zeros(dim)

xshift = int(np.round(math.cos(gradang*np.pi/180)))

yshift = int(np.round(math.sin(gradang*np.pi/180)))

Ipad = np.pad(I,(1,),'constant',constant_values = (0,0))

for r in range(1,dim[0]+1):

for c in range(1,dim[1]+1):

maggrad = [Ipad[r-xshift,c-yshift],Ipad[r,c],Ipad[r+xshift,c+yshift]]

if Ipad[r,c] == np.max(maggrad):

Inms[r-1,c-1] = Ipad[r,c]

return Inms

#...........................................................................................

def calc_sigt(I,threshval):

M,N = I.shape

ulim = np.uint8(np.max(I))

N1 = np.count_nonzero(I>threshval)

N2 = np.count_nonzero(I<=threshval)

w1 = np.float64(N1)/(M*N)

w2 = np.float64(N2)/(M*N)

#print N1,N2,w1,w2

try:

u1 = np.sum(i*np.count_nonzero(np.multiply(I>i-0.5,I<=i+0.5))/N1 for i in range(threshval+1,ulim))

u2 = np.sum(i*np.count_nonzero(np.multiply(I>i-0.5,I<=i+0.5))/N2 for i in range(threshval+1))

uT = u1*w1+u2*w2

sigt = w1*w2*(u1-u2)**2

#print u1,u2,uT,sigt

except:

return 0

return sigt

#...........................................................................................

def get_threshold(I):

max_sigt = 0

opt_t = 0

ulim = np.uint8(np.max(I))

print(ulim)

for t in range(ulim+1):

sigt = calc_sigt(I,t)

#print t, sigt

if sigt > max_sigt:

max_sigt = sigt

opt_t = t

print ('optimal high threshold: ',opt_t)

return opt_t

#...........................................................................................

def threshold(I,uth):

lth = uth/2.5

Ith = np.zeros(I.shape)

Ith[I>=uth] = 255

Ith[I

Ith[np.multiply(I>=lth, I

return Ith

#...........................................................................................

def hysteresis(I):

r,c = I.shape

#xshift = int(np.round(math.cos(gradang*np.pi/180)))

#yshift = int(np.round(math.sin(gradang*np.pi/180)))

Ipad = np.pad(I,(1,),'edge')

c255 = np.count_nonzero(Ipad==255)

imgchange = True

for i in range(1,r+1):

for j in range(1,c+1):

if Ipad[i,j] == 100:

#if Ipad[i-xshift,j+yshift]==255 or Ipad[i+xshift,j-yshift]==255:

if np.count_nonzero(Ipad[r-1:r+1,c-1:c+1]==255)>0:

Ipad[i,j] = 255

else:

Ipad[i,j] = 0

Ih = Ipad[1:r+1,1:c+1]

return Ih

#...........................................................................................

#Reading the image

img = cv2.imread('img0030.jpg')

while img.shape[0] > 1100 or img.shape[1] > 1100:

img = cv2.resize(img,None, fx=0.5,fy=0.5,interpolation = cv2.INTER_AREA)

#tic = time.time()

gimg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

dim = img.shape

#...........................................................................................

#Bilateral filtering

print ('Bilateral filtering...\n')

gimg = bilatfilt(gimg,5,3,10)

print ('after bilat: ',np.max(gimg),'\n')

#...........................................................................................

stime = time.time()

angles = [0,45,90,135]

nang = len(angles)

#...........................................................................................

#Gradient of Image

print ('Calculating Gradient...\n')

img_edges = get_edges(gimg,2)

print ('after gradient: ',np.max(img_edges),'\n')

#...........................................................................................

#Non-max suppression

print ('Suppressing Non-maximas...\n')

for n in range(nang):

img_edges[n,:,:] = nonmaxsup(img_edges[n,:,:],angles[n])

print ('after nms: ', np.max(img_edges))

img_edge = np.max(img_edges,axis=0)

lim = np.uint8(np.max(img_edge))

plt.imshow(img_edge)

plt.show()

#...........................................................................................

#Converting to uint8

#img_edges_uint8 = np.uint8(img_edges)

#...........................................................................................

#Thresholding

print ('Calculating Threshold...\n')

th = get_threshold(gimg)

the = get_threshold(img_edge)

#...........................................................................................

print ('\nThresholding...\n')

img_edge = threshold(img_edge, the*0.25)

#cv2.imshow('afterthe',img_edge)

#...........................................................................................

#Hysteresis

print ('Applying Hysteresis...\n')

#for i in xrange(nang):

img_edge = nonmaxsup(hysteresis(img_edge),90)

#...........................................................................................

#img_edge = np.max(img_edges,axis=0)

#...........................................................................................

#OpenCV Canny Function

img_canny = cv2.Canny(np.uint8(gimg),th/3,th)

#toc = time.time()

#print('自适应耗时:',toc-tic)

cv2.imshow('Uncanny',img_edge)

cv2.imshow('Canny',img_canny)

print( 'Time taken :: ', str(time.time()-stime)+' seconds...')

cv2.waitKey(0)

dog.py:

import numpy as np

import math

#Oriented Odd Symmetric Gaussian Filter :: First Derivative of Gaussian

def deroGauss(w=5,s=1,angle=0):

wlim = (w-1)/2

y,x = np.meshgrid(np.arange(-wlim,wlim+1),np.arange(-wlim,wlim+1))

G = np.exp(-np.sum((np.square(x),np.square(y)),axis=0)/(2*np.float64(s)**2))

G = G/np.sum(G)

dGdx = -np.multiply(x,G)/np.float64(s)**2

dGdy = -np.multiply(y,G)/np.float64(s)**2

angle = angle*math.pi/180 #converting to radians

dog = math.cos(angle)*dGdx + math.sin(angle)*dGdy

return dog

bilateralfilt.py:

import numpy as np

#import cv2, time

def bilatfilt(I,w,sd,sr):

dim = I.shape

Iout= np.zeros(dim)

#If the window is 5X5 then w = 5

wlim = (w-1)//2

y,x = np.meshgrid(np.arange(-wlim,wlim+1),np.arange(-wlim,wlim+1))

#Geometric closeness

g = np.exp(-np.sum((np.square(x),np.square(y)),axis=0)/(2*(np.float64(sd)**2)))

#Photometric Similarity

Ipad = np.pad(I,(wlim,),'edge')

for r in range(wlim,dim[0]+wlim):

for c in range(wlim,dim[1]+wlim):

Ix = Ipad[r-wlim:r+wlim+1,c-wlim:c+wlim+1]

s = np.exp(-np.square(Ix-Ipad[r,c])/(2*(np.float64(sr)**2)))

k = np.multiply(g,s)

Iout[r-wlim,c-wlim] = np.sum(np.multiply(k,Ix))/np.sum(k)

return Iout

参考:

(Canny具有基于python2的自适应阈值,有些地方会报告错误)

算法细节,您可以搜索以查看相关文献.

本文来自电脑杂谈,转载请注明本文网址:

http://www.pc-/a/jisuanjixue/article-174876-1.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。