距離變換 Distance Transformation

以下為該學習地址的學習筆記:Distance transformation in image - Python OpenCV - GeeksforGeeks

?其他學習資料:Morphology - Distance Transform

簡介

距離變換是一種用于計算圖像中每個像素與最近的非零像素之間距離的技術。它通常用于圖像分割和物體識別任務,因為它可以幫助識別圖像中物體的邊界。(如下圖片來源于Chamani, H., Rabbani, A., Russell, K. P., Zydney, A. L., Gomez, E. D., Hattrick-Simpers, J., & Werber, J. R. (2023). Rapid reconstruction of 3-D membrane pore structure using a single 2-D Micrograph.?arXiv preprint arXiv:2301.10601.)

1. 距離變換在OpenCV中的實現

OpenCV 中的距離變換函數 cv2.distanceTransform() 接收二值圖像并返回兩個數組:距離圖像和標簽圖像(the distance image and the label image)。距離圖像包含每個像素與最近的非零像素的距離值,標簽圖像包含最近的非零像素的標簽。

#簡單表示一下
dist_transform, labels = cv2.distanceTransform(binary_image, distance_type, mask_size)
  • binary_image: 輸入的二值圖像,非零像素通常表示前景對象。
  • distance_type: 距離類型,可以使用常量如cv2.DIST_L1(曼哈頓距離)或cv2.DIST_L2(歐幾里得距離)。
  • mask_size: 掩碼大小,確定用于計算距離的掩碼的大小,值越大計算越精確但速度越慢。

距離類型

  • cv2.DIST_L1: 曼哈頓距離the Manhattan distance,即只計算水平和垂直方向的距離。
  • cv2.DIST_L2: 歐幾里得距離the Euclidean distance,即計算實際的幾何距離,包含所有方向。

掩碼大小

掩碼大小(mask size)決定了計算距離時使用的鄰域范圍,常用的大小有3、5等。較大的掩碼可以提供更精確的距離值,但計算開銷也會增加。

距離變換的結果

距離變換的結果是一個與原始圖像大小相同的距離圖像,每個像素值表示該像素到最近前景像素的距離。通過這種方式,可以有效地識別圖像中對象的邊界。

距離圖像的歸一化

為了方便可視化,OpenCV提供了cv2.normalize()函數,可以將距離圖像的值歸一化到0到255的范圍內。

歸一化

#簡單表示一下
normalized_dist_transform = cv2.normalize(dist_transform, None, 0, 255, cv2.NORM_MINMAX)
  • dist_transform: 輸入的距離圖像。
  • None: 輸出數組,通常設為None表示原地操作。
  • 0: 歸一化后的最小值。
  • 255: 歸一化后的最大值。
  • cv2.NORM_MINMAX: 歸一化類型,將最小值和最大值歸一化到指定范圍。

除了距離變換函數外,OpenCV 還提供了 cv2.normalize() 函數,用于對距離圖像進行歸一化處理,使距離值在 0 到 255 之間。這對距離圖像的可視化非常有用。

距離變換是一種圖像處理技術,可用于獲取圖像中每個像素與最近的非零像素之間的距離。它常用于圖像分割和物體識別任務。

2. 具體步驟

在 OpenCV 中,我們可以使用 cv2.distanceTransform() 函數執行距離變換。

需要遵循的步驟

  1. 加載圖像:使用 cv2.imread() 函數加載圖像。
  2. 轉換為灰度圖像:使用 cv2.cvtColor() 函數將圖像轉換為灰度圖像。這是因為距離變換函數僅適用于單通道圖像
  3. 創建二值圖像:進行閾值處理,使用cv2.threshold()函數對圖像進行二值化,將像素強度值大于某個閾值的像素設為255,其他像素設為0。
  4. 計算距離變換:使用cv2.distanceTransform()函數計算每個像素到最近非零像素的距離。該函數接受三個參數:二值圖像、距離類型(如cv2.DIST_L2表示歐幾里得距離)和掩碼大小(如3表示3×3掩碼)。
  5. 返回結果:距離變換函數返回兩個數組:距離圖像和標簽圖像。距離圖像包含每個像素與最近的非零像素的距離值,標簽圖像包含最近的非零像素的標簽。

3. 示例

3.1 示例 1

import cv2  # 導入OpenCV庫# 加載圖像
# 你可以提供圖像的路徑
image = cv2.imread(r"Mandala.jpg")  # 讀取圖像文件"Mandala.jpg"# 將圖像轉換為灰度圖像
grayScaleImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 將彩色圖像轉換為灰度圖像# 對圖像進行二值化處理,創建二值圖像
_, threshold = cv2.threshold(grayScaleImage, 123, 255, cv2.THRESH_BINARY)  # 將灰度圖像進行二值化,閾值為123# 計算距離變換
# distTransform = cv2.distanceTransform(threshold, cv2.DIST_C, 3)  # 使用Chebyshev距離計算距離變換
# distTransform= cv2.distanceTransform(threshold, cv2.DIST_L1, 3)  # 使用曼哈頓距離計算距離變換
distTransform= cv2.distanceTransform(threshold, cv2.DIST_L2, 3)  # 使用歐幾里得距離計算距離變換# 顯示距離變換后的圖像
cv2.imshow('Transformed Distance Image1', distTransform)  # 顯示距離變換后的圖像# 按任意鍵結束進程
cv2.waitKey(0)  # 等待按鍵輸入
cv2.destroyAllWindows()  # 銷毀所有窗口# 保存距離變換后的圖像
cv2.imwrite('distTransformed.jpg', distTransform)  # 將距離變換后的圖像保存為"distTransformed.jpg"

此代碼的輸出將是一個包含距離圖像的窗口,其中每個像素包含與最近非零像素的距離值。距離值的范圍為 0 到 255,值越大表示距離越大。

3.2 示例2(標簽圖像)

下面是OpenCV中距離變換的第二個示例代碼,演示了如何使用標簽圖像獲取圖像中每個像素的最近非零像素的坐標:

# importing necessary libraries 
# 導入必要的庫
import cv2  # 導入OpenCV庫
import numpy as np  # 導入NumPy庫,用于數組操作# Load the image 
# you can specify the path to image 
# 加載圖像
# 你可以指定圖像的路徑
image = cv2.imread(r"Visual_arts.jpg")  # 讀取圖像文件"Visual_arts.jpg"# Convert the image to grayscale 
# 使用cv2.cvtColor()函數將圖像轉換為灰度圖像
grayScaleImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Threshold the image to create a binary image 
# 使用cv2.threshold()函數對灰度圖像進行二值化處理,創建二值圖像
_, threshold = cv2.threshold(grayScaleImage, 127, 255, cv2.THRESH_BINARY) # Calculate the distance transform 
# 使用cv2.distanceTransform()函數計算二值圖像的距離變換
dist, labels, *other_vars = cv2.distanceTransform(threshold, cv2.DIST_L2, 3) # Find the coordinates of the nearest non-zero pixels for each pixel in the image 
# 使用np.where()和np.column_stack()函數找到每個像素的最近非零像素的坐標
coords = np.column_stack(np.where(labels > 0)) # Print the coordinates 
# squeeze is used to remove the undesired dimension 
# 打印坐標
# 使用squeeze()函數去除不需要的維度
print(coords.squeeze())

輸出:

[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1718 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 3536 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 5354 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 7172 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 8990 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143144 151 152 156 157 158 159 160 161 162 163 167 168 169 170 171 172 179180 200 201 202 203 204 240 241 242 243 244 254 255 256 257 287 290 297]

代碼片段補充介紹

_, threshold = cv2.threshold(grayScaleImage, 127, 255, cv2.THRESH_BINARY)
  • _:這個下劃線通常用作占位符,表示在此處接收一個值但不需要使用它。在這里,它用于接收cv2.threshold()函數返回的第一個返回值,即閾值化操作后的閾值(threshold),但實際上在后續代碼中并沒有使用這個值。
  • threshold:這是一個變量名,用于接收cv2.threshold()函數返回的第二個返回值,即二值化后的圖像。這是我們感興趣的結果,它是一個灰度圖像,其中像素值只有兩種可能:0(黑色,表示背景)和255(白色,表示前景)。
  • cv2.THRESH_BINARY:這是cv2.threshold()函數的一個參數,用于指定閾值化類型。cv2.THRESH_BINARY表示二值閾值化類型,即將大于閾值的像素設置為一個值(這里是255),小于或等于閾值的像素設置為另一個值(這里是0)。
dist, labels, *other_vars = cv2.distanceTransform(threshold, cv2.DIST_L2, 3)
  • dist:這是一個變量名,用于接收cv2.distanceTransform()函數返回的第一個數組,即距離圖像(distance image)。距離圖像包含了每個像素到最近非零像素的距離值。
  • labels:這是一個變量名,用于接收cv2.distanceTransform()函數返回的第二個數組,即標簽圖像(label image)。標簽圖像包含了每個像素所屬的最近非零像素的標簽。
  • other_vars:這個是Python中的可變參數形式,用于接收cv2.distanceTransform()函數可能返回的額外的參數。在這個特定的情況下,cv2.distanceTransform()函數實際上只返回兩個值(距離圖像和標簽圖像),所以other_vars在這里實際上是一個空列表,因為沒有額外的參數需要接收。
  • cv2.distanceTransform():這是OpenCV庫中的一個函數,用于計算圖像的距離變換。它接受以下參數:
    • threshold:輸入的二值化圖像,這里是前面閾值化得到的二值圖像。
    • cv2.DIST_L2:距離的類型,這里選擇歐幾里得距離(L2范數),表示每個像素到最近非零像素的歐幾里得距離。
    • 3:掩碼大小,即用于計算距離的卷積核的大小,這里是3×3的卷積核。

補充掩碼

  • 控制掩碼的大小和形狀可以影響操作的結果,例如在距離變換中,掩碼的大小決定了計算每個像素到最近非零像素距離的精度和效率。
  • 在距離變換中,掩碼用于計算每個像素到最近非零像素的距離。通常使用的掩碼大小是一個正方形(3×3、5×5等),它定義了像素周圍的鄰域。
coords = np.column_stack(np.where(labels > 0)) 

np.where(labels > 0)

  • labels > 0:這是一個條件表達式,返回一個布爾類型的數組,數組的每個元素都是 labels 中對應位置的像素值是否大于0的判斷結果。如果 labels 中的像素值大于0,則對應位置為True,否則為False。
  • np.where():這是一個NumPy函數,用于根據指定的條件返回符合條件的元素的索引。它可以接受一個條件表達式作為參數,并返回一個包含符合條件元素索引的元組。
    • 如果條件表達式是一個二維數組,np.where() 返回的是一個包含兩個一維數組的元組,分別代表符合條件的行索引和列索引。
    • 如果條件表達式是一個一維數組,np.where() 直接返回符合條件的元素的索引。

在這里,np.where(labels > 0) 返回的是一個元組,其中包含了 labels 中大于0的像素點的索引。

np.column_stack()

  • np.column_stack():這是NumPy函數,用于將多個一維數組按列堆疊成一個二維數組。它接受一個元組或列表作為參數,參數中的每個元素是一個一維數組。

在這里,np.column_stack(np.where(labels > 0)) 接受了 np.where(labels > 0) 返回的元組作為參數,將其中的每個一維數組按列堆疊成一個二維數組。因為 np.where(labels > 0) 返回的是一個包含行索引和列索引的元組,所以 np.column_stack() 的作用是將這兩個一維數組按列排列成一個二維數組,即將行索引和列索引對應堆疊在一起。

coords

  • coords:這是一個變量名,用于接收 np.column_stack(np.where(labels > 0)) 的結果。它表示了所有 labels 中大于0的像素點的坐標。

綜合起來,coords = np.column_stack(np.where(labels > 0)) 這行代碼的作用是找到 labels 圖像中所有像素值大于0的像素點的坐標,并將這些坐標按列堆疊成一個二維數組,存儲在 coords 變量中。

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

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

相關文章

51單片機5(GPIO簡介)

一、序言:不論學習什么單片機,最簡單的外設莫過于I口的高低電平的操作,接下來,我們將給大家介紹一下如何在創建好的工程模板上面,通過控制51單片機的GPIO來使我們的開發板上的LED來點亮。 二、51單片機GPIO介紹&#…

第三節SHELL腳本中的變量與運算(1.1-1.5)

一,腳本中的變量 1,1什么是變量 在編寫程序是,通常會遇到被操作對象不固定的情況我們需要用一串固定的字符來的表示不固定的值,這就是變量存在的根本意義變量的實現原理就是內存存儲單元的一個符合名稱 1,2 變量的命名規則 變量的名稱中只能包含數字,大小寫字母以及下劃線 …

PySide在Qt Designer中使用QTableView 顯示表格數據

在 PySide6 中,可以使用 Qt Model View 架構中的 QTableView 部件來顯示和編輯表格數據。 1、創建ui文件 在Qt Designer中新建QMainWindow,命名為csvShow.ui。QMainWindow上有兩個部件:tableview和btn_exit。 2、使用pyuic工具將ui文件轉換為…

Kafka(四) Consumer消費者

一,基礎知識 1,消費者與消費組 每個消費者都有對應的消費組,不同消費組之間互不影響。 Partition的消息只能被一個消費組中的一個消費者所消費, 但Partition也可能被再平衡分配給新的消費者。 一個Topic的不同Partition會根據分配…

MySQL集群、Redis集群、RabbitMQ集群

一、MySQL集群 1、集群原理 MySQL-MMM 是 Master-Master Replication Manager for MySQL(mysql 主主復制管理器)的簡稱。腳本)。MMM 基于 MySQL Replication 做的擴展架構,主要用來監控 mysql 主主復制并做失敗轉移。其原理是將真…

環境變量在Gradle中的妙用:構建自動化的秘訣

環境變量在Gradle中的妙用:構建自動化的秘訣 在構建自動化的過程中,環境變量扮演著至關重要的角色。它們允許開發者根據不同的運行環境(如開發、測試和生產環境)來調整配置,而無需修改代碼。Gradle,作為一…

基于Faster R-CNN的安全帽目標檢測

基于Faster R-CNN的安全帽目標檢測項目通常旨在解決工作場所,特別是建筑工地的安全監管問題。這類項目使用計算機視覺技術,特別是深度學習中的Faster R-CNN算法,來自動檢測工人是否正確佩戴了安全帽,從而確保遵守安全規定并減少事…

實驗一:圖像信號的數字化

目錄 一、實驗目的 二、實驗原理 三、實驗內容 四、源程序及結果 源程序(python): 結果: 五、結果分析 一、實驗目的 通過本實驗了解圖像的數字化過程,了解數字圖像的數據矩陣表示法。掌握取樣(象素個…

用Python爬蟲能實現什么?得到什么?

Python爬蟲是一種強大的工具,可以用來自動化地從互聯網上抓取數據和信息。使用Python實現爬蟲可以達成多種目的,包括但不限于以下幾個方面: 數據收集: 網頁內容抓取:可以抓取網頁上的文本、圖片、視頻等內容。搜索引擎…

Linux 網絡配置與連接

一、網絡配置 1.1 ifconfig 網卡配置查詢 ifconfig #查看所有啟動的網絡接口信息 ifconfig 指定的網卡 #查看指定網絡接口信息 1.2 修改網絡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 #ens33網絡配置文…

【電源拓撲】反激拓撲

目錄 工作模式 固定頻率 CCM連續電流模式 DCM不連續電流模式 可變頻率 CRM電流臨界模式 反激電源CRM工作模式為什么要跳頻 反激電源應用場景 為什么反激電源功率做不大 電感電流爬升 反激變壓器的限制條件 精通反激電源設計的關鍵-反激電源變壓器設計 反激電源變壓…

MySQL 事務與鎖

事務ACID特性 原子性:事務要么同時成功,要么同時失敗,事務的原子性通過undo log日志保證 一致性:業務代碼要拋出報錯,讓數據庫回滾 隔離性:事務并發執行時,他們內部操作不能互相干擾 持久性&…

Python 讀取esxi上所有主機的設備信息

(主要是為了統計所有虛擬機的設備名稱和所屬主機) 代碼: from pyVim import connect from pyVmomi import vim import ssldef get_vm_devices(vm):devices []try:if vm.config is not None and hasattr(vm.config, hardware) and hasattr(v…

SpringBoot解決Apache Tomcat輸入驗證錯誤漏洞

Apache Tomcat是美國阿帕奇(Apache)基金會的一款輕量級Web應用服務器。該程序實現了對Servlet和JavaServer Page(JSP)的支持。 Apache Tomcat存在輸入驗證錯誤漏洞,該漏洞源于HTTP/2請求的輸入驗證不正確,會…

postgresql簡單導出數據與手動本地恢復(小型數據庫)

問題 需要每天手動備份postgresql。 步驟 導出數據 /opt/homebrew/opt/postgresql16/bin/pg_dump --file/Users/zhangyalin/backup_sql/<IP地址>_pg-2024_07_15_17_30_15-dump.sql --dbname<數據庫名> --username<用戶名> --host<IP地址> --port54…

Day53:圖論 島嶼數量 島嶼的最大面積

99. 島嶼數量 時間限制&#xff1a;1.000S 空間限制&#xff1a;256MB 題目描述 給定一個由 1&#xff08;陸地&#xff09;和 0&#xff08;水&#xff09;組成的矩陣&#xff0c;你需要計算島嶼的數量。島嶼由水平方向或垂直方向上相鄰的陸地連接而成&#xff0c;并且四周…

低空經濟持續發熱,無人機培訓考證就業市場及前景剖析

隨著科技的不斷進步和社會需求的日益增長&#xff0c;低空經濟已成為全球及我國經濟增長的新引擎。作為低空經濟的重要組成部分&#xff0c;無人機技術因其廣泛的應用領域和顯著的經濟效益&#xff0c;受到了社會各界的廣泛關注。為滿足市場對無人機人才的需求&#xff0c;無人…

深入剖析 Android 開源庫 EventBus 的源碼詳解

文章目錄 前言一、EventBus 簡介EventBus 三要素EventBus 線程模型 二、EventBus 使用1.添加依賴2.EventBus 基本使用2.1 定義事件類2.2 注冊 EventBus2.3 EventBus 發起通知 三、EventBus 源碼詳解1.Subscribe 注解2.注冊事件訂閱方法2.1 EventBus 實例2.2 EventBus 注冊2.2.1…

夢想CAD在線預覽編輯功能

1.最近有個需求&#xff0c;在web系統里進行在線進行CAD預覽和編輯&#xff0c;這里用的是夢想CAD實現此功能&#xff0c;夢想CAD官網文檔 2.CAD預覽&#xff0c;需要需要對CAD文件格式進行轉化&#xff0c;將dwg文件格式轉化為mxweb格式&#xff0c;再進行調用夢想CAD里的打開…

ipynb轉換為pdf、Markdown(.md)

Jupyter Notebook 文件&#xff08;.ipynb&#xff09;可以轉換成多種數據格式&#xff0c;以適應不同的使用場景和需求。以下是幾種常見的轉換格式及其簡潔描述&#xff1a; HTML: Jupyter Notebook可以直接導出為靜態的網頁&#xff08;HTML&#xff09;格式&#xff0c;這樣…