[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
留言分享你的想法!
avatar-img
螃蟹_crab的沙龍
148會員
255內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。
螃蟹_crab的沙龍的其他內容
2025/04/01
1. 概述 在光學字符識別(OCR)過程中,常見的問題之一是「斷字」,即原本應為一個完整字符的部分被錯誤地分割成兩個或多個獨立的字符。這通常發生在掃描文件、圖像降噪或影像二值化處理後。本篇文章將介紹一種基於 骨架化端點距離分析 的斷字檢測方法,並提供完整的 Python 實作。 2. 斷字檢測的
Thumbnail
2025/04/01
1. 概述 在光學字符識別(OCR)過程中,常見的問題之一是「斷字」,即原本應為一個完整字符的部分被錯誤地分割成兩個或多個獨立的字符。這通常發生在掃描文件、圖像降噪或影像二值化處理後。本篇文章將介紹一種基於 骨架化端點距離分析 的斷字檢測方法,並提供完整的 Python 實作。 2. 斷字檢測的
Thumbnail
2025/03/24
在影像處理或機器學習的應用中,我們常常需要將影片逐幀擷取出來,進一步進行辨識或分析。 本篇教學將示範如何使用 Python + OpenCV 來: ✅ 讀取 MP4 影片 測試影片可由下方超連結下載,從file-examples.com下載 file-examples.com 是一個 免費提
Thumbnail
2025/03/24
在影像處理或機器學習的應用中,我們常常需要將影片逐幀擷取出來,進一步進行辨識或分析。 本篇教學將示範如何使用 Python + OpenCV 來: ✅ 讀取 MP4 影片 測試影片可由下方超連結下載,從file-examples.com下載 file-examples.com 是一個 免費提
Thumbnail
2025/03/13
本教學將介紹如何使用 OpenCV 來檢測螺絲的鎖附間距,並提供完整的 Python 程式碼來實作這項功能。 🔹 1. 設計目標 使用二值化處理與形態學運算來強化影像 計算螺絲之間的間距 視覺化結果,標記最大間距並顯示數值 🔹 2. 測試用螺絲影像 🔹 3.
Thumbnail
2025/03/13
本教學將介紹如何使用 OpenCV 來檢測螺絲的鎖附間距,並提供完整的 Python 程式碼來實作這項功能。 🔹 1. 設計目標 使用二值化處理與形態學運算來強化影像 計算螺絲之間的間距 視覺化結果,標記最大間距並顯示數值 🔹 2. 測試用螺絲影像 🔹 3.
Thumbnail
看更多
你可能也想看
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
本文將說明如何去辨識出圖片文字​位置及高寬。
Thumbnail
本文將說明如何去辨識出圖片文字​位置及高寬。
Thumbnail
先上成果圖,如果是螺母的話就標註 is circle來區分。 簡單的用圖表加文字說明AOI辨識 在此文章的範例中: 影像前處理:色彩空間轉換(灰階) -> 二值化閥值處理 演算法:尋找輪廓 數值判斷:長,寬,面積,周長 圖片來源 程式碼 import cv2 import nu
Thumbnail
先上成果圖,如果是螺母的話就標註 is circle來區分。 簡單的用圖表加文字說明AOI辨識 在此文章的範例中: 影像前處理:色彩空間轉換(灰階) -> 二值化閥值處理 演算法:尋找輪廓 數值判斷:長,寬,面積,周長 圖片來源 程式碼 import cv2 import nu
Thumbnail
首先我們先用小畫家,創建一個簡單的十字箭頭圖,在用高斯模糊將圖用模糊來模擬圖片糊掉的狀況。 如何檢測呢? 先假設在圖像清晰的狀況下,取邊緣的話線條應該是很明顯的吧,模糊的情況下,邊緣線條應該就會變多? 看下圖,由左看到右,在圖片清晰的狀況下,線條是相當明顯的 那有什麼方法將其量化成數字?
Thumbnail
首先我們先用小畫家,創建一個簡單的十字箭頭圖,在用高斯模糊將圖用模糊來模擬圖片糊掉的狀況。 如何檢測呢? 先假設在圖像清晰的狀況下,取邊緣的話線條應該是很明顯的吧,模糊的情況下,邊緣線條應該就會變多? 看下圖,由左看到右,在圖片清晰的狀況下,線條是相當明顯的 那有什麼方法將其量化成數字?
Thumbnail
觀看本文將可以學習到如何利用Numpy求得物件的邊緣點,及算出物件的寬跟高。 有詳細的程式邏輯說明,及各函式用法說明。 綠點及紅點則是採樣到的邊界點,比較粗的點是偵測到的最大值 完整程式碼 import cv2 import numpy as np import matplotl
Thumbnail
觀看本文將可以學習到如何利用Numpy求得物件的邊緣點,及算出物件的寬跟高。 有詳細的程式邏輯說明,及各函式用法說明。 綠點及紅點則是採樣到的邊界點,比較粗的點是偵測到的最大值 完整程式碼 import cv2 import numpy as np import matplotl
Thumbnail
直方圖是對圖像中像素強度分布的圖形表示。通過分析直方圖,我們可以獲得有關圖像對比度、亮度和色彩分佈的有用信息。
Thumbnail
直方圖是對圖像中像素強度分布的圖形表示。通過分析直方圖,我們可以獲得有關圖像對比度、亮度和色彩分佈的有用信息。
Thumbnail
廢話不多說,先上成果圖。 成果圖 主要實現方法 1.灰階後利用cv2.Canny找物體的邊緣 2.找物件相對應的直線cv2.HoughLines 3.分類為橫向和垂直的直線角度,求得相對於物件的旋轉角度 4.根據算出的相對應旋轉角度將物件轉正
Thumbnail
廢話不多說,先上成果圖。 成果圖 主要實現方法 1.灰階後利用cv2.Canny找物體的邊緣 2.找物件相對應的直線cv2.HoughLines 3.分類為橫向和垂直的直線角度,求得相對於物件的旋轉角度 4.根據算出的相對應旋轉角度將物件轉正
Thumbnail
本文介紹OpenCV中的SimpleBlobDetector用於檢測斑點或圓,以及其與霍夫轉換找圓方法的差異。透過程式範例和解析,講解檢測到的關鍵點和設定參數,並整理SimpleBlobDetector與霍夫轉換的不同。最後,探討不同的應用場景和參數調整。
Thumbnail
本文介紹OpenCV中的SimpleBlobDetector用於檢測斑點或圓,以及其與霍夫轉換找圓方法的差異。透過程式範例和解析,講解檢測到的關鍵點和設定參數,並整理SimpleBlobDetector與霍夫轉換的不同。最後,探討不同的應用場景和參數調整。
Thumbnail
本文將利用OpenCV的findContours函式,從找到的輪廓中來計算物件的面積,周長,邊界框等屬性,從而得到物體的寬度與高度。 一般來說,我們在進行輪廓檢測時,會先進行圖像二值化,將對象轉換為白色,背景為黑色。這樣,在找到輪廓後,輪廓的點就會以白色表示,背景為黑色。 結果圖 從圖中綠色框
Thumbnail
本文將利用OpenCV的findContours函式,從找到的輪廓中來計算物件的面積,周長,邊界框等屬性,從而得到物體的寬度與高度。 一般來說,我們在進行輪廓檢測時,會先進行圖像二值化,將對象轉換為白色,背景為黑色。這樣,在找到輪廓後,輪廓的點就會以白色表示,背景為黑色。 結果圖 從圖中綠色框
Thumbnail
利用OPENCV,實現SIFT應用,尋找圖片中物件的旋轉角度 本文介紹主要提出SIFT提取關鍵角點的座標,由此算出物件的旋轉角度 程式功能介紹 : 導入待檢測圖及樣本圖,則會依照樣本圖中的物件為基準
Thumbnail
利用OPENCV,實現SIFT應用,尋找圖片中物件的旋轉角度 本文介紹主要提出SIFT提取關鍵角點的座標,由此算出物件的旋轉角度 程式功能介紹 : 導入待檢測圖及樣本圖,則會依照樣本圖中的物件為基準
Thumbnail
[影像處理_OpenCV Python]使用Python撰寫影像處理功能,圖片遮罩或濾除掉不要的地方,旋轉圖片 以下範例將呈現影像處理三種不同的應用: 遮罩的實現 濾除 旋轉
Thumbnail
[影像處理_OpenCV Python]使用Python撰寫影像處理功能,圖片遮罩或濾除掉不要的地方,旋轉圖片 以下範例將呈現影像處理三種不同的應用: 遮罩的實現 濾除 旋轉
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News