【圖像處理入門】3. 幾何變換基礎:從平移旋轉到插值魔法

在這里插入圖片描述

摘要

掌握圖像的幾何變換相當于學會「圖像的空間魔法」。本文將帶你理解平移/旋轉/縮放的數學原理,掌握OpenCV中warpAffinegetAffineTransform的核心用法,對比最近鄰、雙線性等插值算法的優劣。通過圖像翻轉、鏡像、透視變換實戰,學會用變換矩陣控制圖像的空間形態,為圖像配準、目標檢測等高級應用鋪路。

一、幾何變換的數學本質:變換矩陣

所有幾何變換均可表示為矩陣運算:
通用變換公式
[ x ′ y ′ 1 ] = [ a b c d e f 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} a & b & c \\ d & e & f \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} ?xy1? ?= ?ad0?be0?cf1? ? ?xy1? ?

  • 線性變換:左上角2x2矩陣(縮放、旋轉、剪切)
  • 平移變換:第三列(c,d)決定平移量

OpenCV通過warpAffine函數實現仿射變換,需先計算變換矩陣M

二、基礎變換實戰:平移、旋轉、縮放

1. 平移變換:圖像的「空間位移」

import cv2
import numpy as np# 定義平移矩陣:向右平移100像素,向下平移50像素
M = np.float32([[1, 0, 100], [0, 1, 50]])  
translated = cv2.warpAffine(color, M, (width+100, height+50))  # 可視化對比
plt.subplot(121), plt.imshow(rgb), plt.title('Original')
plt.subplot(122), plt.imshow(cv2.cvtColor(translated, cv2.COLOR_BGR2RGB)), plt.title('Translated')

2. 旋轉變換:繞原點的「順時針舞蹈」

# 獲取旋轉矩陣:繞中心旋轉30°,縮放因子1.0
height, width = color.shape[:2]
center = (width//2, height//2)
M = cv2.getRotationMatrix2D(center, 30, 1.0)  
rotated = cv2.warpAffine(color, M, (width, height))  # 注意:旋轉后圖像可能超出邊界,需擴大輸出尺寸避免裁剪

3. 縮放變換:放大縮小的「像素重組」

# 方法1:直接指定尺寸(最近鄰插值)
zoomed_nearest = cv2.resize(color, (width*2, height*2), interpolation=cv2.INTER_NEAREST)  # 方法2:按比例縮放(雙線性插值,更平滑)
zoomed_bilinear = cv2.resize(color, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR)  

三、插值算法:變換時的像素「重建魔法」

不同插值算法在速度和質量間權衡:

算法速度圖像質量適用場景
最近鄰(NEAREST)最快鋸齒明顯縮小圖像、實時處理
雙線性(LINEAR)中等邊緣平滑放大/縮小/旋轉
雙三次(CUBIC)最慢細節保留最佳高質量圖像重建
區域插值(AREA)中等邊緣清晰縮小圖像(優于NEAREST)
# 對比不同插值的縮放效果
plt.figure(figsize=(15, 5))
plt.subplot(131), plt.imshow(zoomed_nearest[:200, :200]), plt.title('Nearest')
plt.subplot(132), plt.imshow(zoomed_bilinear[:200, :200]), plt.title('Bilinear')
plt.subplot(133), plt.imshow(zoomed_cubic[:200, :200]), plt.title('Bicubic')

四、進階變換:翻轉、鏡像與透視

1. 翻轉與鏡像:圖像的「左右互搏」

# 水平翻轉(左右鏡像)
flipped_horizontal = cv2.flip(color, 1)  
# 垂直翻轉(上下顛倒)
flipped_vertical = cv2.flip(color, 0)  
# 同時水平+垂直翻轉
flipped_both = cv2.flip(color, -1)  

2. 透視變換:從平面到3D的「視覺欺騙」

# 定義原始四邊形頂點和目標頂點(均為順時針順序)
src_points = np.float32([[50, 50], [450, 50], [450, 450], [50, 450]])  
dst_points = np.float32([[100, 200], [400, 200], [400, 300], [100, 300]])  # 獲取透視變換矩陣并應用
M_perspective = cv2.getPerspectiveTransform(src_points, dst_points)  
perspective_img = cv2.warpPerspective(color, M_perspective, (width, height))  

五、實戰:證件照尺寸標準化

假設需要將200x300像素的證件照縮放為標準1寸(295x413像素),并保持頭像區域不變:

# 1. 計算縮放比例(保持寬高比)
src_h, src_w = img.shape[:2]
dst_w, dst_h = 295, 413
scale_w = dst_w / src_w
scale_h = dst_h / src_h
scale = min(scale_w, scale_h)# 2. 計算縮放后尺寸和填充區域
new_w = int(src_w * scale)
new_h = int(src_h * scale)
dx = (dst_w - new_w) // 2
dy = (dst_h - new_h) // 2# 3. 縮放+邊緣填充(黑色背景)
resized = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_AREA)
standardized = cv2.copyMakeBorder(resized, dy, dst_h-new_h-dy, dx, dst_w-new_w-dx, cv2.BORDER_CONSTANT, value=(0,0,0))

六、避坑指南:變換中的尺寸計算

  1. 旋轉后的尺寸溢出
    旋轉后圖像可能超出原尺寸,需提前計算最小包圍矩形:

    rows, cols = img.shape[:2]
    M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1)
    # 計算旋轉后的新尺寸
    cos = np.abs(M[0,0]); sin = np.abs(M[0,1])
    new_cols = int(rows*sin + cols*cos)
    new_rows = int(rows*cos + cols*sin)
    M[0,2] += (new_cols - cols)/2; M[1,2] += (new_rows - rows)/2
    
  2. 透視變換的頂點順序
    頂點必須按順時針/逆時針順序排列,否則會出現扭曲

總結

幾何變換是圖像處理的空間操作基石:

  • 平移/旋轉/縮放通過仿射變換矩陣實現,本質是像素的坐標映射
  • 插值算法的選擇直接影響變換后的圖像質量,雙線性插值是平衡之選
  • warpAffinewarpPerspective是處理2D/3D變換的核心函數

下一篇我們將進入圖像增強領域,學習如何通過直方圖均衡化、伽馬校正等技術提升圖像視覺效果。現在請打開一張傾斜的文檔照片,嘗試用透視變換將其矯正為正視角度吧!

思考:為什么旋轉后的圖像邊緣會出現黑邊?如何用邊界填充解決這個問題?

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

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

相關文章

微信小程序學習目錄

個人簡介 👨?💻?個人主頁: 魔術師 📖學習方向: 主攻前端方向,正逐漸往全棧發展 🚴個人狀態: 研發工程師,現效力于政務服務網事業 🇨🇳人生格言&…

QT 5.15.2 程序中文亂碼

1. 在.pro文件中添加: msvc { QMAKE_CXXFLAGS /source-charset:utf-8 /execution-charset:utf-8 }備注:.pro文件只有在選擇 qmake 方式才會生成。 [Cmake 只會生成 CMakeLists.txt 文件] 2. 在文件首部增加以下程序行 #pragma execution_character_s…

Unity UI設計優化與模式原則

前言 在 Unity 中設計高效且可維護的 UI 系統時,需要結合性能優化和設計模式兩大核心方向。以下是關鍵原則及實踐方法: 對惹,這里有一個游戲開發交流小組,希望大家可以點擊進來一起交流一下開發經驗呀! 一、UI 性能…

CppCon 2014 學習: The Implementation of Value Types

“The Implementation of Value Types” 在C里,通常指的是如何設計和實現**值類型(value types)**的類,確保它們符合值語義(value semantics),也就是說: 對象的賦值和拷貝操作應該是…

每日算法刷題Day19 5.31:leetcode二分答案3道題,用時1h

6. 475.供暖器(中等,學習check函數雙指針思想) 475. 供暖器 - 力扣(LeetCode) 思想 1.冬季已經來臨。 你的任務是設計一個有固定加熱半徑的供暖器向所有房屋供暖。在加熱器的加熱半徑范圍內的每個房屋都可以獲得供暖。現在,給出…

【計算機網絡】第2章:應用層—應用層協議原理

目錄 1. 網絡應用的體系結構 2. 客戶-服務器(C/S)體系結構 3. 對等體(P2P)體系結構 4. C/S 和 P2P 體系結構的混合體 Napster 即時通信 5. 進程通信 6. 分布式進程通信需要解決的問題 7. 問題1:對進程進行編址…

PHP+MySQL開發語言 在線下單訂水送水小程序源碼及搭建指南

隨著互聯網技術的不斷發展,在線下單訂水送水服務為人們所需要。分享一款 PHP 和 MySQL 搭建一個功能完善的在線訂水送水小程序源碼及搭建教程。這個系統將包含用戶端和管理端兩部分,用戶可以在線下單、查詢訂單狀態,管理員可以處理訂單、管理…

vBulletin未認證API方法調用漏洞(CVE-2025-48827)

免責聲明 本文檔所述漏洞詳情及復現方法僅限用于合法授權的安全研究和學術教育用途。任何個人或組織不得利用本文內容從事未經許可的滲透測試、網絡攻擊或其他違法行為。使用者應確保其行為符合相關法律法規,并取得目標系統的明確授權。 對于因不當使用本文信息而造成的任何直…

計算機模擬分子合成有哪些應用軟件?

參閱:Top 創新大獎 以下是用于計算機模擬分子合成(包括逆合成設計、分子對接、分子動力學模擬及綜合設計平臺)的主流應用軟件分類總結,結合其核心功能和應用場景進行整理: 🔬 一、逆合成設計與路線規劃軟件…

Excel 中的SUMIFS用法(基礎版),重復項求和

1. 首先復制篩選條件所在的列,去除重復項目 數據 》重復項 》刪除重復項 2. 輸入函數公式 SUMIFS(C:C,A:A,E2) 3. 選中單元格,通過 ShiftF3 查看函數參數 第一個參數:求和區域,要累加的值所在的區域范圍 第二個參數&#xff1a…

【xmb】內部文檔148344597

基于小米CyberDog 2的自主導航與視覺感知系統設計報告 摘要: 本文針對2025年全國大學生計算機系統能力大賽智能系統創新設計賽(小米杯)初賽要求,設計并實現了基于小米仿生四足機器人CyberDog 2的平臺系統方案。參賽作品利用Cyber…

從零開始理解機器學習:知識體系 + 核心術語詳解

你可能聽說過“機器學習”,覺得它很神秘,像是讓電腦自己學會做事。其實,機器學習的本質很簡單:通過數據來自動建立規則,從而完成預測或決策任務。 這篇文章將帶你系統梳理機器學習的知識體系,并用貼近生活…

springboot集成websocket給前端推送消息

一般通常情況下,我們都是前端主動朝后端發送請求,那么有沒有可能,后端主動給前端推送消息呢?這時候就可以借助websocket來實現。下面給出一個簡單的實現樣例。 首先創建一個websocketDemo工程,該工程的整體結構如下&a…

【清晰教程】查看和修改Git配置情況

目錄 查看安裝版本 查看特定配置 查看全局配置 查看本地倉庫配置 設置或修改配置 查看安裝版本 打開命令行工具,通過version命令檢查Git版本號。 git --version 如果顯示出 Git 的版本號,說明 Git 已經成功安裝。 查看特定配置 如果想要查看特定…

【Github/Gitee Webhook觸發自動部署-Jenkins】

Github/Gitee Webhook觸發自動部署-Jenkins #mermaid-svg-hRyAcESlyk5R2rDn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hRyAcESlyk5R2rDn .error-icon{fill:#552222;}#mermaid-svg-hRyAcESlyk5R2rDn .error-tex…

C語言數據結構-鏈式棧

頭文件&#xff1a;stack.h #ifndef __STACK_H__ #define __STACK_H__ #include <stdio.h> #include <stdlib.h> typedef int DataType; /* 鏈式棧節點類型 */ typedef struct staNode { DataType data; struct staNode *pNext; }StackNode; /* 鏈式棧…

M4Pro安裝ELK(ElasticSearch+LogStash+Kibana)踩坑記錄

ElasticSearch安裝&#xff0c;啟動端口9200&#xff1a; docker pull elasticsearch:8.13.0 新增配置文件elasticsearch.yml&#xff1a; cd /opt/homebrew/etc/ mkdir elasticsearch_config cd elasticsearch_config vi elasticsearch.yml cluster.name: "nfturbo…

uni-app學習筆記十六-vue3頁面生命周期(三)

uni-app官方文檔頁面生命周期部分位于頁面 | uni-app官網。 本篇再介紹2個生命周期 1.onUnload&#xff1a;用于監聽頁面卸載。 當頁面被關閉時&#xff0c;即頁面的緩存被清掉時觸發加載onUnload函數。 例如:在demo6頁面點擊跳轉到demo4&#xff0c;在demo4頁面回退不了到d…

Java互聯網大廠面試:從Spring Boot到Kafka的技術深度探索

Java互聯網大廠面試&#xff1a;從Spring Boot到Kafka的技術深度探索 在某家互聯網大廠的面試中&#xff0c;面試官A是一位技術老兵&#xff0c;而被面試者謝飛機&#xff0c;號稱有豐富的Java開發經驗。以下是他們的面試情景&#xff1a; 場景&#xff1a;電商平臺的后端開發…

機器學習算法——KNN

一、KNN算法簡介 1.KNN思想 &#xff08;1&#xff09;K-近鄰算法 根據你的“鄰居”來推斷你是什么類別 KNN算法思想&#xff1a;如果一個樣本在特征空間&#xff08;訓練集&#xff09;中的k個最相似的樣本中的大多數屬于某一個類別。則該樣本也屬于這個類別 &#xff08…