三维血管重建

Posted 理舞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三维血管重建相关的知识,希望对你有一定的参考价值。

原始图片数据如下(共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<

以上是关于三维血管重建的主要内容,如果未能解决你的问题,请参考以下文章

通过MATLAB实现基于冠状动脉造影图像序列的心脏及血管的三维光流运动估计

三维重建开源代码汇总保持更新

三维重建开源代码汇总保持更新

医学图像三维可视化和三维重建的区别

三维重建开源代码汇总保持更新

人工智能机器人5G,这些最新技术都被运用在医疗领域!