共计 9024 个字符,预计需要花费 23 分钟才能阅读完成。
在科学技术疾速倒退的今日,图像处理技术在科研、军事、工业生产、卫生、教育等与人类生存非亲非故的畛域失去宽泛的利用。人脸识别、主动驾驶、各种无人服务,这些新兴技术都体现了机器视觉零碎正确认知主观世界的重要性。边缘检测是图像处理中最根本却又最艰难的一个问题,边缘检测更是实现图像宰割、指标辨认等图像技术的重要前提。
图像边缘指的是图形四周像素灰度急剧变动的那些像素的汇合,是图像最根本的特色。所谓图像边缘检测就是利用灰度值不间断的性质,以灰度渐变为根底宰割出指标区域,检测出合乎边缘个性的边缘像素,实现图像处理。
1. 经典边缘检测办法
在经典边缘检测算法中,咱们常利用各种微分算子对边缘特色进行提取,以达到图像处理的目标。这些算子蕴含一阶微分算子,如 Sobel 算子、Prewitt 算子、Roberts 算子、Canny 算子等等;还有二阶微分算子,如 Laplacian 算子、LoG 算子等等。以上这些微分算子最终都能实现边缘检测的工作,各有劣势。
1.1 算子在边缘检测中的理论使用
目前,所有具备计算机视觉设计需要的公司都会应用这些算子来进行边缘检测解决,其中咱们耳熟能详的就包含腾讯、谷歌、英特尔、英伟达、特斯拉等等。在腾讯的各游戏部门中,通常须要获取场景对应的深度、法线和色彩信息,而后利用边缘检测算子来判断游戏场景的理论状况,之后进行场景渲染;特斯拉倒退的主动驾驶技术是通过利用车上配置的传感器将理论场景转换成图像,再利用各个算子进行边缘检测算法解决,实现感知周围环境的成果,达到躲避障碍物或变换车道的目标,具体实现办法如下:
1.1.1 利用车载传感器取得车道图像(下图)
编辑 1.1.2 应用 Canny 算子失去边缘检测处理结果:
import cv2
import numpy as np
def canyEdgeDetector(image):
edged = cv2.Canny(image, 50, 150)
return edged
编辑 1.1.3 在解决后的图像上,依据理论需要,定义须要关注的区域。
def getROI(image):
height = image.shape[0]
width = image.shape[1]
# Defining Triangular ROI: The values will change as per your camera mounts
# triangle = np.array([[(100, height), (width, height), (width-500, int(height/1.9))]])
triangle = np.array([[(120, height), (width, height), (400, 228)]])
# creating black image same as that of input image
black_image = np.zeros_like(image)
# Put the Triangular shape on top of our Black image to create a mask
mask = cv2.fillPoly(black_image, triangle, 255)
# applying mask on original image
masked_image = cv2.bitwise_and(image, mask)
return masked_image
1.1.4 为了剖析路况及车道状况,咱们要取得图像中的所有直线,通过以下代码实现:
def getLines(image):
# lines=cv2.HoughLinesP(image,bin_size,precision,threshold,dummy 2d array--no use,minLineLength,maxLineGap)
# lets take bin size to be 2 pixels
# lets take precision to be 1 degree= pi/180 radians
# threshold is the votes that a bin should have to be accepted to draw a line
# minLineLength --the minimum length in pixels a line should have to be accepted.
# maxLineGap --the max gap between 2 broken line which we allow for 2 lines to be connected together.
lines = cv2.HoughLinesP(image, 0.3, np.pi/180, 100, np.array([]),minLineLength=70, maxLineGap=20)
return lines
编辑再通过以下程序获取图像和线条列表,并在图像上绘制出线条:
#display lines over a image
def displayLines(image, lines):
if lines is not None:
for line in lines:
# print(line) --output like [[704 418 927 641]] this is 2d array representing [[x1,y1,x2,y2]] for each line
x1, y1, x2, y2 = line.reshape(4) # converting to 1d array []
# draw line over black image --(255,0,0) tells we want to draw blue line (b,g,r) values 10 is line thickness
cv2.line(image, (x1, y1), (x2, y2), (255, 0, 0), 10)
return image
定义另一个效用函数从斜率和截距中获取线坐标
def getLineCoordinatesFromParameters(image,
line_parameters):
slope = line_parameters[0]
intercept = line_parameters[1]
y1 = image.shape[0] # since line will always start from bottom of image
y2 = int(y1 * (3.4 / 5)) # some random point at 3/5
x1 = int((y1 - intercept) / slope)
x2 = int((y2 - intercept) / slope)
return np.array([x1, y1, x2, y2])
1.1.5 将上述失去的直线进行分组,分组后找到各组的均匀斜率和截距,并通过算法为每个组创立一条线。
#Avergaes all the left and right lines found for a lane and retuns single left and right line for the the lane
def getSmoothLines(image, lines):
left_fit = [] # will hold m,c parameters for left side lines
right_fit = [] # will hold m,c parameters for right side lines
for line in lines:
x1, y1, x2, y2 = line.reshape(4)
# polyfit gives slope(m) and intercept(c) values from input points
# last parameter 1 is for linear..so it will give linear parameters m,c
parameters = np.polyfit((x1, x2), (y1, y2), 1)
slope = parameters[0]
intercept = parameters[1]
if slope < 0:
left_fit.append((slope, intercept))
else:
right_fit.append((slope, intercept))
# take averages of all intercepts and slopes separately and get 1 single value for slope,intercept
# axis=0 means vertically...see its always (row,column)...so row is always 0 position.
# so axis 0 means over row(vertically)
left_fit_average = np.average(left_fit, axis=0)
right_fit_average = np.average(right_fit, axis=0)
# now we have got m,c parameters for left and right line, we need to know x1,y1 x2,y2 parameters
left_line = getLineCoordinatesFromParameters(image, left_fit_average)
right_line = getLineCoordinatesFromParameters(image, right_fit_average)
return np.array([left_line, right_line])
编辑 1.1.6 通过上述所有步骤的解决之后,咱们就通过 Canny 算子进行的边缘检测解决取得了独自的函数,咱们只须要在主代码中调用它们,就可能通过车载图传取得车道信息进行下一步的解决。
image = cv2.imread("3d21d93f722e1e3a5dd8fd8bbcd1c5d0.png") #Load Image
edged_image = canyEdgeDetector(image) # Step 1
roi_image = getROI(edged_image) # Step 2
lines = getLines(roi_image) # Step 3
image_with_lines = displayLines(image, lines)
cv2.imshow("Output", roi_image)
# cv2.waitKey(0)
# smooth_lines = getSmoothLines(image, lines) # Step 5
# image_with_smooth_lines = displayLines(image, smooth_lines) # Step 4
#
# cv2.imshow("Output", image_with_smooth_lines)
cv2.waitKey(0)
编辑 1.2 各个算子边缘检测能力的区别
通过上述边缘检测算法实现车道剖析之后,主动驾驶零碎会很具理论状况判断是否须要变道或者躲避障碍物,这就是当初边缘检测在理论利用中所施展的作用。各个算子在实际操作中,对于图像边缘检测的实现状况也略有不同,具体有什么样的区别,咱们能够看看以下实例:
1.2.1 Roberts 算子
Roberts 算子又称为穿插微分算法,它是基于穿插差分的梯度算法,通过部分差分计算检测边缘线条。罕用来解决具备平缓的低噪声图像,当图像边缘靠近于正 45 度或负 45 度时,该算法解决成果更现实。其毛病是对边缘的定位不太精确,提取的边缘线条较粗。
编辑 1.2.2 Prewitt 算子
Prewitt 算子是一种图像边缘检测的微分算子,其原理是利用特定区域内像素灰度值产生的差分实现边缘检测。因为 Prewitt 算子采纳 33 模板对区域内的像素值进行计算,而 Robert 算子的模板为 22,故 Prewitt 算子的边缘检测后果在程度方向和垂直方向均比 Robert 算子更加显著。Prewitt 算子适宜用来辨认噪声较多、灰度突变的图像。
编辑 1.2.3 Sobel 算子
Sobel 算子是一种用于边缘检测的离散微分算子,它联合了高斯平滑和微分求导。该算子用于计算图像明暗水平近似值,依据图像边缘旁边明暗水平把该区域内超过某个数的特定点记为边缘。Sobel 算子在 Prewitt 算子的根底上减少了权重的概念,认为相邻点的间隔远近对以后像素点的影响是不同的,间隔越近的像素点对应以后像素的影响越大,从而实现图像锐化并突出边缘轮廓。Sobel 算子的边缘定位更精确,罕用于噪声较多、灰度突变的图像。
编辑 1.2.4 Laplacian 算子
Laplacian 算子是维欧几里德空间中的一个二阶微分算子,通过灰度差分计算邻域内的像素。Laplacian 算子其实次要是利用 Sobel 算子的运算,通过加上 Sobel 算子运算出的图像 X 方向和 Y 方向上的导数,失去输出图像的图像锐化后果。同时,在进行 Laplacian 算子解决之后,还须要调用 convertScaleAbs() 函数计算绝对值,并将图像转换为 8 位图进行显示。Laplacian 算子容易失落一部分边缘的方向信息,造成一些不间断的检测边缘,同时抗噪声能力比拟差,因为其算法可能会呈现双像素边界,罕用来判断边缘像素位于图像的明区或暗区,很少用于边缘检测。
2. 经典边缘检测技术新倒退
随着数学实践和人工智能技术的倒退,经典边缘检测还联合了很多相干畛域内的理论知识造成了一些新的检测办法,以下是这些新办法中较为常见的几个例子:
2.1 基于数学形态学的边缘检测:
数学形态学是基于积分几何和几何概论建设的对于图像形态和尺寸的钻研办法,本质上是一种非线性滤波办法。数学形态学的办法利用于视觉图像的解决就是用具备肯定形态、大小的构造元素去探测、度量和提取图像中对应形态,以达到对图像进行解决、剖析辨认的目标。在图像处理的过程中,次要应用的是二值形态学和灰度形态学。咱们能够来看看这个办法对于图像轮廓的提取能力如何:
2.2 基于小波和小波包变换的边缘检测算法:
小波变换具备十分丰盛的数学实践做撑持,有着十分大的发展前景;小波变换很好的利用了时域频域的部分化特色,通过对信号进行细化剖析,能达到高频处工夫细分、低频处频率细分,所以小波变换适宜简单图像的边缘检测,它的边缘解决能力如下:
2.3 基于含糊实践的边缘检测算法:
理论利用中的图像边缘是不确定的,具备模糊性,用经典数学形容不精确,所以利用含糊实践进行边缘检测时,首先将图像看作是一个模糊集,将图像中每一个具备特定灰度级的元素进行标记,从而将待处理的图像映射为具备含糊特色的矩阵,在此基础上进行含糊加强解决,因为图像边缘梯度的模糊性,这个办法可能失去比拟好的边缘检测成果。下图就是含糊办法解决后失去的图像边缘:
2.4 基于神经网络的边缘检测算法:
神经网络是一种基于现有数据创立预测的计算零碎,随着神经网络技术的倒退,人们又将其退出到图像边缘检测中,心愿可能取得更好的检测后果。神经网络的边缘检测个别利用 BP 网络,采纳滚动训练和权值随机扰动办法,进步了神经网络的学习效果,取得的边缘图像封闭性好,更加准确。咱们来看看它理论的解决能力:
除了上述的微分算子边缘检测及倒退出的几个新办法外,还有很多畛域的钻研人员联合本人的理论知识提出了不少新算法,比方基于分形几何的边缘检测算法、基于遗传算法的边缘检测算法、漫射边缘检测办法、多尺度边缘检测技术、亚像素边缘定位技术、FCM 聚类的边缘检测算法等等,都可能获得较好的图像边缘检测成果。
3. 经典边缘检测的理论利用及局限
随着图像边缘检测技术的欠缺和倒退,它的成绩早曾经融入到咱们生存的方方面面。咱们平时应用的手机面容解锁,数码相机的眼部追踪和主动对焦性能,翻译软件的拍照辨认翻译,停车场车牌号检测,文字辨认等等,都使用到了图像的边缘检测技术。在很多业余畛域内,都依赖于图像边缘检测技术带来的成绩,比方在医疗畛域,B 超、CT 的剖析也是依附图像边缘检测实现的,像无人驾驶等等畛域也都有它的身影。能够说,咱们曾经享受到很多边缘检测技术带来的便当。
目前所有在应用的传统图像边缘检测算法在大部分工夫内能够满足咱们工作生产的需要,但它们都不具备绝对优势,一个好的边缘检测办法一方面要求可能检测出无效边缘,另一方面要求其抗噪能力强,目前的经典边缘检测算法或多或少都会遇到噪声的影响,如椒盐噪声、高斯噪声等等;同时在理论生存中,当咱们碰到尺寸、分辨率更大的图像时,经典边缘检测算法必须要对像素一一进行计算,这就带来了很大的工作量和微小的工夫老本。
4. 量子算法的退场
在更高效率的需要下,很多人将眼光转向了量子算法畛域。随着量子力学和信息科学的倒退,基于量子信号处理的图像处理钻研是目前图像处理的前沿。如果咱们采纳量子算法进行图像边缘检测,依靠于量子态叠加和量子纠缠带来的微小并行计算的能力,量子图像处理与经典图像处理相比具备人造的劣势,能为图像边缘检测带来指数级的减速。
4.1 量子算法的实现原理:
在应用量子算法进行图像边缘检测时,首先咱们须要将图像各个像素归一化,让每个像素的概率加权等于 1,而后让这些像素矢量转化成为比特字串,通过一个置换酉阵,咱们就能够检测像素矢量的梯度了,之后的工作就是找到像素从明变动到暗的地位,这就是咱们须要的图像边缘所在的点。(下图所示为量子电位图)
4.2 量子算法进行边缘检测的步骤:
具体操作步骤如下图所示:算法的输入量,是一张解决好的 256×256 的灰度图,像素点的值在 0 到 1 之间。之后图片会被宰割成 1024 张 16×16 的子图,对每一张子图,咱们创立格局雷同的两个量子电路,别离用于解决子图的横向边缘扫描和纵向边缘扫描,扫描的后果,是一张 16×16 的横向扫描图和一张 16×16 的纵向扫描图的和,即为这张子图对应的图像边缘。当咱们对这 1024 张子图全副进行上述的步骤后,将失去的 1024 张扫描后果进行重构,失去一张 256×256 的残缺灰度图,这张图即为输入后果。解决时的具体步骤如下图所示:
4.3 量子算法实现边缘检测的步骤代码实现量子算法检测边缘步骤所须要的算法代码如下:
from edge_detection import QED,crop_image,plot_image
import cv2
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
第一步:图像预处理
1. 将须要进⾏图形边缘检测的图⽚,通过 Image.open ⽅式关上,并转换成灰度图(Lmodeimage)存储
2. 读出存储的灰度图,并剪切⾄算法能够解决的⼤⼩:256×256
3. 将像素值不⾜ 0.5 的设置为 0,⼤于 0.5 的设置为 1
4. 将 256×256 ⼤⼩的图⽚,宰割成 16×16 的图⽚堆
img = Image.open('./test.jpeg').convert('L')
img.save('grey.png')
image256 = plt.imread("grey.png")
res = cv2.resize(image256, dsize=(256, 256),
interpolation=cv2.INTER_CUBIC)
res[res\<.5] = 0
res[res\>.5] = 1
crop = crop_image(res)
cropped = crop.image_stack
plot_image(res,"original image")
第二步:量子 QED 实例化
1. 对每⼀个图⽚堆中的 16×16 的宰割⼦图,咱们使⽤ QED 算法,失去宰割后的图像
2. 对图⽚堆中的每⼀个⼦图实现循环,咱们失去⼀个边缘检测之后的图⽚堆 image_out
3. ⽣成⼀张和原图像⼀样⼤⼩的 error_correction 图⽚,⽤于像素值校对
4. 最初边缘检测的后果,即为 image_edge+error_correction
image_out = np.zeros(cropped.shape)
for i in range(len(cropped)):
if (np.sum(cropped[i])>0) * (np.sum(cropped[i])<256):
method = QED(image_in = cropped[i])
out = method.get_scan_images()
image_out[i] = out[2]
image_edge = crop.reshape(image_out)
error_correction = np.ones((256,256))
for i in range(1,16):
error_correction[i*16-1] = 0
for j in range(1,16):
error_correction[:,j*16-1] = 0
plot_image(image_edge*error_correction,"edge detected image")
能够看到,通过解决后的图像边缘解决是十分清晰的,阐明量子算法在图像处理上会比传统的边缘检测成果更好。同时咱们还将量子算法与传统边缘检测数据进行了比照(下图),咱们发现在所破费的工夫上,量子算法的确快了很多,同时随着边缘检测图片像素数量的减少,量子算法所具备的劣势会越来越显著。
5. 量子算法将来的倒退
现阶段,量子算法在图像边缘检测上的劣势曾经初见成效,启科量子作为量子畛域的先行者,会在量子算法畛域深耕,大大放慢量子算法在利用方面的试验工作,施展量子算法在计算机视觉方向等畛域上的全副潜能,为行业倒退做出应有的奉献。同时,启科量子也会借着量子畛域的东风,积极探索,怯懦尝试,努力实现企业价值,不遗余力地为量子算法以及量子计算畛域的倒退添砖加瓦。文章转载自启科量子开发者社区,欢送关注!
注:局部图片及内容来源于网络,如有侵权,请分割删除。
参考链接:
1.https://blog.csdn.net/qq_4272…
2.https://blog.csdn.net/zaishui…
3.https://blog.csdn.net/simonyu…
4.https://www.dounaite.com/arti…
5.Xi-Wei Yao. Quantum Image Processing and Its Application to Edge Detection: Theory and Experiment. Physical Review X 7,031041(2017)
6. 王敏杰. 图像边缘检测技术综述 [J]. 中南大学学报(自然科学版).2011.9
7. 王军敏. 基于多尺度小波变换的图像边缘检测 [J]. 平顶山学院学报.2013
原文链接:
https://mp.weixin.qq.com/s/kM…