の記事からの続き
気管および気管支の軟骨部分を消去するには、通常、深層学習によるセグメンテーションモデル(例:U-Net、Mask R-CNN)が必要です。ただし、簡易的な方法として画像処理を組み合わせて実装するデモを示します。以下のコードは、気管支の輪郭を検出し、それらの領域を除去する形で動作します。
---
### 必要なライブラリのインストール:
```bash
pip install opencv-python pillow numpy
```
---
## プログラムコード:
```python
import tkinter as tk
from tkinter import filedialog, messagebox
import cv2
import numpy as np
from PIL import Image, ImageTk
# グローバル変数
img = None
processed_img = None
def select_image():
global img, img_display, processed_img
# ファイル選択ダイアログ
file_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.jpeg;*.png")])
if not file_path:
return
# 画像をグレースケールで読み込む
img = cv2.imread(file_path, cv2.IMREAD_GRAYSCALE)
img_display = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) # 表示用に変換
# tkinter表示用に変換
img_display_pil = Image.fromarray(cv2.cvtColor(img_display, cv2.COLOR_BGR2RGB))
img_display_tk = ImageTk.PhotoImage(img_display_pil)
# キャンバスに表示
canvas.create_image(0, 0, anchor=tk.NW, image=img_display_tk)
canvas.image = img_display_tk
def remove_bones_and_cartilage():
global img, processed_img
if img is None:
messagebox.showerror("エラー", "画像を選択してください。")
return
# ステップ1: ヒストグラム平坦化で骨と気管の輪郭を強調
equalized_img = cv2.equalizeHist(img)
# ステップ2: ガウシアンぼかしで不要なノイズを除去
blurred_img = cv2.GaussianBlur(equalized_img, (5, 5), 0)
# ステップ3: 骨・気管軟骨部分の検出(閾値処理)
_, thresholded_img = cv2.threshold(blurred_img, 180, 255, cv2.THRESH_BINARY)
# ステップ4: 気管の輪郭を検出し、マスクを生成
contours, _ = cv2.findContours(thresholded_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
mask = np.zeros_like(img)
# 大きい輪郭のみをマスクとして採用(気管・気管支部分の除去)
for contour in contours:
if cv2.contourArea(contour) > 1000: # 小さすぎる領域を除外
cv2.drawContours(mask, [contour], -1, (255), thickness=cv2.FILLED)
# ステップ5: 元画像から気管および骨部分を除去
mask_inv = cv2.bitwise_not(mask)
processed_img = cv2.bitwise_and(img, img, mask=mask_inv)
# tkinter表示用に変換
processed_pil = Image.fromarray(processed_img)
processed_tk = ImageTk.PhotoImage(processed_pil)
# キャンバスに表示
canvas.create_image(0, 0, anchor=tk.NW, image=processed_tk)
canvas.image = processed_tk
# GUIの初期化
root = tk.Tk()
root.title("X線画像の骨および気管軟骨除去")
root.geometry("800x600")
# キャンバスの作成
canvas = tk.Canvas(root, width=800, height=500, bg="gray")
canvas.pack()
# ボタンの配置
button_frame = tk.Frame(root)
button_frame.pack()
select_button = tk.Button(button_frame, text="画像を選択", command=select_image)
select_button.grid(row=0, column=0, padx=10, pady=10)
process_button = tk.Button(button_frame, text="骨および気管軟骨を除去", command=remove_bones_and_cartilage)
process_button.grid(row=0, column=1, padx=10, pady=10)
# メインループの開始
root.mainloop()
```
---
### 説明:
1. **画像の選択**
- ユーザーが選んだX線画像をキャンバスに表示します。
2. **骨および気管軟骨部分の除去**
- ヒストグラム平坦化とガウシアンぼかしで骨や気管の輪郭を強調。
- 閾値処理で骨や気管部分の領域を二値化し、輪郭を検出します。
- 一定以上のサイズの輪郭のみを選択し、マスクとして除去します。
3. **結果の表示**
- 処理後の画像をキャンバスに再描画します。
---
### 改良ポイント:
このプログラムは画像処理技術を用いた簡易的なデモです。精度を向上させるためには、次のような改良が考えられます:
- **深層学習モデルの導入**
U-NetやMask R-CNNなどのセグメンテーションモデルを使用し、気管や気管支の軟骨を高精度に検出・除去する。
- **データセットの事前学習**
X線画像に特化した大規模なデータセットを用いて事前学習し、骨や気管軟骨のセグメンテーションモデルを構築することで、より正確な結果が期待できます。