圖像邊緣檢測新方向--量子算法

在科學(xué)技術(shù)快速發(fā)展的今日,圖像處理技術(shù)在科研、軍事、工業(yè)生產(chǎn)、衛(wèi)生、教育等與人類生活息息相關(guān)的領(lǐng)域得到廣泛的應(yīng)用。人臉識別、自動駕駛、各種無人服務(wù),這些新興技術(shù)都體現(xiàn)了機(jī)器視覺系統(tǒng)正確認(rèn)知客觀世界的重要性。邊緣檢測是圖像處理中最基本卻又最困難的一個問題,邊緣檢測更是實現(xiàn)圖像分割、目標(biāo)識別等圖像技術(shù)的重要前提。

圖像邊緣指的是圖形周圍像素灰度急劇變化的那些像素的集合,是圖像最基本的特征。所謂圖像邊緣檢測就是利用灰度值不連續(xù)的性質(zhì),以灰度突變?yōu)榛A(chǔ)分割出目標(biāo)區(qū)域,檢測出符合邊緣特性的邊緣像素,完成圖像處理。

1. 經(jīng)典邊緣檢測方法

在經(jīng)典邊緣檢測算法中,我們常利用各種微分算子對邊緣特征進(jìn)行提取,以達(dá)到圖像處理的目的。這些算子包含一階微分算子,如 Sobel 算子、Prewitt 算子、Roberts 算子、Canny 算子等等;還有二階微分算子,如 Laplacian 算子、LoG 算子等等。以上這些微分算子最終都能完成邊緣檢測的任務(wù),各有優(yōu)勢。

1.1 算子在邊緣檢測中的實際運(yùn)用

目前,所有具有計算機(jī)視覺設(shè)計需求的公司都會使用這些算子來進(jìn)行邊緣檢測處理,其中我們耳熟能詳?shù)木桶v訊、谷歌、英特爾、英偉達(dá)、特斯拉等等。在騰訊的各游戲部門中,通常需要獲取場景對應(yīng)的深度、法線和顏色信息,然后利用邊緣檢測算子來判斷游戲場景的實際情況,之后進(jìn)行場景渲染;特斯拉發(fā)展的自動駕駛技術(shù)是通過利用車上配置的傳感器將實際場景轉(zhuǎn)換成圖像,再利用各個算子進(jìn)行邊緣檢測算法處理,實現(xiàn)感知周圍環(huán)境的效果,達(dá)到規(guī)避障礙物或變換車道的目的,具體實現(xiàn)方法如下:

1.1.1 利用車載傳感器獲得車道圖像(下圖)

圖片

1.1.2 使用 Canny 算子得到邊緣檢測處理結(jié)果:

import cv2import numpy as npdef canyEdgeDetector(image):    edged = cv2.Canny(image, 50, 150)    return edged
圖片

1.1.3 在處理后的圖像上,根據(jù)實際需求,定義需要關(guān)注的區(qū)域。

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 imagedef 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

定義另一個效用函數(shù)從斜率和截距中獲取線坐標(biāo)

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 將上述得到的直線進(jìn)行分組,分組后找到各組的平均斜率和截距,并通過算法為每個組創(chuàng)建一條線。

#Avergaes all the left and right lines found for a lane and retuns single left and right line for the the lanedef 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 parametersleft_line = getLineCoordinatesFromParameters(image, left_fit_average)right_line = getLineCoordinatesFromParameters(image, right_fit_average)return np.array([left_line, right_line])
圖片

1.1.6 經(jīng)過上述所有步驟的處理之后,我們就通過 Canny 算子進(jìn)行的邊緣檢測處理獲得了單獨(dú)的函數(shù),我們只需要在主代碼中調(diào)用它們,就能夠通過車載圖傳獲得車道信息進(jìn)行下一步的處理。

image = cv2.imread("3d21d93f722e1e3a5dd8fd8bbcd1c5d0.png") #Load Imageedged_image = canyEdgeDetector(image) # Step 1roi_image = getROI(edged_image) # Step 2lines = getLines(roi_image)             # Step 3image_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 各個算子邊緣檢測能力的區(qū)別

通過上述邊緣檢測算法完成車道分析之后,自動駕駛系統(tǒng)會很具實際情況判斷是否需要變道或者規(guī)避障礙物,這就是現(xiàn)在邊緣檢測在實際應(yīng)用中所發(fā)揮的作用。各個算子在實際操作中,對于圖像邊緣檢測的完成情況也略有不同,具體有什么樣的區(qū)別,我們可以看看以下實例:

1.2.1 Roberts 算子

Roberts 算子又稱為交叉微分算法,它是基于交叉差分的梯度算法,通過局部差分計算檢測邊緣線條。常用來處理具有陡峭的低噪聲圖像,當(dāng)圖像邊緣接近于正 45 度或負(fù) 45 度時,該算法處理效果更理想。其缺點(diǎn)是對邊緣的定位不太準(zhǔn)確,提取的邊緣線條較粗。

圖片

1.2.2 Prewitt 算子

Prewitt 算子是一種圖像邊緣檢測的微分算子,其原理是利用特定區(qū)域內(nèi)像素灰度值產(chǎn)生的差分實現(xiàn)邊緣檢測。由于 Prewitt 算子采用 33 模板對區(qū)域內(nèi)的像素值進(jìn)行計算,而 Robert 算子的模板為 22,故 Prewitt 算子的邊緣檢測結(jié)果在水平方向和垂直方向均比 Robert 算子更加明顯。Prewitt 算子適合用來識別噪聲較多、灰度漸變的圖像。

圖片

1.2.3 Sobel 算子

Sobel 算子是一種用于邊緣檢測的離散微分算子,它結(jié)合了高斯平滑和微分求導(dǎo)。該算子用于計算圖像明暗程度近似值,根據(jù)圖像邊緣旁邊明暗程度把該區(qū)域內(nèi)超過某個數(shù)的特定點(diǎn)記為邊緣。Sobel 算子在 Prewitt 算子的基礎(chǔ)上增加了權(quán)重的概念,認(rèn)為相鄰點(diǎn)的距離遠(yuǎn)近對當(dāng)前像素點(diǎn)的影響是不同的,距離越近的像素點(diǎn)對應(yīng)當(dāng)前像素的影響越大,從而實現(xiàn)圖像銳化并突出邊緣輪廓。Sobel 算子的邊緣定位更準(zhǔn)確,常用于噪聲較多、灰度漸變的圖像。

圖片

1.2.4 Laplacian 算子

Laplacian 算子是維歐幾里德空間中的一個二階微分算子,通過灰度差分計算鄰域內(nèi)的像素。Laplacian 算子其實主要是利用 Sobel 算子的運(yùn)算,通過加上 Sobel 算子運(yùn)算出的圖像 X 方向和 Y 方向上的導(dǎo)數(shù),得到輸入圖像的圖像銳化結(jié)果。同時,在進(jìn)行 Laplacian 算子處理之后,還需要調(diào)用 convertScaleAbs()函數(shù)計算絕對值,并將圖像轉(zhuǎn)換為 8 位圖進(jìn)行顯示。Laplacian 算子容易丟失一部分邊緣的方向信息,造成一些不連續(xù)的檢測邊緣,同時抗噪聲能力比較差,由于其算法可能會出現(xiàn)雙像素邊界,常用來判斷邊緣像素位于圖像的明區(qū)或暗區(qū),很少用于邊緣檢測。

圖片

2. 經(jīng)典邊緣檢測技術(shù)新發(fā)展

隨著數(shù)學(xué)理論和人工智能技術(shù)的發(fā)展,經(jīng)典邊緣檢測還結(jié)合了很多相關(guān)領(lǐng)域內(nèi)的理論知識形成了一些新的檢測方法,以下是這些新方法中較為常見的幾個例子:

2.1 基于數(shù)學(xué)形態(tài)學(xué)的邊緣檢測:

數(shù)學(xué)形態(tài)學(xué)是基于積分幾何和幾何概論建立的關(guān)于圖像形狀和尺寸的研究方法,實質(zhì)上是一種非線性濾波方法。數(shù)學(xué)形態(tài)學(xué)的方法應(yīng)用于視覺圖像的處理就是用具有一定形狀、大小的結(jié)構(gòu)元素去探測、度量和提取圖像中對應(yīng)形狀,以達(dá)到對圖像進(jìn)行處理、分析識別的目的。在圖像處理的過程中,主要使用的是二值形態(tài)學(xué)和灰度形態(tài)學(xué)。我們可以來看看這個方法對于圖像輪廓的提取能力如何:

圖片
圖片

2.2 基于小波和小波包變換的邊緣檢測算法:

小波變換具有非常豐富的數(shù)學(xué)理論做支撐,有著非常大的發(fā)展前景;小波變換很好的利用了時域頻域的局部化特征,通過對信號進(jìn)行細(xì)化分析,能達(dá)到高頻處時間細(xì)分、低頻處頻率細(xì)分,所以小波變換適合復(fù)雜圖像的邊緣檢測,它的邊緣處理能力如下:

圖片

2.3 基于模糊理論的邊緣檢測算法:

實際應(yīng)用中的圖像邊緣是不確定的,具有模糊性,用經(jīng)典數(shù)學(xué)描述不準(zhǔn)確,所以利用模糊理論進(jìn)行邊緣檢測時,首先將圖像看作是一個模糊集,將圖像中每一個具有特定灰度級的元素進(jìn)行標(biāo)記,從而將待處理的圖像映射為具有模糊特征的矩陣,在此基礎(chǔ)上進(jìn)行模糊增強(qiáng)處理,由于圖像邊緣梯度的模糊性,這個方法能夠得到比較好的邊緣檢測效果。下圖就是模糊方法處理后得到的圖像邊緣:

圖片

2.4 基于神經(jīng)網(wǎng)絡(luò)的邊緣檢測算法:

神經(jīng)網(wǎng)絡(luò)是一種基于現(xiàn)有數(shù)據(jù)創(chuàng)建預(yù)測的計算系統(tǒng),隨著神經(jīng)網(wǎng)絡(luò)技術(shù)的發(fā)展,人們又將其加入到圖像邊緣檢測中,希望能夠獲得更好的檢測結(jié)果。神經(jīng)網(wǎng)絡(luò)的邊緣檢測一般利用 BP 網(wǎng)絡(luò),采用滾動訓(xùn)練和權(quán)值隨機(jī)擾動方法,提高了神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)效果,獲得的邊緣圖像封閉性好,更加精確。我們來看看它實際的處理能力:

圖片

除了上述的微分算子邊緣檢測及發(fā)展出的幾個新方法外,還有很多領(lǐng)域的研究人員結(jié)合自己的理論知識提出了不少新算法,比如基于分形幾何的邊緣檢測算法、基于遺傳算法的邊緣檢測算法、漫射邊緣檢測方法、多尺度邊緣檢測技術(shù)、亞像素邊緣定位技術(shù)、FCM 聚類的邊緣檢測算法等等,都能夠取得較好的圖像邊緣檢測效果。

3. 經(jīng)典邊緣檢測的實際應(yīng)用及局限

隨著圖像邊緣檢測技術(shù)的完善和發(fā)展,它的成果早已經(jīng)融入到我們生活的方方面面。我們平時使用的手機(jī)面容解鎖,數(shù)碼相機(jī)的眼部追蹤和自動對焦功能,翻譯軟件的拍照識別翻譯,停車場車牌號檢測,文字識別等等,都運(yùn)用到了圖像的邊緣檢測技術(shù)。在很多專業(yè)領(lǐng)域內(nèi),都依賴于圖像邊緣檢測技術(shù)帶來的成果,比如在醫(yī)療領(lǐng)域,B 超、CT 的分析也是依靠圖像邊緣檢測完成的,像無人駕駛等等領(lǐng)域也都有它的身影。可以說,我們已經(jīng)享受到很多邊緣檢測技術(shù)帶來的便利。

目前所有在使用的傳統(tǒng)圖像邊緣檢測算法在大部分時間內(nèi)可以滿足我們工作生產(chǎn)的需求,但它們都不具備絕對優(yōu)勢,一個好的邊緣檢測方法一方面要求能夠檢測出有效邊緣,另一方面要求其抗噪能力強(qiáng),目前的經(jīng)典邊緣檢測算法或多或少都會遇到噪聲的影響,如椒鹽噪聲、高斯噪聲等等;同時在實際生活中,當(dāng)我們碰到尺寸、分辨率更大的圖像時,經(jīng)典邊緣檢測算法必須要對像素逐個進(jìn)行計算,這就帶來了很大的工作量和巨大的時間成本。

4. 量子算法的登場

在更高效率的需求下,很多人將目光轉(zhuǎn)向了量子算法領(lǐng)域。隨著量子力學(xué)和信息科學(xué)的發(fā)展,基于量子信號處理的圖像處理研究是目前圖像處理的前沿。如果我們采用量子算法進(jìn)行圖像邊緣檢測,依托于量子態(tài)疊加和量子糾纏帶來的巨大并行計算的能力,量子圖像處理與經(jīng)典圖像處理相比具有天然的優(yōu)勢,能為圖像邊緣檢測帶來指數(shù)級的加速。

4.1 量子算法的實現(xiàn)原理:

在使用量子算法進(jìn)行圖像邊緣檢測時,首先我們需要將圖像各個像素歸一化,讓每個像素的概率加權(quán)等于 1,然后讓這些像素矢量轉(zhuǎn)化成為比特字串,經(jīng)過一個置換酉陣,我們就可以檢測像素矢量的梯度了,之后的工作就是找到像素從明變化到暗的位置,這就是我們需要的圖像邊緣所在的點(diǎn)。(下圖所示為量子電位圖)

圖片

4.2 量子算法進(jìn)行邊緣檢測的步驟:

具體操作步驟如下圖所示:算法的輸入量,是一張?zhí)幚砗玫?256×256 的灰度圖,像素點(diǎn)的值在 0 到 1 之間。之后圖片會被分割成 1024 張 16×16 的子圖,對每一張子圖,我們創(chuàng)建格式相同的兩個量子電路,分別用于處理子圖的橫向邊緣掃描和縱向邊緣掃描,掃描的結(jié)果,是一張 16×16 的橫向掃描圖和一張 16×16 的縱向掃描圖的和,即為這張子圖對應(yīng)的圖像邊緣。當(dāng)我們對這 1024 張子圖全部進(jìn)行上述的步驟后,將得到的 1024 張掃描結(jié)果進(jìn)行重構(gòu),得到一張 256×256 的完整灰度圖,這張圖即為輸出結(jié)果。處理時的具體步驟如下圖所示:

圖片

4.3 量子算法完成邊緣檢測的步驟代碼

完成量子算法檢測邊緣步驟所需要的算法代碼如下:

from edge_detection import QED,crop_image,plot_imageimport cv2from PIL import Imageimport numpy as npimport matplotlib.pyplot as plt

第一步:圖像預(yù)處理

  1. 將需要進(jìn)?圖形邊緣檢測的圖?,通過 Image.open ?式打開,并轉(zhuǎn)換成灰度圖(Lmodeimage)存儲

  2. 讀出存儲的灰度圖,并剪切?算法可以處理的??:256×256

  3. 將像素值不? 0.5 的設(shè)置為 0,?于 0.5 的設(shè)置為 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] = 0res[res\>.5] = 1crop = crop_image(res)cropped = crop.image_stackplot_image(res,"original image")
圖片

第二步:量子 QED 實例化

  1. 對每?個圖?堆中的 16×16 的分割?圖,我們使? QED 算法,得到分割后的圖像

  2. 對圖?堆中的每?個?圖完成循環(huán),我們得到?個邊緣檢測之后的圖?堆 image_out

  3. ?成?張和原圖像?樣??的 error_correction 圖?,?于像素值校正

  4. 最后邊緣檢測的結(jié)果,即為 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")  
圖片

可以看到,經(jīng)過處理后的圖像邊緣處理是非常清晰的,說明量子算法在圖像處理上會比傳統(tǒng)的邊緣檢測效果更好。同時我們還將量子算法與傳統(tǒng)邊緣檢測數(shù)據(jù)進(jìn)行了對比(下圖),我們發(fā)現(xiàn)在所花費(fèi)的時間上,量子算法確實快了很多,同時隨著邊緣檢測圖片像素數(shù)量的增加,量子算法所具有的優(yōu)勢會越來越明顯。

圖片

5. 量子算法未來的發(fā)展

現(xiàn)階段,量子算法在圖像邊緣檢測上的優(yōu)勢已經(jīng)初見成效,啟科量子作為量子領(lǐng)域的先行者,會在量子算法領(lǐng)域深耕,大大加快量子算法在應(yīng)用方面的實驗工作,發(fā)揮量子算法在計算機(jī)視覺方向等領(lǐng)域上的全部潛能,為行業(yè)發(fā)展做出應(yīng)有的貢獻(xiàn)。同時,啟科量子也會借著量子領(lǐng)域的東風(fēng),積極探索,勇敢嘗試,努力實現(xiàn)企業(yè)價值,不遺余力地為量子算法以及量子計算領(lǐng)域的發(fā)展添磚加瓦。

注:部分圖片及內(nèi)容來源于網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系刪除。

參考鏈接:

  1. https://blog.csdn.net/qq_42722197/article/details/119583862

  2. https://blog.csdn.net/zaishuiyifangxym/article/details/89840396

  3. https://blog.csdn.net/simonyucsdy/article/details/106529258

  4. https://www.dounaite.com/article/6261531a1ca8a644a40db371.html

  5. Xi-Wei Yao. Quantum Image Processing and Its Application to Edge Detection: Theory and Experiment. Physical Review X 7,031041(2017)

  6. 王敏杰.圖像邊緣檢測技術(shù)綜述[J].中南大學(xué)學(xué)報(自然科學(xué)版).2011.9

  7. 王軍敏.基于多尺度小波變換的圖像邊緣檢測[J].平頂山學(xué)院學(xué)報.2013

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容