openCV霍夫變換原理及其實現

一 霍夫變換原理

注意: 進行霍夫變換的前提是首先完成了邊緣檢測任務

1. 霍夫變換概述

霍夫變換是一種特徵檢測(feature extraction),被廣泛應用在圖像分析(image analysis)、計算機視覺(computer vision)以及數位影像處理(digital image processing)。霍夫變換是用來辨別找出物件中的特徵.如直線 圓等物體特徵:
先直觀的看看它的作用:
檢測直線:
在這裏插入圖片描述
檢測圓:
在這裏插入圖片描述

2. 霍夫變換原理

極座標系和直角座標系之間什麼關係:
1.在直角座標系下,點P的座標表示爲(x, y)
在這裏插入圖片描述

2.在極座標系下,點的座標表示爲(p,θ)(p,\theta)
在這裏插入圖片描述
某一點由極座標轉換爲直角座標:
y=γsin(θ)y = \gamma * \sin(\theta)
x=γcos(θ)x = \gamma * \cos(\theta)

在這裏插入圖片描述所以由圖可得:

p=γcos(θβ)p = \gamma * \cos(\theta - \beta)
所以:
p=γcos(θ)cos(β)+γsin(θ)sin(β) p = \gamma*cos(\theta)*cos(\beta)+\gamma*sin(\theta)*sin(\beta)
=γcos(β)cos(θ)+γsin(β)sin(θ) = \gamma*cos(\beta)*cos(\theta)+\gamma*sin(\beta)*sin(\theta)
由極座標與直角座標之間的關係可得:
y=γsin(β)y = \gamma * \sin(\beta)
x=γcos(β)x = \gamma * \cos(\beta)

得到極座標方程:
p=xcos(θ)+ysin(θ)p = x*cos(\theta)+y*sin(\theta)

所以這樣將笛卡爾座標系下函數轉變成了關於參數(p,θ)(p,\theta)的函數空間,也叫極座標系。可以直觀的看到,只需要知道一點就可以在笛卡爾座標中確定一條直線。
在平面座標空間中過一點有無數條直線,那麼平面座標空間中的每一條直線到霍夫空間中都對應一點。

3. 霍夫檢測原理

在笛卡爾座標系中,過這兩點的直線都有不同的(p,θ)(p,\theta),那麼將這些點反應在極座標系中如圖2所示:

圖1 圖1
圖2

在這裏插入圖片描述那麼圖2中的交點(p,θ)(p,\theta)表示,在笛卡爾座標系中有一條直線同時經過了兩點。那麼這條直線爲:將點帶入極座標可得到直線:
由:
p=xcos(θ)+ysin(θ)p = x*cos(\theta)+y*sin(\theta)

可得:
y=xcos(θ)/sin(θ)+p/sin(θ)y = x*cos(\theta) / sin(\theta)+ p / sin(\theta)
所以這樣就找到了直線y=kx+b y = k * x +b

具體可以參考這篇博客:https://blog.csdn.net/shenziheng1/article/details/75307410

二 霍夫變換實現

在這裏插入圖片描述

# coding: utf-8

import numpy as np
import matplotlib.pyplot as plt

from skimage.transform import hough_line
from skimage.draw import line

img = np.zeros((100, 150), dtype=bool)
img[30, :] = 1
img[:, 65] = 1
img[35:45, 35:50] = 1

rr, cc = line(60, 130, 80, 10)
img[rr, cc] = 1
img += np.random.random(img.shape) > 0.95

out, angles, d = hough_line(img)

fix, axes = plt.subplots(1, 2, figsize=(7, 4))

axes[0].imshow(img, cmap=plt.cm.gray)
axes[0].set_title('Input image')

axes[1].imshow(
    out, cmap=plt.cm.bone,
    extent=(np.rad2deg(angles[-1]), np.rad2deg(angles[0]), d[-1], d[0]))
axes[1].set_title('Hough transform')
axes[1].set_xlabel('Angle (degree)')
axes[1].set_ylabel('Distance (pixel)')

plt.tight_layout()
plt.show()

三 霍夫變換應用

1. 直線檢測

在這裏插入圖片描述

import cv2
import numpy as np

image = cv2.imread("27.jpg")
cv2.imshow("image_original", image)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

edges = cv2.Canny(image_gray, 100, 150)

lines = cv2.HoughLines(edges, 1, np.pi / 180, 100)

for line in lines:
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.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(image, (x1, y1), (x2, y2), (0, 0, 255), 2)

cv2.imshow("image_lines", image)
cv2.imwrite("6.jpg",image)
cv2.waitKey(0)

2. 圓檢測

在這裏插入圖片描述

import cv2
import numpy as np
image = cv2.imread("29.jpg")
cv2.imshow("image_original", image)
dst = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)
circle = cv2.HoughCircles(dst, cv2.HOUGH_GRADIENT, 1, 80, param1=40, param2=20, minRadius=20, maxRadius=300)
if not circle is None:
    circle = np.uint16(np.around(circle))
    for i in circle[0, :]:
        cv2.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2)
cv2.imshow("circle", image)
cv2.waitKey(0)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章