b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

基于python的自适应阈值的Canny边缘检测

电脑杂谈  发布时间:2020-04-14 03:13:02  来源:网络整理

边缘角点检测opencv_改进的自适应阈值canny边缘检测_canny算子边缘检测原理

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

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

您可以获取边缘检测结果. 其中,t1,t2是需要手动设置的阈值. 许多文献研究了自动阈值设置方法,即该算法可以在运行过程中自适应地找到更好的分割阈值t1改进的自适应阈值canny边缘检测,t2,但是缺少开源代码,尤其是基于python3的开源代码.

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

canny算子边缘检测原理_改进的自适应阈值canny边缘检测_边缘角点检测opencv

输入图片为:

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

边缘角点检测opencv_canny算子边缘检测原理_改进的自适应阈值canny边缘检测

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

以下代码:

主程序. py:

边缘角点检测opencv_改进的自适应阈值canny边缘检测_canny算子边缘检测原理

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<lth] = 0
	Ith[np.multiply(I>=lth, I<uth)] = 100
	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:

边缘角点检测opencv_canny算子边缘检测原理_改进的自适应阈值canny边缘检测

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-fly.com/a/jisuanjixue/article-174876-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...