概述
? ? ? ? 了解霍夫變換以及該方法如何檢測圖片中的直線,學(xué)習(xí)了解cv2.Canny料祠、cv2.HoughLines改衩、cv2.HoughLinesP。
原理
? ? ? ? 我理解的霍夫變化就是運(yùn)用數(shù)學(xué)知識中關(guān)于極坐標(biāo)與向量的知識表示出所有可以表達(dá)出圖形的公式侍筛。我們最初接觸到的一元一次函數(shù)都是運(yùn)用表達(dá)直線的萤皂,表達(dá)通式為y=k * x + b,這里用(k, b)就可以表示一條直線匣椰。而在極坐標(biāo)中可以表示為r=x * COSθ + y * SINθ裆熙。用(r,θ)兩個(gè)參數(shù)表示一條直線。采用極坐標(biāo)而不采用一元一次函數(shù)是因?yàn)閗值和b值在任意一個(gè)象限里都會(huì)出現(xiàn)負(fù)數(shù)不便于計(jì)算禽笑,而用極坐標(biāo)r值永遠(yuǎn)是大于等于0的數(shù)入录,θ就可以用0~360度表示方便計(jì)算。其中r表示直線到原點(diǎn)的最短距離佳镜,θ表示x軸與原點(diǎn)到直線最短距離的夾角纷跛。在Python語言中,OpenCV的霍夫直線檢測函數(shù)如下:
lines = cv2.HoughLines(image, rho, theta, thresh,?[, lines[, srn[, stn[, min_theta[, max_theta]]]]])
????????* ? ? ?lines是輸出檢測到的直線的向量邀杏,每條直線用(r,θ)表示贫奠。r表示直線到原點(diǎn)(就是圖片的左上角)的距離。θ表示直線的旋轉(zhuǎn)角度望蜡。
????????* ? ? ?image是指輸入的色深8位或者單通道灰度圖片唤崭,否者運(yùn)行時(shí)會(huì)報(bào)錯(cuò)。
????????* ? ? ?rho是指以像素為單位累加器的分辨距離值脖律。
????????* ? ? ?theta是指以用弧度表示的角度谢肾。
????????* ? ? ? thresh是指累加器閾值參數(shù),只有落在直線上的像素點(diǎn)數(shù)大于thresh值才會(huì)返回直線小泉。
????????* ? ? ? ?srn 是對于多個(gè)范圍的霍夫變化芦疏,它是距離分辨率rho的除數(shù)冕杠。估算的距離分辨率是rho,精確的計(jì)算的分辨率是rho/srn酸茴。如果 srn 和 stn 都是0分预,則使用的是經(jīng)典霍夫變化。否則這兩個(gè)參數(shù)必須是正數(shù)薪捍。
????????* ? ? ? ?stn 是對于多范圍的霍夫變化笼痹,他是角度分辨率theta的除數(shù)。
????????* ? ? ? ?min_theta用于經(jīng)典和多范圍霍度變化酪穿,指檢測直線的最小角度凳干,值的范圍是0到max_theta。
????????* ? ? ? ?max_theta用于經(jīng)典和多范圍霍度變化被济,指檢測直線的最大角度救赐,值的范圍是min_theta到pi之間。
? ? ? ? 這個(gè)方法可以檢測到直線只磷,但是得到的是直線经磅,而在現(xiàn)實(shí)應(yīng)用中,需要識別的更多的線段喳瓣。所以我還要學(xué)習(xí)了解一下cv2.HoughLinesP方法。
lines = cv2.HoughLinesP(image赞别,rho畏陕,theta,threshold[, lines[, minLineLength[, maxLineGap]]])
? ? ? ? 這個(gè)方法中前面四個(gè)參數(shù)跟cv2.HoughLines方法中的用法相同仿滔,詳細(xì)記錄一下minLineLength和maxLineGap惠毁。
? ? ? ? * ?lines返回值是以(x1,y1崎页,x2鞠绰,y2)4個(gè)元素的向量為元素的列表。(x1飒焦,y1)和(x2蜈膨,y2)表示一條線段的起點(diǎn)和終點(diǎn)。
? ? ? ? * ?minLineLength指最小的線段長度牺荠,小于該參數(shù)的直線被舍棄掉翁巍,認(rèn)為不合格。
? ? ? ? * ?maxLineGap指同一條線上的最大間斷值休雌。
步驟:
? ? ? ? 1. 讀取圖片后灶壶,先要將圖片轉(zhuǎn)換為灰度圖。
? ? ? ? image = cv2.imread(‘hl.jpg')
? ? ? ? gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
原圖
? ? ? ? ?
????????2. 用cv2.Canny()進(jìn)行邊緣檢測
? ? ? ? ? ? edges = cv2.Canny(gray, 90,110)
? ? ? ? ? ??
邊緣圖
? ? ? ? 3.運(yùn)用霍夫直線識別來識別如片中的直線杈曲。
? ? ? ? ? ? lines = cv2.HoughLines(edges驰凛,1胸懈,np.pi/180,200) ? ?
或者使用cv2.HoughLinesP()方法。
? ? ? ? ? ? lines = cv2.HoughLineP(edges, 1恰响,np.pi/180趣钱,200,20渔隶,10)
? ? ? ? 4.?對檢測到的直線在原圖中標(biāo)記出來羔挡。
? ? ? ? ? 圖5解釋了為什么x1,y1间唉,x2绞灼,y2是下圖中這種寫法〕室埃可以保證檢測到的單條直線畫滿整幅圖低矮。
????????????
????????cv2.HoughLinesP()方法的返回值是(x1,y1被冒,x2军掂,y2),因此畫到原圖中的代碼如下。
???????? for line in lines:
???????????????? x1 = int(round(line[0][0]))
?????????????? y1 = int(round(line[0][1]))
????????????? x2 = int(round(line[0][2]))
???????????? y2 = int(round(line[0][3]))
??????????? cv2.line(img,(x1,y1),(x2,y2),(255,0,0),2)
????????cv2.imshow('HoughLinesP',img)
????????cv2.waitKey(0)
總結(jié)
? ? ? ? ? ? 霍夫變換檢測直線方法只有將參數(shù)設(shè)置合適蝗锥,才有可能達(dá)到想要的效果,還是有一定的不足率触,使用時(shí)還是根據(jù)具體情況來選擇應(yīng)用终议。
????????????