检查邻域中的像素值

时间:2017-05-01 20:09:13

标签: image matlab image-processing

我正在尝试编写执行以下操作的MATLAB脚本:

给定:.jpg图像的像素坐标(x,y) 目标:在给定坐标的5个像素半径内检查是否存在特定值的像素。

例如,假设我给出了坐标(100,100),那么我想检查图像中(100,100)的邻域是否有任何黑色像素(0,0,0) )。也许,像素(103,100)和(104,100)可能具有值(0,0,0)。

当前代码

x_coord = uint32(coord(:,1));  
y_coord = uint32(coord(:,2));
count = 0;

for i = 1:length(x_coord)
    %(img(x,y) returns pixel value at that (x,y)
    %Note 0 = black. Indicating that, at that position, the image is just 
    % black 
    if img(x_coord(i),y_coord(i)) == 0 
        count = count + 1;
    end
end

目前只检查确切的位置。不在当地社区。我怎么能延长这个?

编辑:另请注意,只要附近有至少一个像素值,我就会增加计数。我没有尝试枚举邻域中有多少像素具有该值,只是试图找到至少一个具有该值的像素的证据

编辑:

即使我无法识别代码的错误,我也无法获得我想要的确切结果。这是我正在使用的代码。

val = 0; %pixel value to check
N = 50; % neighbourhood radius

%2D grid of coordinates surrounding center coordinate
[R, C] = ndgrid(1 : size(img, 1), 1 : size(img, 2));

for kk = 1 : size(coord, 1)
    r = coord(kk, 1); c = coord(kk, 2); % Get pixel locations

    % mask of valid locations within the neighbourhood (avoid boundary problems)
    mask = (R - r).^2 + (C - c).^2 <= N*N;         

    pix = img(mask); % Get the valid pixels
    valid = any(pix(:) ~= val);
    % Add either 0 or 1 depending if we have found any matching pixels
    if(valid == 1)
        img = insertMarker(img, [r c], 'x', 'color', 'red', 'size', 10);
        imwrite(img, images(i).name,'tiff');
    end
    count = count + valid; 
end

2 个答案:

答案 0 :(得分:4)

更简单的方法是使用索引来抓取一个邻域,然后检查邻域中的任何像素是否具有您正在寻找的值,在{a}上使用any这个社区的扁平版本。抓住正确邻域的技巧是首先生成一个跨越图像整个维度的二维坐标网格,然后简单地使用一个圆的方程,其中心是您正在查看的每个坐标,并确定那些位置满足以下等式:

(x - a)^2 + (y - b)^2 <= N^2

N是观察窗口的半径,(a, b)是感兴趣的坐标,而(x, y)是图像中的坐标。使用meshgrid生成坐标。

您可以使用上面的等式创建logical蒙版,索引图像以拉出蒙版内有效的位置,并检查有多少像素与您想要的像素匹配。上述方法的另一个好处是您不会受到任何越界错误的影响。因为您正在预生成图像中所有有效坐标的列表,所以生成蒙版会将您限制在图像的边界内,这样您就不必检查超出边界的条件....即使您指定要搜索的坐标超出范围。

具体来说,假设您的图片存储在img中,您可以这样做:

count = 0; % Remembers total count of pixels matching a value
val = 0; % Value to match
N = 50; % Radius of neighbourhood

% Generate 2D grid of coordinates
[x, y] = meshgrid(1 : size(img, 2), 1 : size(img, 1));

% For each coordinate to check...
for kk = 1 : size(coord, 1)
    a = coord(kk, 1); b = coord(kk, 2); % Get the pixel locations
    mask = (x - a).^2 + (y - b).^2 <= N*N; % Get a mask of valid locations
                                           % within the neighbourhood        
    pix = img(mask); % Get the valid pixels
    count = count + any(pix(:) == val); % Add either 0 or 1 depending if 
                                        % we have found any matching pixels
end

答案 1 :(得分:2)

建议的解决方案:

Error: Uncaught (in promise): TypeError: Cannot read property 'get' of undefined
TypeError: Cannot read property 'get' of undefined
at RedditService.getPosts (reddit.service.ts:16)

如果您的img函数一次只能检查一个像素,只需添加fc = repmat(-5:5,11,1); I = (fc.^2+fc'.^2)<=25; fc_x = fc(I); fc_y = fc'; fc_y = fc_y(I); for i = 1:length(x_coord) x_toCheck = fc_x + x_coord(i); y_toCheck = fc_y + y_coord(i); I = x_toCheck>0 & x_toCheck<=yourImageWidth; I = I.*(y_toCheck>0 & y_toCheck<=yourImageHeight); x_toCheck = x_toCheck(logical(I)); y_toCheck = y_toCheck(logical(I)); count = sum(img(x_toCheck(:),y_toCheck(:)) == 0); end

for loop

<强>步骤一步:

首先需要获得给定坐标的5个像素范围内的所有坐标。

我们首先构建一个长度/宽度为11像素的正方形。

for i = 1:length(x_coord)
    x_toCheck = fc_x + x_coord(i);
    y_toCheck = fc_y + y_coord(i);
    I = x_toCheck>0 & x_toCheck<=yourImageWidth;
    I = I.*(y_toCheck>0 & y_toCheck<=yourImageHeight);
    x_toCheck = x_toCheck(logical(I));
    y_toCheck = y_toCheck(logical(I));
    for j = 1:length(x_toCheck)
        count = count + (img(x_toCheck(j),y_toCheck(j)) == 0);
    end
end

enter image description here

我们现在需要构建一个滤镜来摆脱5像素半径以外的那些点。

fc = repmat(-5:5,11,1);
fc_x = fc;
fc_y = fc';
plot(fc_x,fc_y,'.');

应用滤镜,这样我们就可以得到一个5像素半径的圆圈。

I = (fc.^2+fc'.^2)<=25;

enter image description here

接下来将圆心转换为给定坐标:

fc_x = fc_x(I);
fc_y = fc_y(I);

您需要检查圆圈的一部分是否在图像范围之外:

x_toCheck = fc_x + x_coord(i);
y_toCheck = fc_y + y_coord(i);

最后计算像素:

I = x_toCheck>0 & x_toCheck<=yourImageWidth;
I = I.*(y_toCheck>0 & y_toCheck<=yourImageHeight);
x_toCheck = x_toCheck(logical(I));
y_toCheck = y_toCheck(logical(I));