【圖像處理基石】如何進行圖像畸變校正?

在這里插入圖片描述
圖像畸變校正常用于計算機視覺、攝影測量學和機器人導航等領域,能夠修正因鏡頭光學特性或傳感器排列問題導致的圖像失真。下面我將介紹幾種常用的圖像畸變校正算法,并提供Python實現和測試用例。

常用算法及Python實現

1. 徑向畸變校正

徑向畸變是最常見的畸變類型,表現為圖像中心區域正常,邊緣區域出現拉伸或壓縮。校正公式如下:

import numpy as np
import cv2
from matplotlib import pyplot as pltdef correct_radial_distortion(image, k1, k2, k3=0):"""校正圖像的徑向畸變參數:image: 輸入的畸變圖像k1, k2, k3: 徑向畸變系數返回:corrected_image: 校正后的圖像"""h, w = image.shape[:2]# 創建網格坐標x, y = np.meshgrid(np.arange(w), np.arange(h))x_c, y_c = w / 2, h / 2  # 圖像中心# 計算離中心的距離r = np.sqrt((x - x_c)**2 + (y - y_c)**2)# 徑向畸變校正公式x_distorted = (x - x_c) * (1 + k1 * r**2 + k2 * r**4 + k3 * r**6) + x_cy_distorted = (y - y_c) * (1 + k1 * r**2 + k2 * r**4 + k3 * r**6) + y_c# 使用雙線性插值進行重采樣corrected_image = np.zeros_like(image)# 處理整數坐標x_distorted_int = np.clip(x_distorted.astype(int), 0, w - 1)y_distorted_int = np.clip(y_distorted.astype(int), 0, h - 1)# 應用校正if len(image.shape) == 3:  # 彩色圖像corrected_image[y, x] = image[y_distorted_int, x_distorted_int]else:  # 灰度圖像corrected_image[y, x] = image[y_distorted_int, x_distorted_int]return corrected_image# 測試用例
def test_radial_distortion():# 創建測試圖像(棋盤格)test_image = np.zeros((400, 400), dtype=np.uint8)for i in range(8):for j in range(8):if (i + j) % 2 == 0:test_image[i*50:(i+1)*50, j*50:(j+1)*50] = 255# 引入徑向畸變(k1=0.00005, k2=0.0000002)distorted_image = correct_radial_distortion(test_image, 0.00005, 0.0000002)# 校正徑向畸變corrected_image = correct_radial_distortion(distorted_image, -0.00005, -0.0000002)# 顯示結果plt.figure(figsize=(15, 5))plt.subplot(131), plt.imshow(test_image, cmap='gray')plt.title('原始圖像'), plt.axis('off')plt.subplot(132), plt.imshow(distorted_image, cmap='gray')plt.title('畸變圖像'), plt.axis('off')plt.subplot(133), plt.imshow(corrected_image, cmap='gray')plt.title('校正圖像'), plt.axis('off')plt.show()# 運行測試
test_radial_distortion()
2. 切向畸變校正

切向畸變是由于鏡頭與圖像傳感器不平行引起的,表現為圖像局部區域的傾斜。校正公式如下:

def correct_tangential_distortion(image, p1, p2):"""校正圖像的切向畸變參數:image: 輸入的畸變圖像p1, p2: 切向畸變系數返回:corrected_image: 校正后的圖像"""h, w = image.shape[:2]# 創建網格坐標x, y = np.meshgrid(np.arange(w), np.arange(h))x_c, y_c = w / 2, h / 2  # 圖像中心# 計算離中心的距離r = np.sqrt((x - x_c)**2 + (y - y_c)**2)# 切向畸變校正公式x_distorted = (x - x_c) + (2 * p1 * (x - x_c) * (y - y_c) + p2 * (r**2 + 2 * (x - x_c)**2)) + x_cy_distorted = (y - y_c) + (p1 * (r**2 + 2 * (y - y_c)**2) + 2 * p2 * (x - x_c) * (y - y_c)) + y_c# 使用雙線性插值進行重采樣corrected_image = np.zeros_like(image)# 處理整數坐標x_distorted_int = np.clip(x_distorted.astype(int), 0, w - 1)y_distorted_int = np.clip(y_distorted.astype(int), 0, h - 1)# 應用校正if len(image.shape) == 3:  # 彩色圖像corrected_image[y, x] = image[y_distorted_int, x_distorted_int]else:  # 灰度圖像corrected_image[y, x] = image[y_distorted_int, x_distorted_int]return corrected_image# 測試用例
def test_tangential_distortion():# 創建測試圖像(棋盤格)test_image = np.zeros((400, 400), dtype=np.uint8)for i in range(8):for j in range(8):if (i + j) % 2 == 0:test_image[i*50:(i+1)*50, j*50:(j+1)*50] = 255# 引入切向畸變(p1=0.001, p2=0.0008)distorted_image = correct_tangential_distortion(test_image, 0.001, 0.0008)# 校正切向畸變corrected_image = correct_tangential_distortion(distorted_image, -0.001, -0.0008)# 顯示結果plt.figure(figsize=(15, 5))plt.subplot(131), plt.imshow(test_image, cmap='gray')plt.title('原始圖像'), plt.axis('off')plt.subplot(132), plt.imshow(distorted_image, cmap='gray')plt.title('畸變圖像'), plt.axis('off')plt.subplot(133), plt.imshow(corrected_image, cmap='gray')plt.title('校正圖像'), plt.axis('off')plt.show()# 運行測試
test_tangential_distortion()
3. 使用OpenCV進行相機標定與畸變校正

實際應用中,通常使用OpenCV提供的相機標定功能來自動計算畸變系數:

def camera_calibration_and_undistortion():"""使用OpenCV進行相機標定和圖像畸變校正"""# 準備對象點,如 (0,0,0), (1,0,0), (2,0,0) ..., (7,5,0)objp = np.zeros((6*8, 3), np.float32)objp[:, :2] = np.mgrid[0:8, 0:6].T.reshape(-1, 2)# 存儲對象點和圖像點的數組objpoints = []  # 3D點在現實世界中的坐標imgpoints = []  # 2D點在圖像平面中的坐標# 生成模擬標定圖像(通常需要使用多幅圖像)images = []for i in range(5):img = np.zeros((480, 640), dtype=np.uint8)# 生成模擬的棋盤格角點corners = np.zeros((48, 2), dtype=np.float32)for j in range(48):x = 50 + (j % 8) * 60 + np.random.randint(-5, 6)  # 添加隨機畸變y = 50 + (j // 8) * 60 + np.random.randint(-5, 6)corners[j] = [x, y]imgpoints.append(corners)objpoints.append(objp)# 在圖像上繪制角點for corner in corners:cv2.circle(img, (int(corner[0]), int(corner[1])), 5, 255, -1)images.append(img)# 相機標定ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, images[0].shape[::-1], None, None)# 生成測試圖像test_img = np.zeros((480, 640), dtype=np.uint8)for i in range(8):for j in range(6):cv2.circle(test_img, (100 + i * 60, 100 + j * 60), 10, 255, -1)# 畸變校正h, w = test_img.shape[:2]newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))undistorted_img = cv2.undistort(test_img, mtx, dist, None, newcameramtx)# 顯示結果plt.figure(figsize=(10, 5))plt.subplot(121), plt.imshow(test_img, cmap='gray')plt.title('畸變圖像'), plt.axis('off')plt.subplot(122), plt.imshow(undistorted_img, cmap='gray')plt.title('校正圖像'), plt.axis('off')plt.show()# 返回標定結果return mtx, dist# 運行相機標定和畸變校正
camera_matrix, distortion_coeffs = camera_calibration_and_undistortion()
print("相機內參矩陣:\n", camera_matrix)
print("畸變系數:\n", distortion_coeffs)

算法解釋

  1. 徑向畸變校正

    • 徑向畸變是最常見的畸變類型,表現為圖像中心區域正常,邊緣區域出現拉伸或壓縮。
    • 校正公式基于多項式模型,通過徑向畸變系數(k1, k2, k3)來調整像素位置。
  2. 切向畸變校正

    • 切向畸變是由于鏡頭與圖像傳感器不平行引起的,表現為圖像局部區域的傾斜。
    • 校正公式使用切向畸變系數(p1, p2)來調整像素位置。
  3. 相機標定與OpenCV實現

    • 實際應用中,通常使用已知的標定板(如棋盤格)來計算相機的內參矩陣和畸變系數。
    • OpenCV提供了完整的相機標定和畸變校正功能,能夠自動計算所有參數并進行圖像校正。

以上代碼實現了常見的圖像畸變校正算法,并提供了測試用例來驗證算法的有效性。在實際應用中,你可能需要根據具體的相機型號和場景來調整參數。

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

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

相關文章

藍橋杯_DS18B20溫度傳感器---新手入門級別超級詳細解析

目錄 一、引言 DS18B20的原理圖 單總線簡介: ?編輯暫存器簡介: DS18B20的溫度轉換與讀取流程 二、代碼配置 maic文件 疑問 關于不同格式化輸出符號的使用 為什么要rd_temperature()/16.0? onewire.h文件 這個配置為什么要先讀lo…

MySQL的并發事務問題及事務隔離級別

一、并發事務問題 1). 贓讀:一個事務讀到另外一個事務還沒有提交的數據。 比如 B 讀取到了 A 未提交的數據。 2). 不可重復讀:一個事務先后讀取同一條記錄,但兩次讀取的數據不同,稱之為不可重復讀。 事務 A 兩次讀取同一條記錄&…

密碼學基礎——SM4算法

博客主頁:christine-rr-CSDN博客 ????專欄主頁:密碼學 📌 【今日更新】📌 對稱密碼算法——SM4 目錄 一、國密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特點 2.3 基本部件 2.3.1 S盒 2.3.2 非線性變換 ?編輯…

練習:對象數組 4

定義數組存儲 4 個女朋友的對象。女朋友的屬性:姓名、年齡、性別、愛好;要求1:計算出四個女朋友的平均年齡;要求2:統計年齡比平均值低的女朋友有幾個?并把他們的所有信息打印出來。 代碼: //對…

React Hooks 基礎指南

React Hooks 是 React 16.8 引入的重要特性,它允許開發者在函數組件中使用狀態和其他 React 特性。本文將詳細介紹 6 個最常用的 React Hooks。 1. useState useState 是最常用的 Hook,用于在函數組件中添加 state。 import React, { useState } from…

【Python 算法零基礎 4.排序 ⑥ 快速排序】

既有錦繡前程可奔赴,亦有往日歲月可回首 —— 25.5.25 選擇排序回顧 ① 遍歷數組:從索引 0 到 n-1(n 為數組長度)。 ② 每輪確定最小值:假設當前索引 i 為最小值索引 min_index。從 i1 到 n-1 遍歷,若找到…

處理git沒做修改,但是文件顯示變更的情況

使用 TortoiseGit(小烏龜 Git) 時遇到 “文件內容沒改,但顯示為變更,提示有 n 行刪除、n 行添加”,你可以按照以下步驟操作來排查并解決問題: ? 一、定位問題根源(是否為行尾差異)…

智慧貨運飛船多維度可視化管控系統

圖撲搭建智慧貨運飛船可視化系統,借數字孿生技術,高精度復刻貨運飛船外觀、結構與運行場景。整合多維度數據,實時呈現飛行狀態、設備參數等信息,助力直觀洞察貨運飛船運行邏輯,為航天運維、任務推演及決策提供數字化支…

maven微服務${revision}依賴打包無法識別

1、場景描述 我現在又一個微服務項目&#xff0c;父pom的版本&#xff0c;使用<properties>定義好&#xff0c;如下所示&#xff1a; <name>ypsx-finance-center</name> <artifactId>ypsx-finance</artifactId> <packaging>pom</pack…

詳解代理型RAG與MCP服務器集成

檢索增強型生成(RAG)將語言模型與外部知識檢索相結合,讓模型的回答基于最新的事實,而不僅僅是其訓練數據呢。 RAG(高級別) 在 RAG 流程中,用戶查詢用于搜索知識庫(通常通過向量數據庫中的嵌入來實現),并將檢索到的最相關文檔“增強”到模型的提示中,以幫助生成事實…

智能倉儲的未來:自動化、AI與數據分析如何重塑物流中心

當倉庫學會“思考”&#xff0c;物流的終極形態正在誕生 想象這樣的場景&#xff1a; 凌晨3點&#xff0c;某物流中心燈火通明卻空無一人。AGV機器人集群根據實時訂單動態規劃路徑&#xff1b;AI視覺系統在0.1秒內掃描包裹信息&#xff1b;數字孿生平臺正模擬次日峰值流量壓力…

如何防止服務器被用于僵尸網絡(Botnet)攻擊 ?

防止服務器被用于僵尸網絡&#xff08;Botnet&#xff09;攻擊是關鍵的網絡安全措施之一。僵尸網絡是黑客利用大量被感染的計算機、服務器或物聯網設備來發起攻擊的網絡。以下是關于如何防止服務器被用于僵尸網絡攻擊的技術文章&#xff1a; 防止服務器被用于僵尸網絡&#xff…

貪心算法應用:硬幣找零問題詳解

貪心算法與硬幣找零問題詳解 貪心算法&#xff08;Greedy Algorithm&#xff09;在解決優化問題時表現出簡潔高效的特點&#xff0c;尤其適用于特定結構的組合優化問題。本文將用2萬字篇幅&#xff0c;深入探討貪心算法在硬幣找零問題中的應用&#xff0c;覆蓋算法原理、正確性…

Java高級 | 【實驗一】Springboot安裝及測試 |最新

隸屬文章&#xff1a;Java高級 | &#xff08;二十二&#xff09;Java常用類庫-CSDN博客 目錄 一、SpringBoot的特點 二、Spring Boot安裝及測試 &#xff08;一&#xff09;安裝Intellij IDEA &#xff08;二&#xff09;安裝MySQL &#xff08;三&#xff09;安裝postma…

C# WPF 左右布局實現學習筆記(1)

開發流程視頻&#xff1a; https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源碼&#xff1a; GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF應用&#xff08;.NET Framework) 2.…

從零開始,學會上傳,更新,維護github倉庫

以下是一份從頭到尾、覆蓋安裝、配置、創建倉庫、上傳項目到 GitHub 的完整教程。全程使用通用示例&#xff0c;不包含任何具體的倉庫鏈接&#xff0c;僅供參考。 一、準備工作 1. 注冊 GitHub 賬號 打開瀏覽器&#xff0c;訪問 GitHub 官網&#xff08;輸入 “GitHub” 即可找…

使用 Docker Compose 從零部署 TeamCity + PostgreSQL(詳細新手教程)

JetBrains TeamCity 是一款專業的持續集成&#xff08;CI&#xff09;服務器工具&#xff0c;支持各種編程語言和構建流程。本文將一步一步帶你用 Docker 和 Docker Compose 快速部署 TeamCity&#xff0c;搭配 PostgreSQL 數據庫&#xff0c;并確保 所有操作新手可跟著做。 一…

微軟推出SQL Server 2025技術預覽版,深化人工智能應用集成

在Build 2025 大會上&#xff0c;微軟向開發者社區開放了SQL Server 2025的測試版本。該版本的技術改進主要涵蓋人工智能功能集成、系統性能優化與開發工具鏈升級三個維度&#xff0c;展示了數據庫管理系統在智能化演進方向上的重要進展。 智能數據處理功能更新 新版本的技術亮…

企業管理中,商業智能BI主要做哪些事情?

開門見山的告訴大家&#xff0c;在企業管理中商業智能BI 主要就做三件事&#xff1a;拉通數據、整合數據、數據可視化展現。 技術角度的商業智能BI 從技術的角度來講&#xff0c;商業智能BI是一套完整的由數據倉庫、查詢報表、數據分析等組成的數據類技術解決方案。它有一個非…

openharmony5.0.0中kernel子系統編譯構建流程概覽(rk3568)

概述 在梳理openharmony對linux內核做了哪些更改時&#xff0c;簡單梳理了下kernel部分的編譯構建流程&#xff0c;并根據源碼做了簡單論證。分享出來&#xff0c;希望對大家有所幫助。 系統版本:openharmony5.0.0 開發板:dayu200 編譯環境:ubuntu22 執行流程 在kernel\l…