使用 Vyper 實現影像邊緣檢測

ttocr、com發表於2024-12-01

Vyper 是一種 Python 虛擬機器(Python Virtual Machine,PVM)上的程式語言,旨在為智慧合約編寫提供一種更安全、更易審計的選擇。它是 Ethereum 智慧合約開發的替代語言之一,採用與 Python 類似的語法,但移除了 Python 中的一些特性,如類和繼承,強化了可讀性和安全性。

雖然 Vyper 主要用於編寫區塊鏈上的智慧合約,但為了展示其在特定任務中的應用,我們將透過它來實現一個影像邊緣檢測的示例,使用 Vyper 編寫的程式碼實現 Sobel 演算法來檢測影像邊緣。雖然 Vyper 並不常用於影像處理領域,但本文將提供一個如何將其用於其他領域的示範。

環境準備
安裝 Vyper 編譯器

由於 Vyper 是為智慧合約編寫設計的,因此可以透過以下命令安裝 Vyper 編譯器:

bash

pip install vyper
安裝完成後,可以透過以下命令來檢查 Vyper 是否安裝成功:

bash

vyper --version
建立 Vyper 檔案

在本地建立一個 .vy 檔案,例如 sobel_edge_detection.vy,並將程式碼放入該檔案中。Vyper 支援類似 Python 的語法,但在智慧合約開發時會有更多安全性和記憶體控制的需求。

Sobel 演算法回顧
Sobel 演算法是透過計算影像的梯度來檢測影像中的邊緣。它使用兩個卷積核來分別計算水平和垂直方向的梯度,之後計算每個畫素點的邊緣強度。

水平 Sobel 卷積核(Gx):

diff

-1 0 1
-2 0 2
-1 0 1
垂直 Sobel 卷積核(Gy):

diff

1 2 1
0 0 0
-1 -2 -1
計算梯度:
對於每個畫素,計算梯度的幅值:

scss

gradient = sqrt(Gx^2 + Gy^2)
Vyper 實現程式碼
在 Vyper 中,我們可以實現簡單的矩陣運算來模擬 Sobel 演算法的功能。由於 Vyper 更適合處理區塊鏈上的智慧合約,本示例將展示如何利用其進行影像處理操作,儘管這是一個不尋常的用途。

Vyper 程式碼實現
vyper

Sobel Edge Detection Algorithm in Vyper

Sobel filters for horizontal (Gx) and vertical (Gy) gradients

Gx: public(array[3][3]int128)
Gy: public(array[3][3]int128)

@public
def init():
# Define the Sobel filters for Gx and Gy
self.Gx = [
[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]
]
self.Gy = [
[ 1, 2, 1],
[ 0, 0, 0],
[-1, -2, -1]
]

This function calculates the gradient magnitude at a given pixel

@public
@constant
def calculate_gradient(image: array[5][5]int128, x: int128, y: int128) -> int128:
gx: int128 = 0
gy: int128 = 0
# Loop over the 3x3 neighborhood for Sobel convolution
for i in range(-1, 2):
for j in range(-1, 2):
# Image indices must be within bounds
xi: int128 = x + i
yi: int128 = y + j
if xi >= 0 and xi < 5 and yi >= 0 and yi < 5:
gx += image[xi][yi] * self.Gx[i + 1][j + 1]
gy += image[xi][yi] * self.Gy[i + 1][j + 1]

# Compute the gradient magnitude using Pythagorean theorem
gradient: int128 = sqrt(gx ** 2 + gy ** 2)
return gradient

This function simulates the image edge detection using Sobel operator

@public
def sobel_edge_detection(image: array[5][5]int128) -> array[5][5]int128:
result: array[5][5]int128
for i in range(1, 4):
for j in range(1, 4):
result[i][j] = self.calculate_gradient(image, i, j)
return result
程式碼解析
Sobel 卷積核

Gx 和 Gy 分別定義了 Sobel 運算元的水平和垂直卷積核,這兩個矩陣用於計算影像的梯度。

calculate_gradient 函式

該函式接收影像矩陣(5x5)和當前畫素的座標 (x, y),透過 Sobel 卷積核計算該畫素的梯度。我們遍歷 3x3 的鄰域,計算水平和垂直方向的梯度,並使用勾股定理計算出該畫素的邊緣強度。

sobel_edge_detection 函式

該函式接受一個 5x5 的影像矩陣,並遍歷影像的內部區域(排除邊界),對每個畫素呼叫 calculate_gradient 函式,返回一個包含邊緣強度的影像。

初始化與公共變數

init 函式初始化了 Sobel 卷積核,並將其儲存在智慧合約的公共變數中。

使用示例
假設我們有以下 5x5 的簡化影像資料:
更多內容訪問ttocr.com或聯絡1436423940

0 10 10 10 0
0 50 50 50 0
0 100 100 100 0
0 150 150 150 0
0 0 0 0 0
使用 Vyper 編寫的智慧合約來處理這個影像資料,並計算每個畫素的邊緣強度。

相關文章