【问题标题】:Matlab and ImageJ detecting bone fractureMatlab 和 ImageJ 检测骨折
【发布时间】:2015-02-02 17:33:47
【问题描述】:

我正在尝试使用 imageJ 和 Matlab 检测图片中的骨折,这两者都是必需的。这是原图:

我已经在 matlab 和 imageJ 之间建立了连接,并且我已经在 imageJ 上打开了图像并开始做一些事情。首先,我使用 imageJ 菜单中的 Find Edges 功能来获取骨骼的轮廓。在我做了对比度增强以增强轮廓之后。我现在的问题是,只有一个轮廓和黑色背景,我怎样才能制作一个算法或类似的东西来告诉我线条没有连接? (意思是骨头有骨折)。当他勾选 sobel 边缘检测时,我做了一些类似于此视频中的内容。

https://www.youtube.com/watch?v=Hxn2atZl5us

【问题讨论】:

  • 你能提供一个链接到你所指的实际图片吗?而且我不知道您是否需要使用 Matlab 或 ImageJ?你问题的最后一行让我很困惑。
  • s.hswstatic.com/gif/bones-broken.jpg 在这里。我还有另一种获取轮廓的方法。如果我对高斯进行差异化,我也可以得到整个骨骼的清晰轮廓。然后我只需要我有点迷失的部分。如何检查线路是否一路连接
  • 我想仅使用 matlab 和 imagej 检查骨骼中是否存在骨折。使用 sobel 边缘检测,我可以得到骨骼的轮廓(几乎没有“粒子”)。问题是在我得到大纲之后我应该做什么?我正在考虑检查线路是否连接(如果没有连接,则表示断裂)。另外我不知道sobel边缘检测是否是解决这个问题的最佳方法。这就是为什么我需要一些反馈和帮助
  • 另一个选项可能是使用霍夫变换并检查不匹配的行。我不知道,需要一些反馈:/
  • 好吧,我觉得这很有趣;我稍后会尝试解决此问题,但与此同时,您也可能会从其他人那里获得更多见解/答案:)

标签: matlab imagej


【解决方案1】:

仅在 MATLAB 中试一试。您可以使用 Hough 变换找出对边缘滤波图像贡献最大的角度,然后使用该信息更进一步,并通过一些典型的图像处理技巧检测中断的位置。

不承诺这将如何处理不是您提供的任何图像,但可以合理地改进这些步骤以增加样本的广度。

img = imread('http://i.stack.imgur.com/mHo7s.jpg');

ImgBlurSigma = 2; % Amount to denoise input image
MinHoughPeakDistance = 5; % Distance between peaks in Hough transform angle detection
HoughConvolutionLength = 40; % Length of line to use to detect bone regions
HoughConvolutionDilate = 2; % Amount to dilate kernel for bone detection
BreakLineTolerance = 0.25; % Tolerance for bone end detection
breakPointDilate = 6; % Amount to dilate detected bone end points

%%%%%%%%%%%%%%%%%%%%%%%

img = (rgb2gray(img)); % Load image
img = imfilter(img, fspecial('gaussian', 10, ImgBlurSigma), 'symmetric'); % Denoise

% Do edge detection to find bone edges in image
% Filter out all but the two longest lines
% This feature may need to be changed if break is not in middle of bone
boneEdges = edge(img, 'canny');
boneEdges = bwmorph(boneEdges, 'close');
edgeRegs = regionprops(boneEdges, 'Area', 'PixelIdxList');
AreaList = sort(vertcat(edgeRegs.Area), 'descend');
edgeRegs(~ismember(vertcat(edgeRegs.Area), AreaList(1:2))) = [];
edgeImg = zeros(size(img, 1), size(img,2));
edgeImg(vertcat(edgeRegs.PixelIdxList)) = 1;

% Do hough transform on edge image to find angles at which bone pieces are
% found
% Use max value of Hough transform vs angle to find angles at which lines
% are oriented.  If there is more than one major angle contribution there
% will be two peaks detected but only one peak if there is only one major
% angle contribution (ie peaks here = number of located bones = Number of
% breaks + 1)
[H,T,R] = hough(edgeImg,'RhoResolution',1,'Theta',-90:2:89.5);
maxHough = max(H, [], 1);
HoughThresh = (max(maxHough) - min(maxHough))/2 + min(maxHough);
[~, HoughPeaks] = findpeaks(maxHough,'MINPEAKHEIGHT',HoughThresh, 'MinPeakDistance', MinHoughPeakDistance);

% Plot Hough detection results
figure(1)
plot(T, maxHough);
hold on
plot([min(T) max(T)], [HoughThresh, HoughThresh], 'r');
plot(T(HoughPeaks), maxHough(HoughPeaks), 'rx', 'MarkerSize', 12, 'LineWidth', 2);
hold off
xlabel('Theta Value'); ylabel('Max Hough Transform');
legend({'Max Hough Transform', 'Hough Peak Threshold', 'Detected Peak'});

% Locate site of break
if numel(HoughPeaks) > 1;
    BreakStack = zeros(size(img, 1), size(img, 2), numel(HoughPeaks));
    % Convolute edge image with line of detected angle from hough transform
    for m = 1:numel(HoughPeaks);

        boneKernel = strel('line', HoughConvolutionLength, T(HoughPeaks(m)));
        kern = double(bwmorph(boneKernel.getnhood(), 'dilate', HoughConvolutionDilate));
        BreakStack(:,:,m) = imfilter(edgeImg, kern).*edgeImg;
    end

    % Take difference between convolution images.  Where this crosses zero
    % (within tolerance) should be where the break is.  Have to filter out
    % regions elsewhere where the bone simply ends.
    brImg = abs(diff(BreakStack, 1, 3)) < BreakLineTolerance*max(BreakStack(:)) & edgeImg > 0;
    [BpY, BpX] = find(abs(diff(BreakStack, 1, 3)) < BreakLineTolerance*max(BreakStack(:)) & edgeImg > 0);
    brImg = bwmorph(brImg, 'dilate', breakPointDilate);
    brReg = regionprops(brImg, 'Area', 'MajorAxisLength', 'MinorAxisLength', ...
        'Orientation', 'Centroid');
    brReg(vertcat(brReg.Area) ~= max(vertcat(brReg.Area))) = [];

    % Calculate bounding ellipse
    brReg.EllipseCoords = zeros(100, 2);
    t = linspace(0, 2*pi, 100);
    brReg.EllipseCoords(:,1) = brReg.Centroid(1) + brReg.MajorAxisLength/2*cos(t - brReg.Orientation);
    brReg.EllipseCoords(:,2) = brReg.Centroid(2) + brReg.MinorAxisLength/2*sin(t - brReg.Orientation);

else
    brReg = [];

end

% Draw ellipse around break location
figure(2)
imshow(img)
hold on
colormap('gray')
if ~isempty(brReg)
    plot(brReg.EllipseCoords(:,1), brReg.EllipseCoords(:,2), 'r');
end
hold off

【讨论】:

  • 非常感谢!真棒@Staus
  • 是的@Benoit_11 使用我的代码,我已经设法通过霍夫变换获得了线条,但不是所有线条:s
猜你喜欢
  • 1970-01-01
  • 2016-08-21
  • 2014-12-29
  • 2015-06-26
  • 1970-01-01
  • 1970-01-01
  • 2015-07-27
  • 2014-09-19
  • 2021-04-10
相关资源
最近更新 更多