1. 程式人生 > >python+OpenCV影象處理(十)霍夫變換簡單圖形檢測

python+OpenCV影象處理(十)霍夫變換簡單圖形檢測

霍夫變換

霍夫變換(Hough Transform)是影象處理中從影象中識別幾何形狀的基本方法之一,應用很廣泛,也有很多改進演算法。主要用來從影象中分離出具有某種相同特徵的幾何形狀(如:直線、圓等)。最基本的霍夫變換是從黑白影象中檢測直線。

霍夫變換是經典的檢測直線的演算法。其最初用來檢測影象中的直線,同時也可以將其擴充套件,以用來檢測影象中的簡單結構。它最初是用於在二值化的影象中進行直線檢測的。對於影象中的一條直線,利用直角座標系,可以用公式表示為:

                                                                                   y=kx+b

如果從k-b引數空間的角度來考慮,則該直線的任意一點(x,y)將變成一個“點”。也就是說,將影象空間中所有的非零畫素轉換到k-b引數空間,那麼它們將聚焦在一個點上,而且引數空間中的一個區域性峰值點就很有可能對應著原影象空間的一條直線。不過,由於直線的斜率可能為無窮大,或者無窮小,那麼在k-b引數空間就不便於對直線進行描述和刻畫。所以,有人提出採用極座標引數空間進行直線檢測。在極座標系中,直線可以表述為以下形式:

                                                                           \rho =xcos(\theta )+ysin(\theta )

上圖(a)所示為原始的影象空間中的一個點(x_{0},y_{0}

) ;(b)中所示為直角座標系當中為過同一點的四條直線;

(c)所示為這四條直線在極座標引數空間可以表示為四個點。

在OpenCV中,支援兩種兩種不同的霍夫直線變換,the Standard Hough Transform(SHT,標準霍夫變換)和Progressive Probability Hough Transform(PPHT,漸進概率式霍夫變換)。

SHT就是上述的在極座標空間進行引數表示的方法,而PPHT是SHT的改進,它是在一定的範圍內進行霍夫變換,從而減少計算量,縮短計算時間。

在OpenCV中檢測直線的函式有cv2.HoughLines()-----(標準霍夫變換),cv2.HoughLinesP()------(漸進概率式霍夫變換)。

(一)標準霍夫變換

函式cv2.HoughLines()返回值實際上是一個二維資料矩陣,表述的就是上述的(\rho ,\theta),其中\rho的單位是畫素長度(即直線到影象原點直線的距離,從上述圖b中可以看出),\theta的單位是弧度,函式有四個引數輸入:

通過調整邊緣檢測運算元Canny閾值引數和標準霍夫變換閾值引數,來獲取較好的檢測效果。

  • 第一個引數,是需要進行檢測的灰度圖
  • 第二、三引數分別是\rho\theta的精確度,可以理解為步長。
  • 第四個引數為閾值T,認為當累加器中的值高於所設定的閾值T時,才認為是一條直線。
# 標準霍夫變換
img = cv2.imread('malu.jpg')
house = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 獲取灰度圖
edges = cv2.Canny(house, 50, 200)
lines = cv2.HoughLines(edges, 1, np.pi/180, 260)  # 霍夫變換返回的就是極座標系中的兩個引數  rho和theta
print(np.shape(lines))
lines = lines[:, 0, :]  # 將資料轉換到二維
for rho, theta in lines:
    a = np.cos(theta)
    b = np.sin(theta)
    # 從圖b中可以看出x0 = rho x cos(theta)
    #               y0 = rho x sin(theta)
    x0 = a*rho
    y0 = b*rho
    # 由引數空間向實際座標點轉換
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*a)
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*a)
    cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 1)
cv2.imshow('img', img)
cv2.imshow('edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

(二)漸進概率式霍夫變換 

函式cv2.HoughLinesP()是一種概率直線檢測,從原理上講hough變換是一個耗時耗力的演算法,尤其是對每一個點的計算,即便經過了canny轉換,但有的時候點的數量依然很龐大,這時候採取一種概率挑選機制,不是所有的點都進行計算,而是隨機的選取一些點來進行計算,這樣的話在閾值設定上也需要降低一些。

與標準霍夫變換函式相比,在引數的輸入上多了兩個引數:minLineLengh(線的最短長度,比這個線段短的都忽略掉)和maxLineGap(兩條直線之間的最大間隔,小於此值,就認為是一條直線)。

這個函式的輸出直接是直線點的座標位置,這樣可以省去一系列for迴圈中的由引數空間到影象的實際座標點的轉換。

# 漸進概率式霍夫變換
img = cv2.imread('house1.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 250)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 30, minLineLength=60, maxLineGap=10)
lines = lines[:, 0, :]
for x1, y1, x2, y2 in lines:
    cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 1)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

再進行邊緣檢測之前如果對影象進行去噪聲操作,影象顯示的效果將會更好。 

(三)利用霍夫變換檢測圓環

圓的數學的數學表示式為:

(x-x_{0})^{2}+(y-y_{0})^{2}=r^{2}

所以一個圓的確定需要三個引數,那麼就需要三層迴圈來實現,從而把影象上的所有點對映到三維空間上。尋找引數空間累加器的最大(或者大於某一閾值)的值。那麼理論上圓的檢測將比直線更耗時,然而OpenCV對其進行了優化,用了霍夫梯度法。

cv2.HoughCircles(image, method, dp, minDist, circles, param1, param2, minRadius, maxRadius)

param1和param2就是\rho\theta的精確度,最後兩個引數是所要檢測的圓的最大最小半徑,不能盲目的檢測,否則浪費時間和空間。輸出就是三個引數空間矩陣。

利用霍夫檢測對印章進行定位:

img = cv2.imread('yinzhang.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('img_yuantu', img)
gaussian = cv2.GaussianBlur(gray, (3, 3), 0)
circles1 = cv2.HoughCircles(gaussian, cv2.HOUGH_GRADIENT, 1, 100, param1=100, param2=30, minRadius=15, maxRadius=80)
print(np.shape(circles1))             # hough_gradient 霍夫梯度法
circles = circles1[0, :, :]
circles = np.uint16(np.around(circles))
for i in circles[:]:
    cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 3)
    cv2.circle(img, (i[0], i[1]), 2, (255, 0, 255), 10)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

相關推薦

python+OpenCV影象處理變換簡單圖形檢測

霍夫變換 霍夫變換(Hough Transform)是影象處理中從影象中識別幾何形狀的基本方法之一,應用很廣泛,也有很多改進演算法。主要用來從影象中分離出具有某種相同特徵的幾何形狀(如:直線、圓等)。最基本的霍夫變換是從黑白影象中檢測直線。 霍夫變換是經典的檢測直線的演算

影象處理——變換

霍夫變換是一種特徵檢測(feature extraction),被廣泛應用在影象分析(image analysis)、電腦視覺(computer vision)以及數位影像處理(digital image processing)。 霍夫變換是用來辨別找出物件中的特徵,例如:線條。

python+OpenCV影象處理車牌定位中對影象的形態學組合操作處理

車牌定位中對影象的形態學組合操作處理 所謂的車牌定位,其中最關鍵的部分就是對圖片的處理,引數的設定,並使之擁有泛化能力。 首先傳入圖片,在進行大規模的圖片處理時,因為無法確定圖片的尺寸,所以需要將原始圖片進行等比例的縮放。 orgimg = cv2.imread('ch

Python+OpenCV影象處理—— 模板匹配

百度百科:模板匹配是一種最原始、最基本的模式識別方法,研究某一特定物件物的圖案位於影象的什麼地方,進而識別物件物,這就是一個匹配問題。它是影象處理中最基本、最常用的匹配方法。模板匹配具有自身的侷限性,主要表現在它只能進行平行移動,若原影象中的匹配目標發生旋轉或大小變化,該演算

python+OpenCV影象處理影象的閾值分割

影象的閾值處理      一幅影象包括目標物體、背景還有噪聲,要想從多值的數字影象中直接提取出目標物體,常用的方法就是設定一個閾值T,用T將影象的資料分成兩部分:大於T的畫素群和小於T的畫素群。這是研究灰度變換的最特殊的方法,稱為影象的二值化(Binarization)。 

python+OpenCV影象處理讀取、複製、顯示、儲存

前 言       從2017年入坑人工智慧領域開始,就被這一領域深深的所吸引,雖然到現在已經踩了不少坑,但總算有了不少的收穫,深感不虛此行,藉助強大的python讓我快速的向著這一領域靠近,現在流行比較廣的人工智慧應用,比如:影象識別,語音識別,文字情感分析,人體行為分析等

python數字影象處理15變換

在圖片處理中,霍夫變換主要是用來檢測圖片中的幾何形狀,包括直線、圓、橢圓等。 在skimage中,霍夫變換是放在tranform模組內,本篇主要講解霍夫線變換。 對於平面中的一條直線,在笛卡爾座標系中,可用y=mx+b來表示,其中m為斜率,b為截距。但是如果直線是一條垂直線,則m為無窮大,所有通常我們

c語言數字影象處理:閾值處理

定義 全域性閾值處理 假設某一副灰度圖有如下的直方圖,該影象由暗色背景下的較亮物體組成,從背景中提取這一物體時,將閾值T作為分割點,分割後的影象g(x, y)由下述公式給出,稱為全域性閾值處理   多閾值處理 本文僅完成全域性閾值處理的演算法實現 基本全域性閾值處理方法

opencv影象處理:濾波器

     濾波器在影象處理中的應用非常廣泛,OpenCV也有個直接使用濾波器掩碼(核)的函式filter2D,將影象與核進行卷積運算得到目標影象。卷積是在每一個影象塊與某個運算元(核)之間進行的運算,而核就是一個固定大小的數值陣列。     &n

opencv影象處理:讀取圖片,裁剪圖片

1.利用opencv讀取圖片: # -*- coding: utf-8 -*- # !/usr/bin/env python # @Time : 2018/11/19 14:59 # @Author : xhh # @Desc : 讀取圖片 # @File : open

python數字影象處理2影象的讀取、顯示與儲存

skimage提供了io模組,顧名思義,這個模組是用來圖片輸入輸出操作的。為了方便練習,也提供一個data模組,裡面嵌套了一些示例圖片,我們可以直接使用。 引入skimage模組可用: 1 from skimage import io

python數字影象處理3影象畫素的訪問與裁剪

圖片讀入程式中後,是以numpy陣列存在的。因此對numpy陣列的一切功能,對圖片也適用。對陣列元素的訪問,實際上就是對圖片畫素點的訪問。 彩色圖片訪問方式為: img[i,j,c] i表示圖片的行數,j表示圖片的列數,c表示圖片的通道數(RGB三通道分別對應0,1

python數字影象處理18:高階形態學處理

形態學處理,除了最基本的膨脹、腐蝕、開/閉運算、黑/白帽處理外,還有一些更高階的運用,如凸包,連通區域標記,刪除小塊區域等。 1、凸包 凸包是指一個凸多邊形,這個凸多邊形將圖片中所有的白色畫素點都包含在內。 函式為: skimage.morphology.conv

Python3+OpenCV3影象處理—— 影象二值化

簡介:影象二值化就是將影象上的畫素點的灰度值設定為0或255,也就是將整個影象呈現出明顯的黑白效果的過程。 一、普通影象二值化 程式碼如下: import cv2 as cv import numpy as np #全域性閾值 def threshold_demo

Python——pygame影象處理

上接: Python——pygame影象處理(一) 4. 一直移到最右邊: import pygame,sys pygame.init() screen = pygame.display.set_mode([640,480]) screen.fill([255

python數字影象處理5影象的繪製

實際上前面我們就已經用到了影象的繪製,如: io.imshow(img)   這一行程式碼的實質是利用matplotlib包對圖片進行繪製,繪製成功後,返回一個matplotlib型別的資料。因此,我們也可以這樣寫: import matplotlib.pyplot as plt plt.imsh

python數字影象處理11影象自動閾值分割

影象閾值分割是一種廣泛應用的分割技術,利用影象中要提取的目標區域與其背景在灰度特性上的差異,把影象看作具有不同灰度級的兩類區域(目標區域和背景區域)的組合,選取一個比較合理的閾值,以確定影象中每個畫素點應該屬於目標區域還是背景區域,從而產生相應的二值影象。 在skimage庫中,閾值分割的功能是放在fi

python數字影象處理6影象的批量處理

有些時候,我們不僅要對一張圖片進行處理,可能還會對一批圖片處理。這時候,我們可以通過迴圈來執行處理,也可以呼叫程式自帶的圖片集合來處理。 圖片集合函式為: skimage.io.ImageCollection(load_pattern,load_func=None) 這個函式是放在io模組內的,帶兩

python PIL 影象處理

第 1 章 基本的影象操作和處理 本章講解操作和處理影象的基礎知識,將通過大量示例介紹處理影象所需的 Python 工具包,並介紹用於讀取影象、影象轉換和縮放、計算導數、畫圖和儲存結果等的基本工具。這些工具的使用將貫穿本書的剩餘章節。 1.1 PIL:Py

使用 matlab 數字影象處理—— 維納濾波復原

逆濾波只能解決只有退化函式,沒有加性噪聲的問題。維納濾波又稱最小均方誤差濾波,綜合考慮了退化函式和噪聲。均方誤差由下式給出: e2=|f(x)−f^(x)|2 假定噪聲與影象是不相關的,復原影象的最佳估計可用下式表示: F^(u,v)=[HH(u,v)|H