python編程-OpenCV(圖像讀寫-圖像處理-圖像濾波-角點檢測-邊緣檢測)圖像變換

形態變換

圖像處理中的形態學操作是處理圖像結構的有效方法。以下是一些常見的形態學操作的介紹及其在 OpenCV 中的實現示例。

1. 腐蝕(Erosion)

腐蝕操作通過消除圖像邊界來減少圖像中的白色區域(前景),使物體的邊界向內收縮。它的作用是去除小的噪點。根據內核的大小,邊界附近的所有像素都將被丟棄。因此,前景對象的厚度或大小在圖像中減少或只是白色區域減少。它有助于消除小的白色噪音,分離兩個連接的對象等。

import cv2
import numpy as np# 讀取圖像
image = cv2.imread('f:/apple.jpg', 0)
# 定義腐蝕的內核
kernel = np.ones((5,5), np.uint8)
# 進行腐蝕操作  
eroded = cv2.erode(image, kernel, iterations=1)cv2.imshow('Eroded Image', eroded)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. 膨脹(Dilation)

膨脹操作與腐蝕相反,主要是增加圖像中的白色區域,使物體的邊界向外擴展。

# 進行膨脹操作  
dilated = cv2.dilate(image, kernel, iterations=1)  cv2.imshow('Dilated Image', dilated)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

3. 開運算(Opening)

開運算是先進行腐蝕再進行膨脹,用于去除小的噪聲,并保持圖像中物體的形狀和大小。

# 進行開運算  
opened = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)  cv2.imshow('Opened Image', opened)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

4. 閉運算(Closing)

閉運算是先進行膨脹再進行腐蝕,主要用于填補圖像中的小孔洞或黑色區域。

# 進行閉運算  
closed = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)  cv2.imshow('Closed Image', closed)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

5. 形態梯度(Morphological Gradient)

形態梯度是圖像膨脹與腐蝕之間的差異,用于提取邊緣。

# 進行形態梯度  
gradient = cv2.morphologyEx(image, cv2.MORPH_GRADIENT, kernel)  cv2.imshow('Morphological Gradient', gradient)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

6. 頂帽(Top Hat)

頂帽運算是原圖像與開運算結果的差,主要用于突出比周圍區域亮的部分。

# 進行頂帽運算  
tophat = cv2.morphologyEx(image, cv2.MORPH_TOPHAT, kernel)  cv2.imshow('Top Hat', tophat)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

7. 黑帽(Black Hat)

黑帽運算是閉運算結果與原圖像的差,主要用于突出比周圍區域暗的部分。

# 進行黑帽運算  
blackhat = cv2.morphologyEx(image, cv2.MORPH_BLACKHAT, kernel)  cv2.imshow('Black Hat', blackhat)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

幾何變換

縮放

縮放是調整圖片的大小。 OpenCV 使用cv.resize()函數進行調整。可以手動指定圖像的大小,也可以指定比例因子。可以使用不同的插值方法。

import numpy as np
import cv2 as cv
img = cv.imread('image.jpg')
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
#OR
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)

平移變換
平移變換是物體位置的移動。轉換矩陣:

t_x,t_y是方向的偏移量,可以將變換矩陣存為 np.float32 類型的 numpy 數組,并將其作為 cv.warpAffine 的第二個參數。cv.warpAffine 函數的第三個參數是輸出圖像的大小,其形式應為(寬度、高度)。記住寬度=列數,高度=行數。

import numpy as np
import cv2 as cv
img = cv.imread('image.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow('img',dst)
cv.waitKey(0)
cv.destroyAllWindows()

旋轉

旋轉矩陣:

但 Opencv 提供了可變旋轉中心的比例變換,所以你可以在任意位置旋轉圖片,修改后的轉換矩陣為:

例如旋轉90度:

img = cv.imread('image.jpg',0)
rows,cols = img.shape
# cols-1 and rows-1 are the coordinate limits.
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv.warpAffine(img,M,(cols,rows))

仿射變換
在仿射變換中,原始圖像中的所有平行線在輸出圖像中仍然是平行的。仿射變換是圖像處理和計算機視覺中的一種重要技術,用于執行圖像的幾何變換。它保留了點、直線和面之間的相對位置關系,因此常用于圖像的旋轉、縮放、平移和傾斜等操作。

仿射變換包括:

  1. 平移(Translation):圖像中的每個點沿著 x 和 y 軸移動指定的距離。
  2. 縮放(Scaling):根據指定的比例因子縮放圖像的大小。
  3. 旋轉(Rotation):繞圖像中心點旋轉一定的角度。
  4. 傾斜(Shearing):沿 x 或 y 方向對圖像進行剪切或傾斜。

結合這些操作,可以通過仿射矩陣來實現任意的仿射變換。仿射變換的矩陣形式可以表示為:

在 OpenCV 中,使用?cv2.warpAffine?函數執行仿射變換。下面是一個示例,展示如何進行平移、縮放和旋轉:

import cv2
import numpy as np# 讀取圖像
image = cv2.imread('f:/apple.jpg')# 獲取圖像的尺寸
rows, cols, _ = image.shape# 定義仿射變換矩陣
# 這里定義一個平移和縮放的組合
# 平移 tx = 50,ty = 30;縮放 sx = 1.5,sy = 1.5(增加 50%)
M = np.float32([[1.5, 0, 50],[0, 1.5, 30]])# 應用仿射變換
dst = cv2.warpAffine(image, M, (int(cols * 1.5), int(rows * 1.5)))# 顯示結果
cv2.imshow('Original Image', image)
cv2.imshow('Transformed Image', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

綜合仿射變換

下面是一個完成平移、縮放和旋轉組合的仿射變換示例:

import cv2
import numpy as np# 讀取圖像
image = cv2.imread('f:/apple.jpg')
# 獲取圖像的中心
center = (image.shape[1] // 2, image.shape[0] // 2)# 定義旋轉角度和縮放因子
angle = 45  # 旋轉 45 度
scale = 1.0 # 不縮放  # 獲取仿射變換矩陣
M = cv2.getRotationMatrix2D(center, angle, scale)# 應用仿射變換
transformed = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))# 顯示結果
cv2.imshow('Original Image', image)
cv2.imshow('Transformed Image', transformed)
cv2.waitKey(0)
cv2.destroyAllWindows()

透視變換
透視變換是一種將圖像中某個區域進行變形的技術,使得該區域看起來像從不同的角度觀看。透視變換通過將圖像中的四個點映射到另一個四邊形區域來實現,這樣就能夠模擬真實世界中由于相機角度變化而引起的視覺變化。

對透視轉換,你需要一個 3x3 變換矩陣。即使在轉換之后,直線也將保持直線。

要找到這個變換矩陣,需要輸入圖像上的 4 個點和輸出圖像上的相應點。在這四點中,任意三點不應該共線。


?在 OpenCV 中,透視變換使用?cv2.getPerspectiveTransform?函數來計算透視變換矩陣,然后用?cv2.warpPerspective?函數應用該變換。
?

import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('f:/apple.jpg')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()# 讀取圖像
image = cv2.imread('f:/apple.jpg')# 獲取圖像的尺寸
height, width = image.shape[:2]# 定義源圖像中的四個點(例如,選擇四個角點)
pts1 = np.float32([[100, 100], [200, 100], [100, 200], [200, 200]])
# 定義目標圖像中的四個點
pts2 = np.float32([[80, 80], [220, 100], [90, 210], [210, 220]])# 計算透視變換矩陣
M = cv2.getPerspectiveTransform(pts1, pts2)# 應用透視變換
warped_image = cv2.warpPerspective(image, M, (width, height))# 顯示結果
cv2.imshow('Original Image', image)
cv2.imshow('Warped Image', warped_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

頻域變換:傅里葉變換和拉普拉斯變換

Numpy具有FFT軟件包進行傅里葉變換。np.fft.fft2() 為我們提供了頻率轉換。它的第一個參數是輸入灰度圖像。第二個參數是可選的,它決定輸出數組的大小。如果它大于輸入圖像的大小,則在計算FFT之前用零填充輸入圖像。如果小于輸入圖像,將裁切輸入圖像。如果未傳遞任何參數,則輸出數組的大小將與輸入的大小相同。?

使用 NumPy 執行圖像的傅里葉變換(FFT)和反傅里葉變換(IFFT):

1. 傅里葉變換(FFT)

np.fft.fft2()?用于計算二維傅里葉變換,適合處理灰度圖像。你可以傳遞一個可選的大小參數來決定輸出數組的形狀。

2. 逆傅里葉變換(IFFT)

np.fft.ifft2()?用于計算二維逆傅里葉變換,將頻域數據轉換回時域。

import numpy as np
import cv2
import matplotlib.pyplot as plt# 讀取灰度圖像
image = cv2.imread('f:/apple.jpg', cv2.IMREAD_GRAYSCALE)# 執行傅里葉變換
# 參數為 image 的 shape 可以控制零填充大小
f_transform = np.fft.fft2(image)# 對傅里葉變換結果進行移位,使得低頻部分居中
f_transform_shifted = np.fft.fftshift(f_transform)# 計算幅度譜,以便可視化
magnitude_spectrum = np.log(np.abs(f_transform_shifted) + 1)  # 避免 log(0)# 執行逆傅里葉變換
# 首先對移位后的頻域圖像進行逆變換
inverse_transform_shifted = np.fft.ifftshift(f_transform_shifted)
recovered_image = np.fft.ifft2(inverse_transform_shifted)# 取實部作為恢復的圖像
recovered_image = np.abs(recovered_image)# 顯示原始圖像、幅度譜和恢復的圖像
plt.figure(figsize=(12, 12))plt.subplot(1, 3, 1)
plt.title('Original Image')
plt.imshow(image, cmap='gray')
plt.axis('off')plt.subplot(1, 3, 2)
plt.title('Magnitude Spectrum')
plt.imshow(magnitude_spectrum, cmap='gray')
plt.axis('off')plt.subplot(1, 3, 3)
plt.title('Recovered Image')
plt.imshow(recovered_image, cmap='gray')
plt.axis('off')plt.tight_layout()
plt.show()

OpenCV中的傅立葉變換
OpenCV 為此提供了功能 cv.dft() 和 cv.idft() 。它返回與以前相同的結果,但是有兩個通道。第一個通道將具有結果的實部,第二個通道將具有結果的虛部。輸入的圖像應首先轉換為np.float32 。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt# 讀取圖像
img = cv.imread('f:/apple.jpg', 0)# 1. 計算傅里葉變換
dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)# 2. 計算幅度譜
magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))# 3. 創建掩碼,然后將掩碼應用于傅里葉變換結果
rows, cols = img.shape
crow, ccol = rows // 2, cols // 2# 創建一個掩碼,中心區域為1,其余區域為0(高通濾波器)
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1  # 中心區域為1# 應用掩碼
fshift = dft_shift * mask# 4. 計算逆傅里葉變換
f_ishift = np.fft.ifftshift(fshift)  # 反移位
img_back = cv.idft(f_ishift)  # 逆傅里葉變換
img_back = cv.magnitude(img_back[:, :, 0], img_back[:, :, 1])  # 獲取復數的幅度# 5. 顯示原圖、傅里葉變換幅度譜和恢復后的圖像
plt.figure(figsize=(12, 6))# 原始圖像
plt.subplot(1, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Input Image')
plt.xticks([]), plt.yticks([])# 幅度譜
plt.subplot(1, 3, 2)
plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum')
plt.xticks([]), plt.yticks([])# 恢復后的圖像
plt.subplot(1, 3, 3)
plt.imshow(img_back, cmap='gray')
plt.title('Recovered Image')
plt.xticks([]), plt.yticks([])plt.tight_layout()  # 自動調整子圖參數
plt.show()

拉普拉斯算子是高通濾波器,Sobel是HPF。只需對Laplacian進行傅立葉變換,以獲得更大的FFT大小。四種常用算子:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt# 簡單平均濾波器(不帶縮放參數)
mean_filter = np.ones((3, 3))# 創建高斯濾波器
x = cv.getGaussianKernel(5, 10)
gaussian = x * x.T# 不同的邊緣檢測濾波器
# Scharr濾波器(x方向)
scharr = np.array([[-3, 0, 3],[-10, 0, 10],[-3, 0, 3]])# Sobel濾波器(x方向)
sobel_x = np.array([[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]])# Sobel濾波器(y方向)
sobel_y = np.array([[-1, -2, -1],[0, 0, 0],[1, 2, 1]])# 拉普拉斯濾波器
laplacian = np.array([[0, 1, 0],[1, -4, 1],[0, 1, 0]])# 將所有濾波器放入列表中
filters = [mean_filter, gaussian, laplacian, sobel_x, sobel_y, scharr]
filter_name = ['mean_filter', 'gaussian', 'laplacian', 'sobel_x', 'sobel_y', 'scharr']# 計算每個濾波器的傅里葉變換
fft_filters = [np.fft.fft2(f) for f in filters]
fft_shift = [np.fft.fftshift(y) for y in fft_filters]# 計算每個濾波器的幅度譜
mag_spectrum = [np.log(np.abs(z) + 1) for z in fft_shift]# 繪制幅度譜
plt.figure(figsize=(12, 6))
for i in range(6):  # 使用 range 代替 xrangeplt.subplot(2, 3, i + 1)plt.imshow(mag_spectrum[i], cmap='gray')plt.title(filter_name[i])plt.xticks([]), plt.yticks([])plt.tight_layout()  # 調整子圖參數
plt.show()

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

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

相關文章

【Prometheus】PromQL進階用法

?? 歡迎大家來到景天科技苑?? 🎈🎈 養成好習慣,先贊后看哦~🎈🎈 🏆 作者簡介:景天科技苑 🏆《頭銜》:大廠架構師,華為云開發者社區專家博主,…

SiamCAR(2019CVPR):用于視覺跟蹤的Siamese全卷積分類和回歸網絡

原文標題:SiamCAR: Siamese Fully Convolutional Classification and Regression for Visual Tracking 中文標題:SiamCAR:用于視覺跟蹤的Siamese全卷積分類和回歸 代碼地址: https://github.com/ohhhyeahhh/SiamCAR Abstract 通過將視覺跟蹤任務分解為兩個子問題,…

計算機網絡介質訪問控制全攻略:從信道劃分到協議詳解!!!

一、信道劃分介質訪問控制 介質訪問控制:多個節點共享同一個“總線型”廣播信道時,可能發生“信號沖突” 應該怎么控制各節點對傳輸介質的訪問,才能減少沖突,甚至避免沖突? 時分復用(TDM) 時分復用:將時間分為等長的“…

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm監控配置

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm監控配置 1.Prometheus部署1.2.Prometheus修改默認端口 2.grafana可視化頁面部署3.alertmanager部署4.監控配置4.1.主機監控node-exporter4.2.監控mysql數據庫mysqld_exporter4.3.監控mongod數據庫mongodb_expo…

基于tldextract提取URL里的子域名、主域名、頂級域

TLD是TopLevel Domain的縮寫。?tldextract? 是一個用于從URL中提取子域、主域名和頂級域(TLD)的Python庫。它利用公共后綴列表(Public Suffix List)來確保即使是復雜或不常見的URL結構也能被正確解析。tldextract能夠處理包括IC…

常見Arthas命令與實踐

Arthas 官網:https://arthas.aliyun.com/doc/,官方文檔對 Arthas 的每個命令都做出了介紹和解釋,并且還有在線教程,方便學習和熟悉命令。 Arthas Idea 的 IDEA 插件。 這是一款能快速生成 Arthas命令的插件,可快速生成…

Mellanox ConnectX 系列網卡的雙驅動架構:以太網與 InfiniBand 的協同設計

在現代數據中心和高性能計算(HPC)環境中,網絡硬件的性能和功能至關重要。Mellanox ConnectX 系列網卡以其卓越的性能和多功能性而聞名,支持從傳統的以太網到高性能的 InfiniBand 網絡協議。這種多功能性使得 Mellanox 網卡能夠滿足不同應用場景的需求,從常規的數據中心網絡…

win32匯編環境,對多行編輯框添加或刪除文本

;運行效果 ;win32匯編環境,對多行編輯框添加或刪除文本 ;主要要先設置文本的開始點與結束點,然后把一段文本頂替上去。沒有添加文本或刪除文本的概念,只有頂替。如果開始點與結束點都是前面文本的長度值,則成了從后面添加文本的效果。如果結束…

CSDN年度回顧:技術征途上的堅實步伐

嘿,時光過得可真快呀,就像那匹跑得飛快的白馬,嗖的一下,2024 年的日歷就這么悄無聲息地翻到了最后一頁。這會兒我回頭看看在 CSDN 上度過的這一年,心里那叫一個感慨萬千,滿滿的都是喜悅,就像心里…

泛型子類使用Builder提示:both methods have same erasure, yet neither hides the other

父類 Data Builder AllArgsConstructor NoArgsConstructor public class ParentClass {public String name; } 子類 AllArgsConstructor NoArgsConstructor Data SuperBuilder public class ChildClass<T> extends ParentClass {private T value; } 提示錯誤 builde…

Springboot集成Elasticsearch8.0(ES)版本,采用JAVA Client方式進行連接和實現CRUD操作

本文章介紹了 springboot t集成Elasticsearch8.0(ES)版本,如何通過 AVA Client方式進行連接和實現CRUD操作 在ES7.15版本之后,ES官方將高級客戶端 RestHighLevelClient標記為棄用狀態。同時推出了全新的 Java API客戶端 Elasticsearch Java API Client,該客戶端也將在 Ela…

人臉識別打卡系統--基于QT(附源碼)

逃離舒適區 項目源代碼放在我的倉庫中&#xff0c;有需要自取 項目地址 https://gitcode.com/hujiahangdewa/Face_recognition.git 文章目錄 一、項目結構分析二、服務器的搭建三、客戶端的搭建四、人臉識別庫的申請五、基于人臉識別庫的識別判斷六、QT人臉識別----調用百度ai…

人工智能在數字化轉型中的角色:從數據分析到智能決策

引言 在數字化轉型浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正迅速崛起&#xff0c;成為推動企業創新和變革的關鍵力量。面對日益復雜的市場環境和激烈的行業競爭&#xff0c;企業亟需借助技術手段提高運營效率、優化決策過程&#xff0c;并增強市場競爭力。而AI…

react install

react 安裝 React 是一個用于構建用戶界面的 JavaScript 庫。以下是安裝 React 的步驟&#xff1a; 使用 Create React App Create React App 是一個官方支持的命令行工具&#xff0c;用于快速搭建 React 應用。 安裝 Node.js 和 npm 確保你的計算機上安裝了 Node.js 和 npm…

Android系統開發(二十):字體活起來,安卓自定義字體改造指南

為什么要寫這篇文章&#xff1f; 你是否厭倦了千篇一律的安卓默認字體&#xff1f;想讓你的設備從“乏味的配角”變成“炫酷的主角”&#xff1f;好消息&#xff01;從Android 12到Android 15&#xff0c;自定義字體變得更簡單、更強大。尤其是表情字體的更新&#xff0c;不僅…

django使用踩坑經歷

DRF 使用drf獲取序列化后的id visitor_serializer VisitorSaveSerializer(data{…}) if visitor_serializer.is_valid():visitor visitor_serializer.save() visitor_id visitor.pkpostgrepsql踩坑 django使用postgrepsql&#xff0c;使用聚合函數如:sum 等&#xff0c;被…

ASP.NET Core中 JWT 實現無感刷新Token

在 Web 應用開發中&#xff0c;用戶登錄狀態的管理至關重要。為了避免用戶頻繁遇到登錄過期的問題&#xff0c;我們可以通過實現 JWT&#xff08;JSON Web Token&#xff09;刷新機制來提升用戶體驗 推薦: 使用 Refresh Token&#xff08;雙 Token 機制&#xff09; 1. 生成和…

將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch(3.純python的實惠版)

前情&#xff1a; 將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch&#xff08;1.標準版&#xff09;-CSDN博客 將 AzureBlob 的日志通過 Azure Event Hubs 發給 Elasticsearch&#xff08;2.換掉付費的Event Hubs&#xff09;-CSDN博客 python腳本實現 厲害的…

python學opencv|讀取圖像(四十)掩模:三通道圖像的局部覆蓋

【1】引言 前序學習了使用numpy創建單通道的灰色圖像&#xff0c;并對灰色圖像的局部進行了顏色更改&#xff0c;相關鏈接為&#xff1a; python學opencv|讀取圖像&#xff08;九&#xff09;用numpy創建黑白相間灰度圖_numpy生成全黑圖片-CSDN博客 之后又學習了使用numpy創…

【全面解析】深入解析 TCP/IP 協議:網絡通信的基石

深入解析 TCP/IP 協議&#xff1a;網絡通信的基石 導語 你是否曾好奇&#xff0c;現代互聯網是如何實現全球設備之間的高速、穩定和可靠通信的&#xff1f;無論是瀏覽網頁、發送電子郵件&#xff0c;還是進行視頻通話&#xff0c;背后都離不開 TCP/IP 協議 的支撐。作為互聯網…