OpenCV圖像旋轉:單點旋轉與圖片旋轉

1. 引言

圖像旋轉是計算機視覺中最基礎也是最重要的幾何變換之一,在圖像處理、計算機視覺、醫學影像分析等領域有著廣泛應用。OpenCV作為最流行的計算機視覺庫,提供了強大的圖像旋轉功能。本文將深入探討OpenCV中的兩種旋轉方式:基于單點的仿射變換旋轉和直接圖片旋轉,并通過代碼示例展示如何實現這些功能。

2. 圖像旋轉的基本概念

圖像旋轉是指將圖像圍繞某個點(通常是中心點)旋轉一定角度的幾何變換。在數學上,旋轉屬于剛體變換,可以保持圖像中物體的形狀和大小不變。

旋轉的主要參數包括:

  • 旋轉中心點

  • 旋轉角度(順時針或逆時針)

  • 旋轉后的縮放比例

  • 旋轉后圖像的邊界處理

3. 單點旋轉與仿射變換矩陣

3.1 仿射變換基礎

仿射變換是一種二維線性變換,可以表示為:

其中(x,y)是原坐標,(x',y')是變換后坐標。

在OpenCV中,我們使用2×3的矩陣來表示仿射變換:

?

3.2 獲取旋轉的仿射變換矩陣

OpenCV提供了cv2.getRotationMatrix2D函數來計算旋轉矩陣:

import cv2
import numpy as np# 定義旋轉中心和角度
center = (width/2, height/2)  # 通常以圖像中心為旋轉點
angle = 45  # 旋轉角度
scale = 1.0  # 縮放比例# 獲取旋轉矩陣
rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale)

3.3 應用仿射變換進行旋轉

得到旋轉矩陣后,可以使用cv2.warpAffine函數應用變換:

# 讀取圖像
image = cv2.imread('input.jpg')# 獲取圖像尺寸
height, width = image.shape[:2]# 應用旋轉
rotated_image = cv2.warpAffine(image, rotation_matrix, (width, height))# 顯示結果
cv2.imshow('Rotated Image', rotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. 直接圖片旋轉

除了使用仿射變換,OpenCV還提供了更直接的旋轉方式:

4.1 使用transpose和flip實現90度倍數的旋轉

對于90°、180°、270°的旋轉,可以使用更高效的操作:

# 順時針旋轉90度
rotated_90 = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)# 逆時針旋轉90度
rotated_90_counter = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)# 旋轉180度
rotated_180 = cv2.rotate(image, cv2.ROTATE_180)

4.2 任意角度旋轉的完整實現

對于任意角度的旋轉,我們需要考慮旋轉后圖像可能超出原圖邊界的問題:

def rotate_image(image, angle):# 獲取圖像尺寸(h, w) = image.shape[:2]# 計算旋轉中心center = (w // 2, h // 2)# 獲取旋轉矩陣M = cv2.getRotationMatrix2D(center, angle, 1.0)# 計算旋轉后圖像的邊界cos = np.abs(M[0, 0])sin = np.abs(M[0, 1])new_w = int((h * sin) + (w * cos))new_h = int((h * cos) + (w * sin))# 調整旋轉矩陣以考慮平移M[0, 2] += (new_w / 2) - center[0]M[1, 2] += (new_h / 2) - center[1]# 執行旋轉rotated = cv2.warpAffine(image, M, (new_w, new_h), borderMode=cv2.BORDER_CONSTANT, borderValue=(255, 255, 255))return rotated

5. 旋轉中的邊界處理

旋轉圖像時,邊角的處理非常重要。OpenCV提供了多種邊界處理方式:

# 不同邊界填充方式
rotated_replicate = cv2.warpAffine(image, M, (w, h), borderMode=cv2.BORDER_REPLICATE)
rotated_reflect = cv2.warpAffine(image, M, (w, h), borderMode=cv2.BORDER_REFLECT)
rotated_wrap = cv2.warpAffine(image, M, (w, h), borderMode=cv2.BORDER_WRAP)

6. 基于兩點的旋轉(擴展內容)

有時我們需要根據圖像中的兩個特征點來旋轉圖像,使兩點連線達到特定角度:

def rotate_by_two_points(image, pt1, pt2, desired_angle=0):# 計算兩點之間的角度dx = pt2[0] - pt1[0]dy = pt2[1] - pt1[1]current_angle = np.degrees(np.arctan2(dy, dx))# 計算需要旋轉的角度rotation_angle = desired_angle - current_angle# 計算旋轉中心(兩點中點)center = ((pt1[0] + pt2[0]) / 2, (pt1[1] + pt2[1]) / 2)# 獲取旋轉矩陣M = cv2.getRotationMatrix2D(center, rotation_angle, 1.0)# 執行旋轉rotated = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))return rotated

7. 性能優化與注意事項

  1. 批量旋轉優化:如果需要旋轉多張圖片,可以預先計算旋轉矩陣并復用

  2. 插值方法選擇warpAffine中的flags參數可以指定插值方法,影響旋轉質量

    • cv2.INTER_NEAREST:最近鄰插值,速度快但質量低

    • cv2.INTER_LINEAR:雙線性插值(默認)

    • cv2.INTER_CUBIC:雙三次插值,質量更好但速度慢

  3. 內存考慮:大角度旋轉會產生更大的圖像,注意內存消耗

8. 實際應用案例

8.1 文檔校正

def correct_document_skew(image):# 轉換為灰度圖gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 邊緣檢測edges = cv2.Canny(gray, 50, 150, apertureSize=3)# 霍夫線變換檢測直線lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=100, maxLineGap=10)# 計算平均角度angles = []for line in lines:x1, y1, x2, y2 = line[0]angle = np.degrees(np.arctan2(y2-y1, x2-x1))angles.append(angle)median_angle = np.median(angles)# 旋轉圖像校正(h, w) = image.shape[:2]center = (w // 2, h // 2)M = cv2.getRotationMatrix2D(center, median_angle, 1.0)corrected = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC,borderMode=cv2.BORDER_REPLICATE)return corrected

8.2 圖像數據增強

在深度學習中,圖像旋轉是常用的數據增強手段:

def augment_data(image):# 隨機旋轉角度 (-15到15度之間)angle = np.random.uniform(-15, 15)# 隨機縮放 (0.8到1.2之間)scale = np.random.uniform(0.8, 1.2)# 獲取旋轉矩陣h, w = image.shape[:2]center = (w/2, h/2)M = cv2.getRotationMatrix2D(center, angle, scale)# 應用變換augmented = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_LINEAR,borderMode=cv2.BORDER_REFLECT)return augmented

9. 總結

本文詳細介紹了OpenCV中實現圖像旋轉的兩種主要方法:基于單點的仿射變換旋轉和直接圖片旋轉。關鍵點包括:

  1. 使用cv2.getRotationMatrix2D獲取旋轉矩陣

  2. 使用cv2.warpAffine應用仿射變換

  3. 處理旋轉后的邊界問題

  4. 基于兩點旋轉的特殊情況處理

  5. 實際應用中的性能優化技巧

掌握這些技術后,讀者可以靈活地在各種計算機視覺應用中實現圖像旋轉功能。根據具體需求選擇合適的方法,并注意旋轉對圖像質量的影響,就能獲得最佳的旋轉效果。

10. 參考文獻

  1. OpenCV官方文檔

  2. 《學習OpenCV》計算機視覺編程經典書籍

  3. 《數字圖像處理》岡薩雷斯著

希望這篇文章能幫助你全面理解OpenCV中的圖像旋轉技術!如果有任何問題,歡迎在評論區留言討論。

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89127.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89127.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89127.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

yolov11安裝,訓練模型,tensorrtx加速,Qt預測圖像

文章目錄 一. yolov11 python環境安裝二. windows10下yolov11 tensorrtx推理加速三. windows10下qt調用tensorrtx加速的yolov11進行檢測 一. yolov11 python環境安裝 基礎環境 CUDA:cuda_11.8.0_522.06_windows cudnn:cudnn-windows-x86_64-8.6.0.163_c…

生物化學 PCR(聚合酶鏈式反應)引物 制造(固相磷酰胺化學法) 購買 存儲

引物(Primer) 引物(Primer)是一小段單鏈 DNA(通常 18~25 個堿基),與模板 DNA 的特定位點互補。包括:Forward Primer(正向引物)和 Reverse Primer&#xff08…

SQL server 獲取表中所有行的序號 不夠四位數的前面補0

在 SQL Server 中,如果你想要為表中的行編號(即序號)添加前導零,以便它們總是呈現為四位數,你可以使用多種方法來實現這一點。以下是幾種常用的方法: 方法1:使用 RIGHT 和 REPLICATE 函數 如果…

熱門話題!網關模塊解決AB機器人和電壓控制器EtherCAT轉Ethernet/IP難題

網關模塊:解決AB機器人與電壓控制器通訊難題 在現代工業自動化生產中,不同設備之間的通信與協同至關重要。然而,由于設備品牌、型號以及所采用的通信協議各異,常常會出現通信兼容性問題。本案例將詳細介紹如何運用捷米特JM-ECTM-E…

將attribute數據動態寫入到excel上

將attribute數據動態寫入到excel上 顯示效果: I 大體思路: excel range name就設置為attribute_數字_類型,在創建template的時候,通過API得到這個event有幾個attribute,就創建幾列,同時還要根據不同的類…

Stable Diffusion入門-ControlNet 深入理解 第一課:ControlNet,控制AI繪圖的“大殺器”

大家好,歡迎來到Stable Diffusion入門-ControlNet深入理解系列的第一課! 今天,我們要聊聊一個讓AI繪畫從“盲目生成”走向“精準控制”的神奇插件——ControlNet。 它就像一位無聲的魔術師,把原本隨意的AI生成圖片變得有條不紊、…

新生代潛力股劉小北:演藝路上的璀璨新星

在娛樂圈新人輩出的當下,一位來自四川的年輕演員正憑借著自己獨特的魅力和扎實的演技,悄然走進觀眾的視野,他就是劉小北。1998年出生的劉小北,畢業于四川電影電視學院,自踏入演藝圈以來,便以堅定的步伐在演…

強制IDEA始終使用Java 8

解決IDEA總是使用Java 21而非Java 8編譯的問題 您遇到的問題是典型的IDE內置JDK與項目沖突的情況。即使系統只安裝了Java 8,IntelliJ IDEA仍內置有最新的Java運行時,導致它使用Java 21來編譯您的代碼。 解決方案:強制IDEA始終使用Java 8 1…

青少年編程與數學 01-012 通用應用軟件簡介 14 詞典及翻譯資源

青少年編程與數學 01-012 通用應用軟件簡介 14 詞典及翻譯資源 一、什么是詞典及翻譯資源(一)詞典及翻譯資源的基本定義(二)詞典及翻譯資源的工作原理(三)詞典及翻譯資源的類型 二、詞典及翻譯資源的重要意…

AI測試革命:5分鐘自動生成單元測試|覆蓋率和邊界測試實戰指南

AI測試革命:5分鐘自動生成單元測試|覆蓋率和邊界測試實戰指南 你是否曾為編寫測試用例絞盡腦汁?是否因遺漏邊界條件導致上線后BUG頻發?告別低效測試,掌握AI賦能的現代化測試策略! 一、為什么我們需要AI測試…

n8n Docker Compose部署

n8n Docker Compose 部署官方文檔詳細總結 1. 前提條件 具備服務器、容器、網絡和安全相關基礎知識。推薦有 Linux 運維經驗。已準備好一臺服務器(建議為云服務器或本地服務器)。 2. 安裝 Docker 和 Docker Compose 以 Ubuntu 為例,完整命…

Talk is cheap. Show me the code.手搓一個 Wayland 客戶端程序

前幾天我寫了一篇萬字長文《萬字長文詳解 Wayland 協議、架構》,但光講協議分析難免有些枯燥。畢竟,程序員更信奉那句名言:Talk is cheap. Show me the code. 所以這篇文章不打算長篇大論,而是通過編寫一個簡單的 Wayland 客戶端程…

Golang JSON 標準庫用法詳解

JSON (JavaScript Object Notation) 是一種輕量級的數據交換格式,Go語言的標準庫encoding/json提供了強大的JSON處理能力。下面我將詳細介紹各種用法并提供示例代碼。 1. 基本編碼(Marshal) 將Go數據結構轉換為JSON字符串。 package maini…

Day.42

hook函數: import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt torch.manual_seed(42) np.random.seed(42) 張量鉤子: x torch.tensor([2.0], requires_gradTrue) y x ** 2 z y ** 3 def tensor_hook…

【.net core】【sqlsugar】在where條件查詢時使用原生SQL

//初始化查詢 var query repository.IQueryable();//添加原生SQL WHERE條件 query query.Where(" fieldA < 123"); 對應調用ISugarQueryable接口類中&#xff1a; ISugarQueryable<T> Where(string whereString, object parameters null);

網絡 : 傳輸層【TCP協議】

網絡 : 傳輸層【TCP協議】 一、TCP協議段格式1.1 32位序號與確認號1.1.1 32位序號1.1.2 確認號 1.2 4位首部長度1.3 6位標志位1.4 16位窗口大小 二、確認應答(ACK)機制三、超時重傳機制四、連接管理機制4.1 三次握手(連接)listen的第二個參數 4.2 四次揮手(斷開連接)**TIME_WAI…

人大金倉Kingbase數據庫 Ksql: 未找到命令

人大金倉Kingbase數據庫 Ksql: 未找到命令 1. 定位 Kingbase 安裝目錄 Kingbase 數據庫通常安裝在 /kingbase/ES/V8/Server 目錄下。可以通過以下命令定位&#xff1a; cd /kingbase/ES/V8/Server2. 驗證 ksql 工具是否安裝成功 執行以下命令檢查 ksql 客戶端工具的版本信息…

Flask(四) 模板渲染render_template

文章目錄 &#x1f4e6; 過程詳解&#xff08;路由 <-> HTML 模板&#xff09;&#x1f9e0; 數據是怎么傳過去的&#xff1f;多變量示例 ? Jinja2 支持條件判斷、循環、模板繼承&#xff1a;? 安全性&#x1f512; Flask 默認也會對變量進行 HTML 轉義&#xff1a;&am…

[附源碼+數據庫+畢業論文+開題報告]基于Spring+MyBatis+MySQL+Maven+jsp實現的寵物領養管理系統,推薦!

摘 要 互聯網發展至今&#xff0c;無論是其理論還是技術都已經成熟&#xff0c;而且它廣泛參與在社會中的方方面面。它讓信息都可以通過網絡傳播&#xff0c;搭配信息管理工具可以很好地為人們提供服務。針對寵物領養信息管理混亂&#xff0c;出錯率高&#xff0c;信息安全性差…

【ArcGIS】水資源單項評價

【ArcGIS】水資源單項評價 一、水資源單項評價1、評價思路 二、操作步驟1、處理環境設置2、數據處理3、要素轉柵格4、水資源評價 一、水資源單項評價 1、評價思路 &#xff08;1&#xff09;省級層面宜選用四級/五級水資源分區或縣級行政區為評價單元&#xff0c;按照水資源總…