【问题标题】:Chessboard distance in the image matrix图像矩阵中的棋盘距离
【发布时间】:2019-05-27 13:17:43
【问题描述】:

给定一个图像矩阵,我如何获得与像素 A 的棋盘距离小于 D 的像素的位置。我需要对所有像素执行此操作。

使用 MATLAB 函数 bwdist 我无法提供所需的结果。解决办法是什么?

[D,idx] = bwdist(Img,'chessboard');

【问题讨论】:

    标签: matlab image-processing distance


    【解决方案1】:

    给定图像、像素和最大距离:

    % Test image
    Image = zeros(20,30);
    
    % Maximum chessboard distance from image
    maxDist = 7;
    
    % The pixel from which to measure distance
    pix = [4,19];
    

    要找到与pix 的棋盘距离的像素是 小于maxDist 并且在图像边界内:

    选项1:使用bwdist

    % Create a binary image with all pixels zero except 'pix'
    bw = zeros(size(Image));
    bw(pix(1), pix(2)) = 1;
    
    % Get the chessboard distance transform
    [D,idx] = bwdist(bw,'chessboard');
    
    % Get the linear index of 'pix' 
    pixInd = sub2ind(size(bw), pix(1), pix(2));
    
    % Find linear indices of pixels who's chessboard distance from pixel are 
    % less than 'maxDist'
    pointsInd = find(idx == pixInd & D < maxDist);
    
    % Remove 'pix'
    pointsInd(pointsInd == pixInd) = [];
    
    % Get the pairs of (x,y) of the pixels
    [pointsX, pointsY] = ind2sub(size(bw), pointsInd);
    

    选项2:使用meshgrid

    % Get the range of x and y indices who's chessboard distance from pixel are 
    % less than 'maxDist' and in the image bounds
    xRange = max((pix(1)-(maxDist-1)),1):min((pix(1)+(maxDist-1)),size(Image,1));
    yRange = max((pix(2)-(maxDist-1)),1):min((pix(2)+(maxDist-1)),size(Image,2));
    
    % Create a mesgrid to get the pairs of (x,y) of the pixels
    [pointsX, pointsY] = meshgrid(xRange, yRange);
    pointsX = pointsX(:);
    pointsY = pointsY(:);
    
    % Remove 'pix'
    pixIndToRemove = (pointsX == pix(1) & pointsY == pix(2));
    pointsX(pixIndToRemove) = [];
    pointsY(pixIndToRemove) = [];
    

    显示结果:

    % Get linear indices of pixels
    pointsInd = sub2ind(size(Image), pointsX, pointsY);
    
    % To display the result, create a binary image with all found pixels 
    % colored white
    bwPoints = zeros(size(Image));
    bwPoints(pointsInd) = 1;
    
    % Show points
    imshow(bwPoints, 'InitialMagnification', 2000)
    
    % Show pixel grid lines
    hold on
    [rows, cols] = size(bwPoints);
    for row = 0.5 : 1 : (rows + 0.5)
        line([0.5, cols+0.5], [row, row], 'Color', 'r', 'LineWidth', 0.5);
    end
    for col = 0.5 : 1 : (cols + 0.5)
        line([col, col], [0.5, rows+0.5], 'Color', 'r', 'LineWidth', 0.5);
    end
    

    效率并在所有图像像素上循环运行:

    选项 2选项 1 快得多。我首先写了 Option 1,因为问题中提到了bwdist。在循环中运行 选项 2 可以通过首先计算像素然后将它们移动到每个像素的位置来改进:

    % Get the range of x and y indices who's chessboard distance from pixel 
    % (0,0) are less than 'maxDist'
    xRange = (-(maxDist-1)):(maxDist-1);
    yRange = (-(maxDist-1)):(maxDist-1);
    
    % Create a mesgrid to get the pairs of (x,y) of the pixels
    [pointsX, pointsY] = meshgrid(xRange, yRange);
    pointsX = pointsX(:);
    pointsY = pointsY(:);
    
    % Remove pixel (0,0)
    pixIndToRemove = (pointsX == 0 & pointsY == 0);
    pointsX(pixIndToRemove) = [];
    pointsY(pixIndToRemove) = [];
    
    for x=1:size(Image, 1)
        for y=1:size(Image, 2)
            % Get a shifted copy of 'pointsX' and 'pointsY' that is centered
            % around (x, y)
            pointsX1 = pointsX + x;
            pointsY1 = pointsY + y;
    
            % Remove the the pixels that are out of the image bounds        
            inBounds =...
                pointsX1 >= 1 & pointsX1 <= size(Image, 1) &...
                pointsY1 >= 1 & pointsY1 <= size(Image, 2);
    
            pointsX1 = pointsX1(inBounds);
            pointsY1 = pointsY1(inBounds);
    
            % Do stuff with 'pointsX1' and 'pointsY1'
            % ...
    
        end
    end
    

    【讨论】:

    • 感谢您提供有效的解决方案。看起来没问题,但有一个小问题:目标像素 (pix) 的位置包含在 [pointsX, pointsY] 对中,不应该这样。
    • @dtr43:我编辑了答案并删除了目标像素
    • 它有效,但在一个示例情况下(对于 434*700 像素图像)计算所有像素的棋盘距离,选项 1(您提出的解决方案)已在两个 for 循环中使用。此外,还有另一个内部循环计算目标像素与棋盘距离内的周围像素之间的欧几里得距离。这个过程非常耗时且效率低下。有什么技巧可以提高效率吗?
    • @dtr43:选项 2 更快。我编辑了答案并添加了一个部分:效率和在所有图像像素上循环运行
    【解决方案2】:

    "目的是获取到像素A的棋盘距离小于D的像素的位置。过程应该是 对所有像素执行..."

    由于 D 正在创建一个正方形选择区域,因此只需使用简单的数学运算即可..

    例如:如果 D 为 3 那么从像素 A 的 [x,y] 位置...

    //# we minus D by 1 since you want less than D (not equal / higher)
    
    Start-X = pixelA.x - (D-1); //from the left
    End-X = pixelA.y + (D-1); //to the right
    
    Start-Y = pixelA.y - (D-1); //from the top
    End-Y = pixelA.y + (D-1); //to the bottom
    

    这将为您提供代表所需选择区域的正方形周长。

    请看下面的示例图片:
    每个正方形是一个像素。如果“皇冠”图标代表像素 A 并且 D 为 3(您的 “小于 D 表示D 最大长度为 2 个像素),你能看到上面的伪代码是如何应用的吗?

    【讨论】:

    • 感谢您的建议;恐怕它可以计算对角邻域。
    • 如果我没有误解您的评论...(1) 向左/向右步进一像素,并且向上/向下步进一像素以进行对角线移动。 (2)重复步骤(1),直到覆盖所有对角线像素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 2016-12-06
    • 2011-08-08
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多