You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab冠脉图像矢状面转横断面异常:需两点却输出整线求解

问题:冠状动脉图像转换回横断面时错误显示整线而非两点

我有一组包含271帧的冠状动脉图像,已经将其转换为矢状面视图,并通过二值化操作提取出了动脉内表面。但当我尝试转换回横断面视图以保留矢状面的提取信息时,结果不符合预期:我仅需在横断面视图中显示两个点,实际却输出了整条线。

相关图像:

  • 矢状面边缘图
  • 当前错误输出图
  • 目标输出图

我的Matlab代码如下:

clear , clc 
mri = uint8(zeros(512,512,271)); % preallocate 4-D array 
for frame=1:271 
    [mri(:,:,frame),map] = imread('image.tif',frame); 
end 
for angle = 0:1:180 
    if angle == 0 
        Img(:,:,:) = mri(:,:,:); 
    else 
        Img(:,:,:) = imrotate(mri(:,:,:),angle,'bilinear','crop'); 
    end 
    ImgSg = squeeze(permute(Img, [1 3 2])); 
    for slice = 1: 271 
        Image(:,:,:) = Img(:,:,slice); 
        xcentre = floor(size(Image, 2) / 2); 
        ycentre = floor(size(Image, 1) / 2); 
        sliceC =(xcentre+ycentre)/2; 
        sliceimage = squeeze(permute(Image(:, sliceC, :), [1 3 2])); 
        if slice == 1 
            image3D = sliceimage; 
        else 
            image3D = cat(2, image3D, sliceimage); 
        end 
    end 
    ImgSg1 = ImgSg; 
    image3D(226:286,1:271)=10; 
    % imshow(ImgSg(:,:,256)); 
    [counts,x] = imhist(image3D,16); 
    T = otsuthresh(counts); 
    BW = imbinarize(image3D,T); 
    % imshow3D(BW); 
    [rows, columns, numberOfColorChannels] = size(BW); 
    middleRow = floor(rows/2); 
    topHalf = BW(1:middleRow, :,:); 
    bottomHalf = BW(1+middleRow:end, :,:); 
    filterImg = bwareaopen(bottomHalf,25); 
    output_img = zeros(size(bottomHalf)); 
    for col = 1: size(bottomHalf,2) 
        first_nnz_row = find(filterImg(:,col),1,'first'); 
        output_img(first_nnz_row:end,col) = 1; 
    end 
    filterImg = bwareaopen(topHalf,25); 
    output_img1 = zeros(size(topHalf)); 
    for col = 1: size(topHalf,2) 
        first_nnz_row1 = find(filterImg(:,col),1,'last'); 
        output_img1(1:first_nnz_row1,col) = 1; 
    end 
    fullImage = [output_img1; output_img]; 
    fullImage=logical(1 - fullImage); 
    i2 = bwperim(fullImage,8); 
    im1 = i2; 
    other_images = ImgSg; 
    blend = 0.2; 
    mask1 = im1; 
    fused = other_images; 
    for slice = 1 : size(fused, 2) 
        this_slice = fused(:,:,slice); 
        this_slice(mask1)=double(this_slice(mask1))*blend+double(im1(mask1)*(1-blend)); 
        % imshow(this_slice) 
        fused(:,:,slice) = this_slice; 
    end 
    imshow(fused(:,:,256)); 
    % imshow3D(fullImage); 
    ImgSg = squeeze(permute(fused, [1 3 2])); 
    imshow3D(ImgSg) 
end 

问题分析与解决方案

我帮你排查了代码,发现问题出在生成二值化输出时的列填充逻辑上:

你当前的代码中,在处理下半部分和上半部分图像时,是把从找到的边缘行到列的首尾全部填充为1,这就导致了整线的出现,而不是只保留边缘的单个点:

  • 对于下半部分:output_img(first_nnz_row:end,col) = 1; —— 这会把first_nnz_row到该列底部的所有像素都设为1,形成竖线
  • 对于上半部分:output_img1(1:first_nnz_row1,col) = 1; —— 这会把该列顶部到first_nnz_row1的所有像素都设为1,同样形成竖线

只需要把这两处的整列填充修改为仅标记找到的边缘点即可,具体修改如下:

修改后的关键代码片段

filterImg = bwareaopen(bottomHalf,25); 
output_img = zeros(size(bottomHalf)); 
for col = 1: size(bottomHalf,2) 
    first_nnz_row = find(filterImg(:,col),1,'first'); 
    % 仅标记找到的第一个非零行的点,而非整列
    if ~isempty(first_nnz_row)
        output_img(first_nnz_row,col) = 1;
    end
end 
filterImg = bwareaopen(topHalf,25); 
output_img1 = zeros(size(topHalf)); 
for col = 1: size(topHalf,2) 
    first_nnz_row1 = find(filterImg(:,col),1,'last'); 
    % 仅标记找到的最后一个非零行的点,而非整列
    if ~isempty(first_nnz_row1)
        output_img1(first_nnz_row1,col) = 1;
    end
end 

额外说明

  1. 我添加了~isempty()判断,避免当某列没有找到非零像素时出现索引错误
  2. 修改后,output_img和output_img1只会保留你需要的边缘点,而非整列的线
  3. 后续的bwperim和图像融合逻辑会基于这些点进行处理,最终转换回横断面视图时就能得到你想要的两个点的效果

你可以把这段修改后的代码替换原代码中对应的部分,再运行试试效果。

内容的提问来源于stack exchange,提问作者Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:14:20