【问题标题】:Calculate the contact length between segments of image in Matlab在Matlab中计算图像段之间的接触长度
【发布时间】:2018-12-12 01:41:16
【问题描述】:

我有四种颜色的图像。每种颜色代表一个特定的物质阶段。我可以根据颜色分割图像并计算分割图像的周长。现在,我需要计算不同相之间的接触长度。 An example of the image is shown here。例如,蓝相和黄相之间的接触长度很小,而蓝相和灰相有明显的接触。

% aa is the image  
oil = (aa(:,:,3)==255);
rock =(aa(:,:,2)==179);
gas =(aa(:,:,2)==255);
water =(aa(:,:,2)==0 && aa(:,:,3)==0);

O = bwboundaries(oil);
R = bwboundaries(rock);
G = bwboundaries(gas);
W = bwboundaries(water);

【问题讨论】:

    标签: matlab image-processing


    【解决方案1】:

    一种蛮力方法是遍历图像中的每个像素,并根据该像素值及其右侧像素的值,递增一个表示该相变接触长度计数的变量(如果存在)相变。然后对像素下方的值执行相同的操作。对图像中的每个像素执行此操作,边缘条件除外。

    一种更有效的方法是一次执行行和列,并在执行此操作时递增计数器。

    或者您可以制作图像的多个矩阵,移动一个像素,然后进行比较以查找最终得到二进制矩阵结果的相变,然后简单地将这些结果二进制矩阵相加

    【讨论】:

    • 我使用 bwboundaries 来计算区域的边界。然后,代码沿着边界追踪。我还使用了'dilate来扩展每个阶段的区域,因此由bwboundaries计算的边界将在相邻阶段。
    【解决方案2】:

    这是我最终编写的最终代码。结果看起来是正确的。

        % aa is the image  
    oil = (aa(:,:,3)==255);
    rock =(aa(:,:,2)==179);
    gas =(aa(:,:,2)==255);
    water =(aa(:,:,2)==0 && aa(:,:,3)==0);
    
    phases(1,:,:)=RockBW;
    phases(2,:,:)=WaterBW;
    phases(3,:,:)=OilBW;
    phases(4,:,:)=GasBW;
    
    outMat = ContactMatrix(phases);
    

    ContactMatrix函数如下所示:

    function [ContactMat] = ContactMatrix(phases)
    %CONTACTMATRIX measure the contact area between diferent phases
    
    % The output is a 2D matrix which shows the lengths
    
    %         Phase1, Phase2, Phase 3 
    %phase1     L1      L2      L4
    %Phase2     L2      L3      L5
    %Phase3     L4      L5      L6
    
    % L1 is zero
    % L2 is the contact area of Phase1 and Phase2
    
    nph = size(phases,1);
    
    imSize = size(phases(1,:,:));
    xmax =imSize(2);
    ymax = imSize(3);
    % Idealy we need a check for all sizes :) 
    ContactMat = zeros(nph);
    
    for i=1:1:nph
       counts = zeros(1,nph);
       dd2=bwmorph(squeeze(phases(i,:,:)),'dilate',1);
       B = bwboundaries(dd2);
       nB = size(B,1);
       coefs=1:1:nph;
       coefs(i)=[];
       for j=1:1:nB
            fd = B{j};
            % Ignore the points at boundary of image
            fd(fd(:,1)==1 | fd(:,1)==xmax | fd(:,2)==1 | fd(:,2)==ymax,:)=[];
            nL = size(fd,1);
    
            for k=1:1:nL(1)
                %bufCheck=false(nph-1,1);
                   mat=fd(k,1) + (fd(k,2)-1)*xmax;
                   bufCheck = phases(coefs,mat);
                   counts(coefs)=counts(coefs)+bufCheck';
            end
       end 
       ContactMat(i,coefs)=counts(coefs);
    end
    ContactMat = 0.5*(ContactMat+ContactMat');
    end
    

    【讨论】:

    • 这种方法的问题在于它将边界像素计算为边界长度的代理。 45 度的边界将具有与length/sqrt(2) 成比例的像素数量,而0 度的边界将与length 成比例。也就是说,您的测量值会因图像中边界的角度而有所偏差。
    • 是的,计算有错误。我添加了几行代码来使用 regionprops('perimeter') 计算界面。
    猜你喜欢
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多