【问题标题】:How do i extract coordinates of pixel edges/corners我如何提取像素边缘/角落的坐标
【发布时间】:2017-01-27 15:29:28
【问题描述】:

我了解像素元素存储在单元格的中心。但是,我需要使用边缘和角落的坐标而不是中心坐标。

该代码可用于提取下图中显示的所有内部节点。

enter image description here

%obtain the pixel width
pixelsPerInch = get(0, 'ScreenPixelsPerInch');
mmPerInch     = 25.4;
mmPerPixel    = mmPerInch / pixelsPerInch; 

[nrow, ncol] = size(Img);

for ii = 1: nrow - 1
  for jj = 1: ncol - 1
    % determine the distance of each pixel from the origin
    x_mm(jj) = jj * mmPerPixel;
    y_mm(ii) = ii * mmPerPixel;

    % determine the nodal coordinates
    node_x(jj) = (x_mm(jj) + (mmPerPixel/2))/mmPerPixel;
    node_y(ii) = (y_mm(ii) + (mmPerPixel/2))/mmPerPixel;

  end
end

%%%%% merge the x and y-coords
[node_y, node_x] = meshgrid(node_y, node_x);
my_nodes         = [node_y(:), node_x(:)];

为了找到任何节点上方、下方或两侧的边缘中心,所需要做的就是根据一个人打算去的方向,从 node_x 和 node_y 中加上或减去 1/2。例如,要找到任何节点上方的边,请执行以下操作:

jx = node_x;
iy = node_y - 0.5;

人们也可以通过决定是否从兴趣点的 x 和 y 坐标中加/减 1/2 来找到每个兴趣节点的像素中心。

【问题讨论】:

  • 不确定 Matlab 的人是做什么的,但是使用 ImageMagick,您只需将 1/2 添加到每个坐标... imagemagick.org/Usage/draw/#coordinates跨度>
  • @MarkSetchell 取决于 OP 希望他的最终输出是什么样子(在他的显示器上可能以mminches 为单位),这还不够。在从图像矩阵中的像素坐标中添加/减去1/2 后,您必须进行一些后期处理,以将其转换为有意义的距离单位。
  • 这仅对应于半个像素的移位。在许多应用中,区别是无关紧要的。在其他情况下,无需调整单个坐标,只需在适用的情况下对结果进行后处理即可。

标签: matlab image-processing


【解决方案1】:

由于您使用的是图像及其像素坐标,因此此答案假定您有权访问 MATLAB's Image Processing Toolbox

来自 MATLAB 的Image Coordinate Systems documentation

任何像素中心点的固有坐标 (x,y) 与该像素的列和行索引相同。例如,第 5 行第 3 列像素的中心点具有空间坐标 x = 3.0,y = 5.0。

首先,找出每个像素的宽度(以您感兴趣的单位为准)。 Another answer on SO 已经说明了这是如何完成的:

[T]根对象的 ScreenPixelsPerInch 属性。

pixelsPerInch = get(0, 'ScreenPixelsPerInch');
mmPerInch     = 25.4;
mmPerPixel    = mmPerInch / pixelsPerInch;

然后,通过执行x_mm = 3.0 * mmPerPixely = 5.0 * mmPerPixel 之类的操作来转换像素在图像矩阵中的位置(让我们使用MATLAB 文档中第5 行和第3 列的示例-> x = 3.0y = 5.0)。

如果您想要任何角的位置,只需将mmPerPixel / 2 加/减到x_mmy_mm 变量,并且您已经确定了角(或边缘,请选择)的空间位置图像矩阵中的像素。

编辑

提取您感兴趣的所有像素的右上角的空间坐标:

% 2-D locations of pixels of interest
pixelLocations = [2,4;2,3;2,2;3,2;4,1;5,1;6,1;6,2;6,3];
% XY coordinates of all pixels of interest
pixelPositions = sub2ind(size(SegI), pixelLocations(:,1), pixelLocations(:,2));   

% Convert XY coordinates into millimeters
nodeCoords = SegI(pixelsPositions) .* mmPerPixel;
% Since mmPerPixel is the full width & length of each pixel, this value corresponds with the upper-right hand corner of each pixel (i.e., each node)

% Offset nodeCoords by half of their height & width to obtain pixelCoords
pixelCoords = pixelCoord - [mmPerPixel/2, mmPerPixel/2];

【讨论】:

  • 非常感谢@Vladislav。我非常感谢您的帮助,但我对转换有点困惑。由于 1inch = 25.4mm,mmPerInch 不应该 = 1 除以 25.4 吗?另外,据我了解,“ScreenPixelPerInch”似乎是屏幕分辨率的函数?
  • 非常感谢@Vladislav .. 我现在明白了。每个像素的距离为 0.2646 毫米(我的像素每英寸 = 96)。从上图中,这意味着从原点到像素 (1,1) = 0.2646mm,因此将 0.2646/2 添加到该距离(在两个轴上)将为我提供 (1.5, 1.5) 处的节点。刚才我还有一点困难——一次找到所有感兴趣的节点(蓝色和绿色)的坐标。请问,还有什么帮助/建议吗?谢谢!
  • 谢谢弗拉迪斯拉夫。我认为您的建议代码中可能存在错误,因为我得到了node_coords_mm = [0.3969 0.3969],而答案应该是:[x y] = [0.3969 0.926] 你能再检查一遍吗?非常感谢。
  • 看看我对那个红色节点的尝试是什么:M = size(Seg_I, 1); N = size(Seg_I, 2); linear_indices = sub2ind(size(Seg_I), 3, 1); [row, col] = ind2sub(size(Seg_I), linear_indices); pixelCoord = [col row].* mmPerPixel; cornerCoord = pixelCoord + [mmPerPixel/2, mmPerPixel/2]; 我现在的想法是找到一种方法来存储图像的所有线性索引,然后我可以轻松循环这些以找到所有节点。
  • 查看我的最新编辑。您的方法没有任何问题(除了对行和列的一些混淆),您需要做的就是将所有这些下标放入一个矩阵中(就像我所做的那样)。不需要将线性索引重新转换回二维下标的附加步骤(请参阅我的编辑,我没有这样做)。此外,您的 pixelCoord 并不直观 - 行通常是列左侧的维度。
猜你喜欢
  • 2011-05-20
  • 1970-01-01
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-24
  • 2018-07-20
相关资源
最近更新 更多