Расстояние шахматной доски в матрице изображения - PullRequest
2 голосов
/ 27 мая 2019

Учитывая матрицу изображения, как я могу получить расположение пикселей, расстояние шахматной доски от которых по пикселю A меньше D .Мне нужно выполнить это для всех пикселей.

Использование функции MATLAB bwdist Я не смог обеспечить желаемый результат.Какое решение?

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

Ответы [ 2 ]

4 голосов
/ 27 мая 2019

Учитывая изображение, пиксель и максимальное расстояние:

% 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

enter image description here

Эффективность и работа в цикле по всем пикселям изображения:

Опция 2 намного быстрее, чем Опция 1 . Сначала я написал Вариант 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
3 голосов
/ 27 мая 2019

"Цель состоит в том, чтобы получить доступ к местоположению пикселей, расстояние шахматной доски от которых по пикселю A меньше D . Процесс должен быть выполняется для всех пикселей ... "

Поскольку D создает квадратную область выделения, просто используйте простую математику.

Например: если D равно 3, то из положения [x, y] пикселя A ...

//# 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 пикселя). Вы видите, как применяется приведенный выше псевдокод?

image

...