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
额外说明
- 我添加了
~isempty()判断,避免当某列没有找到非零像素时出现索引错误 - 修改后,
output_img和output_img1只会保留你需要的边缘点,而非整列的线 - 后续的
bwperim和图像融合逻辑会基于这些点进行处理,最终转换回横断面视图时就能得到你想要的两个点的效果
你可以把这段修改后的代码替换原代码中对应的部分,再运行试试效果。
内容的提问来源于stack exchange,提问作者Kim
相关产品推荐
相关产品推荐

