[OpenCV應用][Python]霍夫直線轉換偵測應用於旋轉補正

更新於 發佈於 閱讀時間約 8 分鐘

廢話不多說,先上成果圖。

成果圖

算出旋轉角度後轉正

算出旋轉角度後轉正


主要實現方法

1.灰階後利用cv2.Canny找物體的邊緣

2.找物件相對應的直線cv2.HoughLines

3.分類為橫向和垂直的直線角度,求得相對於物件的旋轉角度

4.根據算出的相對應旋轉角度將物件轉正


霍夫直線變換語法

cv2.HoughLines:

  • 用途:用於檢測圖像中的直線。
  • 返回值:返回檢測到的直線的極座標表示(rho, theta)。
  • 用法:
lines = cv2.HoughLines(image, rho, theta, threshold)
  • image: 二值化圖像,通常是由邊緣檢測算法(如Canny)生成的。
  • rho: 霍夫空間中極座標中的像素距離解析度。
  • theta: 霍夫空間中極座標中的角度解析度,常輸入np.pi / 180,代表所有角度都偵測
  • threshold: 閾值,線條檢測的閾值,長度需超過多少才算有效線條,單位為像素。
    假設門檻設為90,表示值線長度須超過90個像素。

直線的極座標表示 (rho, theta),其中 rho從原點到直線的距離,而 theta直線的角度theta 的範圍通常被設置為 [0, 180] 度,這是因為直線的表示是對稱的,也就是說,同一條直線的兩個方向都被考慮到,角度的範圍因此被限制在 [0, 180] 度

程式範例

import cv2
import numpy as np

#旋轉圖片用
def rotate_image(image, angle):
# 取得影像中心點坐標
center = tuple(np.array(image.shape[1::-1]) / 2)
# 設定旋轉矩陣
rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
# 進行影像旋轉
rotated_image = cv2.warpAffine(image, rotation_matrix, image.shape[1::-1], flags=cv2.INTER_LINEAR)
return rotated_image

#算出旋轉角度並轉正
def calculate_rotation_angle(image_path):

# 讀取圖片
image = cv2.imread(image_path)
height, width = image.shape[:2]

# 將圖片轉換為灰度
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 使用霍夫直線變換檢測直線
edges = cv2.Canny(gray, 100, 250, apertureSize=3)
lines = cv2.HoughLines(edges, 1, np.pi / 180, threshold=120)

#存圖分析用
edges_img = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
image_view = image.copy()

# 計算直線的平均角度
angles_horizontal = []
angles_vertical = []

for i , line in enumerate(lines):
print(f'line :{line}')
rho, theta = line[0]
angle = theta * 180 / np.pi

# 分類橫向和垂直直線
if 50 <= angle <= 130: # 橫向直線
angles_horizontal.append(angle)
elif 150 <= angle <= 190: # 垂直直線
angles_vertical.append(angle)
elif 0 <= angle <= 30: # 垂直直線
angle += 180
angles_vertical.append(angle)
print(angle)

line_length = max(height, width) # 畫出檢測到的直線
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + line_length * (-b))
y1 = int(y0 + line_length * (a))
x2 = int(x0 - line_length * (-b))
y2 = int(y0 - line_length * (a))
cv2.line(image_view, (x1, y1), (x2, y2), (0, 0, 255), 1)

#平均計算橫向與垂直直線
if angles_horizontal:
average_angle_horizontal = np.mean(angles_horizontal)
else:#假設沒偵測到指定數值
average_angle_horizontal = 90
if angles_vertical:
average_angle_vertical = np.mean(angles_vertical)
else:#假設沒偵測到指定數值
average_angle_vertical = 180

# 顯示包含檢測到的直線的圖片
cv2.imshow('Detected_Lines', image_view)
cv2.waitKey(0)
cv2.destroyAllWindows()
print(f"橫向直線的平均角度:{average_angle_horizontal} 度")
print(f"垂直直線的平均角度:{average_angle_vertical} 度")

# 算出相對應旋轉角度
angle_horizontal = 90 - average_angle_horizontal
angle_vertical = 180 - average_angle_vertical

# 計算平均角度
average_angle = np.mean([angle_horizontal, angle_vertical])
print(f'旋轉角度 : {average_angle}')

# 轉正
rotate = rotate_image(image, -average_angle)

# 顯示包含檢測到的直線的圖片
cv2.imshow('result Image', rotate)
cv2.waitKey(0)
cv2.destroyAllWindows()


# 替換成你的圖片路徑
image_path = 'D:/CRABpy/Rotation/test2.png'
calculate_rotation_angle(image_path)

霍夫直線角度分析

一條直線的兩個方向都被考慮到,就容易混淆到底算出來的直線角度是哪個方向。

以下利用不同旋轉角度的物體,來記錄不同的直線角度。

raw-image
raw-image
raw-image

霍夫偵測角度表

最後根據上面三個圖得到以下角度表,根據這角度表在來設定分類橫向垂直直線角度

角度表

右半邊為0至90

但我實際在測試時有跑出過183度,雖然文件寫說偵測的出的直線角度範圍為[0,180]

左半邊為180至90

raw-image

以上為我實際應用的心得總結,不保證說明的內容完全正確,但實際上可以應用物體轉正,若有錯誤在留言讓我知道,謝謝:)












avatar-img
136會員
229內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。
留言
avatar-img
留言分享你的想法!
螃蟹_crab的沙龍 的其他內容
涉及圖像處理和計算機視覺時,色彩空間轉換是一個常見操作,應用如下: 降維: 將一張彩色圖像轉換為灰度圖像可以減少數據的維度,簡化處理過程,同時在某些情況下保留重要的視覺信息。 突顯特徵: 在某些情況下,某些色彩通道可能包含冗餘或不必要的信息,通過轉換到其他色彩空間,可以更好地突顯圖像中的重要特徵
warpAffine 和 warpPerspective 都是 OpenCV 中用於圖像變換的函數,主要差異在於這兩種函數所使用的變換矩陣的類型和適用場景。 本文主要討論warpAffine,另外warpPerspective可以此篇文章
當我們在拍照時,有時候會期望圖像中物體是呈現我們想要的樣子,就可以利用透視變換的方式,將物體捏造成我們想要的樣子。 當我們拍攝文件或書籍時,如果有角度和距離的變化,文件可能會變形。透視變換可用於校正這種變形,使文件呈現平整的視覺效果。 cv2.warpPerspective
OpenCV 提供了多種用於邊緣偵測的方法,其中一些常見的包括 Sobel、Scharr、Laplacian,還有 Canny 邊緣檢測器。這些方法可以幫助我們檢測圖像中的暗明強度變化,從而找到物體的邊緣。
在生活中常看到的美圖秀秀或美圖修修或者其他圖像編輯軟體,通常使用各種濾波器和模糊化技術來實現照片的修飾和美化效果。這些濾波和模糊化技術可以應用於不同的區域,以改進照片的外觀,包括平滑皮膚、去除細節、調整對比度等。 本文會介紹 OpenCV 四種影像模糊化的方法
在影像處理中,我們總是會想把圖像內一些物件的特徵讓它明顯一點,形態學運算就是一個好用強大的工具。 形態學運算是圖像處理中的一個重要概念,用於改善或改變圖像的形狀。在OpenCV中,形態學運算提供了一系列操作,包括開運算、閉運算、禮帽運算和黑帽運算。這些操作通常應用於二值圖像,用於去除噪聲、連接物體
涉及圖像處理和計算機視覺時,色彩空間轉換是一個常見操作,應用如下: 降維: 將一張彩色圖像轉換為灰度圖像可以減少數據的維度,簡化處理過程,同時在某些情況下保留重要的視覺信息。 突顯特徵: 在某些情況下,某些色彩通道可能包含冗餘或不必要的信息,通過轉換到其他色彩空間,可以更好地突顯圖像中的重要特徵
warpAffine 和 warpPerspective 都是 OpenCV 中用於圖像變換的函數,主要差異在於這兩種函數所使用的變換矩陣的類型和適用場景。 本文主要討論warpAffine,另外warpPerspective可以此篇文章
當我們在拍照時,有時候會期望圖像中物體是呈現我們想要的樣子,就可以利用透視變換的方式,將物體捏造成我們想要的樣子。 當我們拍攝文件或書籍時,如果有角度和距離的變化,文件可能會變形。透視變換可用於校正這種變形,使文件呈現平整的視覺效果。 cv2.warpPerspective
OpenCV 提供了多種用於邊緣偵測的方法,其中一些常見的包括 Sobel、Scharr、Laplacian,還有 Canny 邊緣檢測器。這些方法可以幫助我們檢測圖像中的暗明強度變化,從而找到物體的邊緣。
在生活中常看到的美圖秀秀或美圖修修或者其他圖像編輯軟體,通常使用各種濾波器和模糊化技術來實現照片的修飾和美化效果。這些濾波和模糊化技術可以應用於不同的區域,以改進照片的外觀,包括平滑皮膚、去除細節、調整對比度等。 本文會介紹 OpenCV 四種影像模糊化的方法
在影像處理中,我們總是會想把圖像內一些物件的特徵讓它明顯一點,形態學運算就是一個好用強大的工具。 形態學運算是圖像處理中的一個重要概念,用於改善或改變圖像的形狀。在OpenCV中,形態學運算提供了一系列操作,包括開運算、閉運算、禮帽運算和黑帽運算。這些操作通常應用於二值圖像,用於去除噪聲、連接物體
你可能也想看
Google News 追蹤
Thumbnail
該來的終究還是來了 度過焦躁不安的一整周,學徒老人家我的不安感等比級數的襲來,自3/19寫了第一篇關於<巴克萊銀行:倉促撤退>的報告,看到市場上的機構法人有如大洪水、地震來臨前夕開始竄逃撤退。 海湖莊園協議 接著,在3/31與4/2兩天接著寫了川普與他的財經團隊在海湖莊園豪
Thumbnail
空單爆天量、技術指標超賣、情緒恐慌到極致:美股嘎空行情有機會啟動嗎? 重點摘要: 技術面極度超賣,反彈條件醞釀中,但尚未明確止穩 SPY 與 QQQ 的重要指標,如MACD、KDJ、RSI等指標進入極端超賣區,但尚未出現底部鈍化或明確反轉訊號,技術面仍屬空方主導。 連續出現跳空缺口,空方動
Thumbnail
全新 vocus 挑戰活動「方格人氣王」來啦~四大挑戰任你選,留言 / 愛心 / 瀏覽數大 PK,還有新手專屬挑戰!無論你是 vocus 上活躍創作者或剛加入的新手,都有機會被更多人看見,獲得站上版位曝光&豐富獎勵!🏆
Thumbnail
使用 LBP(Local Binary Patterns) 進行紋理分析和瑕疵檢測 Local Binary Patterns(LBP) 是一種用來描述圖像紋理的特徵提取技術。LBP 對於檢測表面紋理的異常具有很好的效果,尤其在檢測紋理一致的材料表面(例如紡織品、紙張、金屬)時,LBP 非常有用。
Thumbnail
接續上一邊,分割了螺絲與螺母的圖像,但分割後的結果,因為螺絲過於接近的關係,沒有切割乾淨,會有其他螺絲的頭或者身體,這樣會影響到後續量測。 [OpenCV應用][Python]擷取出螺絲或螺母的影像 本文主要是,如何去除掉不要的背景雜物。 下層為原先分割的圖,上層為去除背景雜物的圖。
Thumbnail
此篇為上一篇文章的延伸,先辦別是螺絲還是螺母才擷取出影像。 [OpenCV應用][Python]利用findContours辨識螺絲還是螺母 因為可能會需要另外處理螺絲與螺母才可以準確地去做量測,所以第一步就是先分割出這兩種的圖像。
Thumbnail
先上成果圖,如果是螺母的話就標註 is circle來區分。 簡單的用圖表加文字說明AOI辨識 在此文章的範例中: 影像前處理:色彩空間轉換(灰階) -> 二值化閥值處理 演算法:尋找輪廓 數值判斷:長,寬,面積,周長 圖片來源 程式碼 import cv2 import nu
Thumbnail
[OpenCV應用][Python]找出圖像中的四個方位的邊緣點求出寬高 呈上篇應用Numpy找到的座標點,那我們如何捨棄掉差異過大的座標點呢? 可能圖像物件邊緣不佳,採樣就會差異過大,造成計算出的寬高是不準確的。 遇到這種狀況,就可以使用下方的程式範例來篩選座標點。 為求方便,此範例跟圖
Thumbnail
該來的終究還是來了 度過焦躁不安的一整周,學徒老人家我的不安感等比級數的襲來,自3/19寫了第一篇關於<巴克萊銀行:倉促撤退>的報告,看到市場上的機構法人有如大洪水、地震來臨前夕開始竄逃撤退。 海湖莊園協議 接著,在3/31與4/2兩天接著寫了川普與他的財經團隊在海湖莊園豪
Thumbnail
空單爆天量、技術指標超賣、情緒恐慌到極致:美股嘎空行情有機會啟動嗎? 重點摘要: 技術面極度超賣,反彈條件醞釀中,但尚未明確止穩 SPY 與 QQQ 的重要指標,如MACD、KDJ、RSI等指標進入極端超賣區,但尚未出現底部鈍化或明確反轉訊號,技術面仍屬空方主導。 連續出現跳空缺口,空方動
Thumbnail
全新 vocus 挑戰活動「方格人氣王」來啦~四大挑戰任你選,留言 / 愛心 / 瀏覽數大 PK,還有新手專屬挑戰!無論你是 vocus 上活躍創作者或剛加入的新手,都有機會被更多人看見,獲得站上版位曝光&豐富獎勵!🏆
Thumbnail
使用 LBP(Local Binary Patterns) 進行紋理分析和瑕疵檢測 Local Binary Patterns(LBP) 是一種用來描述圖像紋理的特徵提取技術。LBP 對於檢測表面紋理的異常具有很好的效果,尤其在檢測紋理一致的材料表面(例如紡織品、紙張、金屬)時,LBP 非常有用。
Thumbnail
接續上一邊,分割了螺絲與螺母的圖像,但分割後的結果,因為螺絲過於接近的關係,沒有切割乾淨,會有其他螺絲的頭或者身體,這樣會影響到後續量測。 [OpenCV應用][Python]擷取出螺絲或螺母的影像 本文主要是,如何去除掉不要的背景雜物。 下層為原先分割的圖,上層為去除背景雜物的圖。
Thumbnail
此篇為上一篇文章的延伸,先辦別是螺絲還是螺母才擷取出影像。 [OpenCV應用][Python]利用findContours辨識螺絲還是螺母 因為可能會需要另外處理螺絲與螺母才可以準確地去做量測,所以第一步就是先分割出這兩種的圖像。
Thumbnail
先上成果圖,如果是螺母的話就標註 is circle來區分。 簡單的用圖表加文字說明AOI辨識 在此文章的範例中: 影像前處理:色彩空間轉換(灰階) -> 二值化閥值處理 演算法:尋找輪廓 數值判斷:長,寬,面積,周長 圖片來源 程式碼 import cv2 import nu
Thumbnail
[OpenCV應用][Python]找出圖像中的四個方位的邊緣點求出寬高 呈上篇應用Numpy找到的座標點,那我們如何捨棄掉差異過大的座標點呢? 可能圖像物件邊緣不佳,採樣就會差異過大,造成計算出的寬高是不準確的。 遇到這種狀況,就可以使用下方的程式範例來篩選座標點。 為求方便,此範例跟圖