1. 程式人生 > >用分割點座標將影象二值化

用分割點座標將影象二值化

最近在做影象分割,找了一些醫學影象資料集,但GroundTruth不是二值圖,而是由座標表示。

如圖:
圖1 座標:以(X, Y)成對存放於txt檔案中
圖1 座標:以(X, Y)成對存放於txt檔案中

原始圖
圖2 原始圖

分割效果
圖3 將座標標註在圖上

由於訓練過程需要將影象分為二值圖,也就是說要將左心室和非左心室分割開來。
opencv有個很好用的函式,可以直接將影象用輪廓座標分割成二值圖。那就是cv2.fillPoly

首先是得到一個掩模(mask),毫無疑問這個mask需要跟原圖一樣的大小。

import numpy as np
import pydicom
import cv2
import matplotlib.pyplot as
plt from PIL import Image raw_dicom = pydicom.dcmread(dicom_dir) #影象為dicom格式,所以用pydicom讀取 dicom_picture = raw_dicom.pixel_array.astype(int) #用pixel_array提取影象資訊。相當於一個畫素值組成的陣列 mask = np.zeros_like(dicom_picture) #將mask定義為一個跟影象一樣大小的零矩陣 coords = np.loadtxt(counter_dir, delimiter=' ').astype('int'
) #將座標以list的形式提取出來 cv2.fillPoly(mask, [coords], 255) #關鍵的一步,用這個函式就可以將輪廓內的部分標記出來。

結果:
這裡寫圖片描述
圖4 原圖

這裡寫圖片描述
圖5 二值圖

還有一個坑的地方,為什麼用255而不是1,我看很多人都用的1,這是方便後續的儲存。解釋一下:
如果用1填充,那麼用plt.imshow(mask, cmap =’gray’)可以將影象顯示出來,但是儲存的時候就是全黑的。我猜測是因為儲存畫素範圍預設為0-255,所以0和1就沒有太大的差別。所以我選用了255來填充。

這樣就可以得到圖中的效果了,但是為了得到二值圖,還需要再轉換一下。我用了PIL中的Image

mask = Image.fromarray(mask)         #mask是一個數組,所以先轉為影象
mask = mask.convert("1")             #convert("1")表示轉為2值圖
scipy.misc.imsave("counter.png", mask)      #最後就是儲存了