Python SimpleITK 水平集

GeodesicActiveContourLevelSetImageFilter是一个水平集图像分割方法,根据已有的初始轮廓,向内/外延伸并找到分割边缘。

输入
  • initial image:初始水平集,即第0层的图像。把初始轮廓代入signed distance function(比如SignedMaurerDistanceMapImageFilter)。这个初始轮廓可以和图像的分割边缘重合或相交。
  • feature image:待分割的原图的边缘图(edge map),通常用gradient计算。在边缘图中,边缘处的值一般接近于0,在分割区域内的值接近于1。
输出

图像矩阵,以正负值区分分割区域的不同区域,0代表边缘/传播面。

# =========================================================================
 #
 #  Copyright NumFOCUS
 #
 #  Licensed under the Apache License, Version 2.0 (the "License");
 #  you may not use this file except in compliance with the License.
 #  You may obtain a copy of the License at
 #
 #         http://www.apache.org/licenses/LICENSE-2.0.txt
 #
 #  Unless required by applicable law or agreed to in writing, software
 #  distributed under the License is distributed on an "AS IS" BASIS,
 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 #
 # =========================================================================
  
from __future__ import print_function
  
import os
import sys
  
import SimpleITK as sitk
  
if len(sys.argv) < 8:
	print("Usage:", sys.argv[0],"<inputImage> <outputImage> <sigma> <InitialDistance>", "<PropagationScaling> <seedX> <seedY> <?seedZ>")
  sys.exit(1)
  
inputImage = sys.argv[1]
outputImage = sys.argv[2]
sigma = float(sys.argv[3])
initialDistance = float(sys.argv[4])
propagationScaling = float(sys.argv[5])
seed = [float(sys.argv[6]), float(sys.argv[7])]
  
if len(sys.argv) > 8:
	seed.append(float(sys.argv[8]))
  
# 读取原始图片(待分割图片)
reader = sitk.ImageFileReader()
reader.SetFileName(inputImage)
image = reader.Execute()

# 使用GradientMagnitudeRecursiveGaussianImageFilter对原图进行处理 -> 得到featureImage
gradientMagnitude = sitk.GradientMagnitudeRecursiveGaussianImageFilter()
gradientMagnitude.SetSigma(sigma)
featureImage = sitk.BoundedReciprocal(gradientMagnitude.Execute(image))

# 得到初始轮廓(mask)
seedImage = sitk.Image(image.GetSize()[0], image.GetSize()[1], sitk.sitkUInt8)
seedImage.SetSpacing(image.GetSpacing())
seedImage.SetOrigin(image.GetOrigin())
seedImage.SetDirection(image.GetDirection())
seedImage[seedImage.TransformPhysicalPointToIndex(seed)] = 1

# 使用SignedMaurerDistanceMapImageFilter对初始轮廓处理 -> 得到initialImage
distance = sitk.SignedMaurerDistanceMapImageFilter()
distance.InsideIsPositiveOff()
distance.UseImageSpacingOn()
initialImage = sitk.BinaryThreshold(distance.Execute(seedImage), -1000, 10)
initialImage = sitk.Cast(initialImage, featureImage.GetPixelID()) * -1 + 0.5

# 进行分割
geodesicActiveContour = sitk.GeodesicActiveContourLevelSetImageFilter()
geodesicActiveContour.SetPropagationScaling(propagationScaling) # 正负值控制扩张方向
geodesicActiveContour.SetCurvatureScaling(.5) # 控制圆滑/smooth程度
geodesicActiveContour.SetAdvectionScaling(1.0)
geodesicActiveContour.SetMaximumRMSError(0.01)
geodesicActiveContour.SetNumberOfIterations(1000)
levelset = geodesicActiveContour.Execute(initialImage, featureImage)
  
print("RMS Change: ", geodesicActiveContour.GetRMSChange())
print("Elapsed Iterations: ", geodesicActiveContour.GetElapsedIterations())
  
contour = sitk.BinaryContour(sitk.BinaryThreshold(levelset, -1000, 0))
  
if ("SITK_NOSHOW" not in os.environ):
  sitk.Show(sitk.LabelOverlay(image, contour), "Levelset Countour")
Reference

“Geodesic Active Contours”, V. Caselles, R. Kimmel and G. Sapiro. International Journal on Computer Vision, Vol 22, No. 1, pp 61-97, 1997

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值