码迷,mamicode.com
首页 > 其他好文 > 详细

三维血管重建

时间:2017-10-27 23:52:10      阅读:276      评论:0      收藏:0      [点我收藏+]

标签:imp   ==   shape   max   tool   color   images   radius   结果   

原始图片数据如下(共100张):

技术分享

如何求每个界面的最大内圆?求每幅图片中阴影各点到阴影边界的最小距离中的最大距离即为最大内圆的半径,通过这种思路可得到内圆圆心位置和半径,代码实现:

#coding=utf-8
import matplotlib.pyplot as plt
from skimage import io
import math
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
# 在画3D的时候需要

def transfer_data(image_path):
    # get center points
    img = io.imread(image_path)
    points = []     # 存放图片中阴影的点信息
    bound = []      # 存放图片中阴影的边界点信息
    for x in range(img.shape[0]):
        for y in range(img.shape[1]):
            if img[x, y] == 0:
                points.append([x, y])  # 阴影点
                # 判断是否为阴影的边界
                if img[x - 1, y] > 0 or img[x + 1, y] > 0 or img[x, y - 1] > 0 or img[x, y + 1] > 0:
                    bound.append([x, y])  # 阴影边界
    return points, bound


def get_center_radius(image_path):
    points, bound = transfer_data(image_path)
    radius_list = []
    for point in points:
        min_radius = 1000
        for bound_point in bound:
            if min_radius <= 0:
                min_radius = 0
                break
            # 求阴影点到阴影边界的最小距离
            distance = math.sqrt((bound_point[0] - point[0]) ** 2
                                 + (bound_point[1] - point[1]) ** 2)
            if distance < min_radius:
                min_radius = distance

        radius_list.append([point[0], point[1], min_radius])
    max_radius = [0, 0, 0]
    # 在所有阴影点离边界的最小距离中求取最大距离,即为内圆半径
    for ele in radius_list:
        if ele[2] > max_radius[2]:
            max_radius = ele
    return max_radius

def parse_images():
    center_radius = []
    for i in range(100):
        image_path = images/+str(i)+.bmp
        temp = get_center_radius(image_path)
        center_radius.append({index: i, data: temp})
        print(image_path, temp)
    return center_radius

# 求出了100个离散的中心点
center_radius = parse_images()
print(center_radius)

求出结果为:

center_radius = [{index: 0, data: [95, 256, 29.0]}, {index: 1, data: [95, 256, 29.0]}, {index: 2, data: [95, 256, 29.0]}, {index: 3, data: [95, 256, 29.0]}, {index: 4, data: [95, 256, 29.0]}, {index: 5, data: [95, 256, 29.0]}, {index: 6, data: [95, 256, 28.861739379323623]}, {index: 7, data: [95, 257, 29.0]}, {index: 8, data: [95, 257, 29.0]}, {index: 9, data: [95, 257, 29.0]}, {index: 10, data: [95, 257, 29.0]}, {index: 11, data: [95, 258, 29.0]}, {index: 12, data: [95, 258, 29.0]}, {index: 13, data: [95, 258, 29.0]}, {index: 14, data: [95, 259, 29.0]}, {index: 15, data: [95, 260, 29.0]}, {index: 16, data: [95, 260, 29.0]}, {index: 17, data: [95, 261, 29.0]}, {index: 18, data: [95, 262, 29.0]}, {index: 19, data: [95, 263, 29.0]}, {index: 20, data: [94, 266, 29.0]}, {index: 21, data: [94, 267, 29.0]}, {index: 22, data: [94, 268, 29.0]}, {index: 23, data: [95, 267, 29.0]}, {index: 24, data: [95, 276, 29.017236257093817]}, {index: 25, data: [95, 275, 29.017236257093817]}, {index: 26, data: [95, 275, 29.017236257093817]}, {index: 27, data: [96, 285, 29.068883707497267]}, {index: 28, data: [96, 285, 29.068883707497267]}, {index: 29, data: [96, 284, 29.068883707497267]}, {index: 30, data: [97, 291, 29.120439557122072]}, {index: 31, data: [97, 291, 29.154759474226502]}, {index: 32, data: [97, 291, 29.120439557122072]}, {index: 33, data: [97, 291, 29.120439557122072]}, {index: 34, data: [98, 296, 29.120439557122072]}, {index: 35, data: [98, 296, 29.120439557122072]}, {index: 36, data: [99, 300, 29.120439557122072]}, {index: 37, data: [100, 304, 29.120439557122072]}, {index: 38, data: [104, 316, 29.154759474226502]}, {index: 39, data: [104, 316, 29.154759474226502]}, {index: 40, data: [106, 321, 29.154759474226502]}, {index: 41, data: [118, 344, 29.154759474226502]}, {index: 42, data: [115, 339, 29.154759474226502]}, {index: 43, data: [115, 339, 29.154759474226502]}, {index: 44, data: [120, 347, 29.410882339705484]}, {index: 45, data: [120, 347, 29.410882339705484]}, {index: 46, data: [120, 347, 29.410882339705484]}, {index: 47, data: [137, 368, 29.698484809834994]}, {index: 48, data: [136, 367, 29.698484809834994]}, {index: 49, data: [136, 367, 29.698484809834994]}, {index: 50, data: [137, 368, 29.698484809834994]}, {index: 51, data: [137, 368, 29.698484809834994]}, {index: 52, data: [138, 369, 29.698484809834994]}, {index: 53, data: [140, 371, 29.698484809834994]}, {index: 54, data: [144, 375, 29.410882339705484]}, {index: 55, data: [152, 382, 29.206163733020468]}, {index: 56, data: [156, 385, 29.206163733020468]}, {index: 57, data: [183, 402, 29.410882339705484]}, {index: 58, data: [183, 402, 29.410882339705484]}, {index: 59, data: [185, 403, 29.154759474226502]}, {index: 60, data: [196, 408, 29.154759474226502]}, {index: 61, data: [199, 409, 29.120439557122072]}, {index: 62, data: [204, 411, 29.120439557122072]}, {index: 63, data: [236, 419, 29.154759474226502]}, {index: 64, data: [236, 419, 29.154759474226502]}, {index: 65, data: [236, 419, 29.154759474226502]}, {index: 66, data: [230, 418, 29.120439557122072]}, {index: 67, data: [236, 419, 29.068883707497267]}, {index: 68, data: [294, 419, 29.068883707497267]}, {index: 69, data: [286, 420, 29.068883707497267]}, {index: 70, data: [299, 418, 29.120439557122072]}, {index: 71, data: [294, 419, 29.154759474226502]}, {index: 72, data: [299, 418, 29.120439557122072]}, {index: 73, data: [299, 418, 29.120439557122072]}, {index: 74, data: [299, 418, 29.120439557122072]}, {index: 75, data: [331, 409, 29.154759474226502]}, {index: 76, data: [331, 409, 29.154759474226502]}, {index: 77, data: [343, 404, 29.154759474226502]}, {index: 78, data: [343, 404, 29.154759474226502]}, {index: 79, data: [372, 387, 29.206163733020468]}, {index: 80, data: [372, 387, 29.206163733020468]}, {index: 81, data: [387, 375, 29.410882339705484]}, {index: 82, data: [387, 375, 29.68164415931166]}, {index: 83, data: [387, 375, 29.68164415931166]}, {index: 84, data: [388, 374, 29.68164415931166]}, {index: 85, data: [400, 362, 29.68164415931166]}, {index: 86, data: [401, 361, 29.68164415931166]}, {index: 87, data: [401, 361, 29.410882339705484]}, {index: 88, data: [401, 361, 29.206163733020468]}, {index: 89, data: [407, 354, 29.206163733020468]}, {index: 90, data: [413, 346, 29.154759474226502]}, {index: 91, data: [413, 346, 29.154759474226502]}, {index: 92, data: [431, 314, 29.154759474226502]}, {index: 93, data: [431, 314, 29.154759474226502]}, {index: 94, data: [433, 309, 29.154759474226502]}, {index: 95, data: [433, 309, 29.120439557122072]}, {index: 96, data: [436, 301, 29.120439557122072]}, {index: 97, data: [437, 298, 29.120439557122072]}, {index: 98, data: [439, 291, 29.120439557122072]}, {index: 99, data: [440, 287, 29.120439557122072]}]

说明:在结果中的index表示原始图片的序号,data表示图片内圆的圆心坐标和圆半径

{‘index‘: 0, ‘data‘: [95, 256, 29.0]}

表示图片0.bmp的圆心坐标为(95, 256) 半径为29.0

#coding=utf-8
import matplotlib.pyplot as plt
from skimage import io
import math
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
# 在画3D的时候需要

# 使用100个离散的中心点,采用曲线拟合方式,得出x(z)与y(z)的曲线
center_radius = [{index: 0, data: [95, 256, 29.0]}, {index: 1, data: [95, 256, 29.0]}, {index: 2, data: [95, 256, 29.0]}, {index: 3, data: [95, 256, 29.0]}, {index: 4, data: [95, 256, 29.0]}, {index: 5, data: [95, 256, 29.0]}, {index: 6, data: [95, 256, 28.861739379323623]}, {index: 7, data: [95, 257, 29.0]}, {index: 8, data: [95, 257, 29.0]}, {index: 9, data: [95, 257, 29.0]}, {index: 10, data: [95, 257, 29.0]}, {index: 11, data: [95, 258, 29.0]}, {index: 12, data: [95, 258, 29.0]}, {index: 13, data: [95, 258, 29.0]}, {index: 14, data: [95, 259, 29.0]}, {index: 15, data: [95, 260, 29.0]}, {index: 16, data: [95, 260, 29.0]}, {index: 17, data: [95, 261, 29.0]}, {index: 18, data: [95, 262, 29.0]}, {index: 19, data: [95, 263, 29.0]}, {index: 20, data: [94, 266, 29.0]}, {index: 21, data: [94, 267, 29.0]}, {index: 22, data: [94, 268, 29.0]}, {index: 23, data: [95, 267, 29.0]}, {index: 24, data: [95, 276, 29.017236257093817]}, {index: 25, data: [95, 275, 29.017236257093817]}, {index: 26, data: [95, 275, 29.017236257093817]}, {index: 27, data: [96, 285, 29.068883707497267]}, {index: 28, data: [96, 285, 29.068883707497267]}, {index: 29, data: [96, 284, 29.068883707497267]}, {index: 30, data: [97, 291, 29.120439557122072]}, {index: 31, data: [97, 291, 29.154759474226502]}, {index: 32, data: [97, 291, 29.120439557122072]}, {index: 33, data: [97, 291, 29.120439557122072]}, {index: 34, data: [98, 296, 29.120439557122072]}, {index: 35, data: [98, 296, 29.120439557122072]}, {index: 36, data: [99, 300, 29.120439557122072]}, {index: 37, data: [100, 304, 29.120439557122072]}, {index: 38, data: [104, 316, 29.154759474226502]}, {index: 39, data: [104, 316, 29.154759474226502]}, {index: 40, data: [106, 321, 29.154759474226502]}, {index: 41, data: [118, 344, 29.154759474226502]}, {index: 42, data: [115, 339, 29.154759474226502]}, {index: 43, data: [115, 339, 29.154759474226502]}, {index: 44, data: [120, 347, 29.410882339705484]}, {index: 45, data: [120, 347, 29.410882339705484]}, {index: 46, data: [120, 347, 29.410882339705484]}, {index: 47, data: [137, 368, 29.698484809834994]}, {index: 48, data: [136, 367, 29.698484809834994]}, {index: 49, data: [136, 367, 29.698484809834994]}, {index: 50, data: [137, 368, 29.698484809834994]}, {index: 51, data: [137, 368, 29.698484809834994]}, {index: 52, data: [138, 369, 29.698484809834994]}, {index: 53, data: [140, 371, 29.698484809834994]}, {index: 54, data: [144, 375, 29.410882339705484]}, {index: 55, data: [152, 382, 29.206163733020468]}, {index: 56, data: [156, 385, 29.206163733020468]}, {index: 57, data: [183, 402, 29.410882339705484]}, {index: 58, data: [183, 402, 29.410882339705484]}, {index: 59, data: [185, 403, 29.154759474226502]}, {index: 60, data: [196, 408, 29.154759474226502]}, {index: 61, data: [199, 409, 29.120439557122072]}, {index: 62, data: [204, 411, 29.120439557122072]}, {index: 63, data: [236, 419, 29.154759474226502]}, {index: 64, data: [236, 419, 29.154759474226502]}, {index: 65, data: [236, 419, 29.154759474226502]}, {index: 66, data: [230, 418, 29.120439557122072]}, {index: 67, data: [236, 419, 29.068883707497267]}, {index: 68, data: [294, 419, 29.068883707497267]}, {index: 69, data: [286, 420, 29.068883707497267]}, {index: 70, data: [299, 418, 29.120439557122072]}, {index: 71, data: [294, 419, 29.154759474226502]}, {index: 72, data: [299, 418, 29.120439557122072]}, {index: 73, data: [299, 418, 29.120439557122072]}, {index: 74, data: [299, 418, 29.120439557122072]}, {index: 75, data: [331, 409, 29.154759474226502]}, {index: 76, data: [331, 409, 29.154759474226502]}, {index: 77, data: [343, 404, 29.154759474226502]}, {index: 78, data: [343, 404, 29.154759474226502]}, {index: 79, data: [372, 387, 29.206163733020468]}, {index: 80, data: [372, 387, 29.206163733020468]}, {index: 81, data: [387, 375, 29.410882339705484]}, {index: 82, data: [387, 375, 29.68164415931166]}, {index: 83, data: [387, 375, 29.68164415931166]}, {index: 84, data: [388, 374, 29.68164415931166]}, {index: 85, data: [400, 362, 29.68164415931166]}, {index: 86, data: [401, 361, 29.68164415931166]}, {index: 87, data: [401, 361, 29.410882339705484]}, {index: 88, data: [401, 361, 29.206163733020468]}, {index: 89, data: [407, 354, 29.206163733020468]}, {index: 90, data: [413, 346, 29.154759474226502]}, {index: 91, data: [413, 346, 29.154759474226502]}, {index: 92, data: [431, 314, 29.154759474226502]}, {index: 93, data: [431, 314, 29.154759474226502]}, {index: 94, data: [433, 309, 29.154759474226502]}, {index: 95, data: [433, 309, 29.120439557122072]}, {index: 96, data: [436, 301, 29.120439557122072]}, {index: 97, data: [437, 298, 29.120439557122072]}, {index: 98, data: [439, 291, 29.120439557122072]}, {index: 99, data: [440, 287, 29.120439557122072]}]
z_index = []
x_index = []
y_index = []
r_list = []
for item in center_radius:
    z_index.append(item[index])
    x_index.append(item[data][0])
    y_index.append(item[data][1])
    r_list.append(item[data][2])

radius = sum(r_list) / len(r_list)
# 采用多项式进行拟合x(z)与y(z)
z_array = np.array(z_index)
x_array = np.array(x_index)
y_array = np.array(y_index)

times = 3
x_z_p = np.polyfit(z_array, x_array, times)  # 用3次多项式拟合
y_z_p = np.polyfit(z_array, y_array, times)  # 用3次多项式拟合
x_z_func = np.poly1d(x_z_p)
y_z_func = np.poly1d(y_z_p)

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=3d)
ax.plot(x_array, y_array, z_array)  # 画三维曲线

z_array = np.arange(0, 100, 0.01)
xvals = x_z_func(z_array)
yvals = y_z_func(z_array)
ax.plot(xvals, yvals, z_array, r., markersize=2)  # 画三维曲线
plt.show()

采用拟合结果如图所示

技术分享技术分享技术分享

最终选择7次方,绘制如图(将上面代码中的 markersize=2 改为 markersize=radius 即可)

技术分享

 

三维血管重建

标签:imp   ==   shape   max   tool   color   images   radius   结果   

原文地址:http://www.cnblogs.com/TheoryDance/p/7745580.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!