使用 Fantom 實現影像邊緣檢測

ttocr、com發表於2024-11-27

Fantom 本身沒有直接支援影像處理的庫,所以我們會利用 Java 的影像處理庫來實現邊緣檢測。由於 Fantom 可以與 Java 庫進行互操作,我們將透過 Java 的影像處理功能進行實現。

環境準備
安裝 Fantom:訪問 Fantom 官方網站下載並安裝 Fantom 編譯器。
設定 Java 環境:確保系統上已經安裝了 Java 環境。
Fantom 程式碼實現

using fan.sys._
using fan.java._

class ImageEdgeDetection {
更多內容訪問ttocr.com或聯絡1436423940
// 載入影像
static Void loadImage(Str path) {
try {
// 使用 Java 影像處理庫載入影像
var image = java.awt.Image.read(path)
return image
} catch (e: Exception) {
Console.out.println("Error loading image: " + e.toStr)
return null
}
}

// 轉換為灰度影像
static Void toGray(java.awt.Image image) {
try {
var width = image.width
var height = image.height
var grayImage = java.awt.Image.new(width, height)

  for (i in 0..<width) {
    for (j in 0..<height) {
      var pixel = image.getRGB(i, j)
      var r = (pixel >> 16) & 0xFF
      var g = (pixel >> 8) & 0xFF
      var b = pixel & 0xFF
      
      var gray = (r + g + b) / 3
      var grayPixel = (gray << 16) | (gray << 8) | gray
      grayImage.setRGB(i, j, grayPixel)
    }
  }
  return grayImage
} catch (e: Exception) {
  Console.out.println("Error converting to gray: " + e.toStr)
  return null
}

}

// 應用 Sobel 運算元進行邊緣檢測
static Void applySobel(java.awt.Image grayImage) {
try {
var width = grayImage.width
var height = grayImage.height
var sobelImage = java.awt.Image.new(width, height)

  // Sobel 運算元
  var sobelX = [-1, 0, 1, -2, 0, 2, -1, 0, 1]
  var sobelY = [-1, -2, -1, 0, 0, 0, 1, 2, 1]
  
  for (x in 1..<width-1) {
    for (y in 1..<height-1) {
      var gx = 0
      var gy = 0
      
      for (dx in 0..<3) {
        for (dy in 0..<3) {
          var pixel = grayImage.getRGB(x + dx - 1, y + dy - 1) & 0xFF
          gx += pixel * sobelX[dx * 3 + dy]
          gy += pixel * sobelY[dx * 3 + dy]
        }
      }
      
      var edgeMagnitude = Math.sqrt(gx * gx + gy * gy).toInt
      if (edgeMagnitude > 255) edgeMagnitude = 255
      var edgePixel = (edgeMagnitude << 16) | (edgeMagnitude << 8) | edgeMagnitude
      sobelImage.setRGB(x, y, edgePixel)
    }
  }
  return sobelImage
} catch (e: Exception) {
  Console.out.println("Error applying Sobel: " + e.toStr)
  return null
}

}

// 儲存處理後的影像
static Void saveImage(java.awt.Image image, Str path) {
try {
java.awt.Image.write(image, path)
Console.out.println("Image saved to: " + path)
} catch (e: Exception) {
Console.out.println("Error saving image: " + e.toStr)
}
}

// 主程式
static Void main() {
var inputImage = "input_image.jpg"
var outputImage = "output_image.jpg"

// 載入影像
var image = loadImage(inputImage)
if (image == null) return

// 轉換為灰度圖
var grayImage = toGray(image)
if (grayImage == null) return

// 應用 Sobel 運算元進行邊緣檢測
var sobelImage = applySobel(grayImage)
if (sobelImage == null) return

// 儲存影像
saveImage(sobelImage, outputImage)

}
}
步驟解析
載入影像:

透過 Java 庫中的 Image.read() 函式載入影像。Fantom 透過 fan.java 包與 Java 庫互動來讀取影像。
灰度影像轉換:

透過遍歷影像的每個畫素並計算其平均 RGB 值,將彩色影像轉換為灰度影像。
應用 Sobel 運算元:

定義 Sobel 運算元並透過卷積操作對影像應用邊緣檢測。我們透過遍歷影像的畫素來計算其梯度。
儲存影像:

使用 Image.write() 函式將處理後的影像儲存到本地。
執行程式
編譯並執行:
在 Fantom 環境中編譯並執行程式。
影像將經過邊緣檢測處理,最終儲存為 output_image.jpg。
示例輸出
執行程式後,輸入影像將經過 Sobel 運算元處理,輸出影像將顯示出影像的邊緣部分,突出顯示影像中的主要特徵。

相關文章