【发布时间】:2021-03-19 09:37:17
【问题描述】:
我有一个灰度像素值的二维数组,看起来像
255 250 250 250 235 251 255 201
255 250 250 250 235 251 255 151
255 250 250 250 235 251 255 151
255 250 250 250 235 251 255 151
255 250 250 250 235 251 255 151
在我在网上和其他帖子中看到的实现中,该程序将专门获取 3x3 窗口区域中的相邻像素。
例如,
for (row = 1; row <= numRows; ++row)
{
for (col = 1; col <= numCols; ++col)
{
//neighbor pixel values are stored in window including this pixel
window[0] = imageArr[row - 1][col - 1];
window[1] = imageArr[row - 1][col];
window[2] = imageArr[row - 1][col + 1];
window[3] = imageArr[row][col - 1];
window[4] = imageArr[row][col];
window[5] = imageArr[row][col + 1];
window[6] = imageArr[row + 1][col - 1];
window[7] = imageArr[row + 1][col];
window[8] = imageArr[row + 1][col + 1];
// do something with window
}
}
我正在尝试实现更动态的窗口大小。 前任。如果用户想在 4x4 区域或 5x5 区域中查找相邻像素
【问题讨论】:
-
基本答案是肯定的:添加两个在窗口尺寸上起作用的额外循环并删除所有这些硬连线的重复代码。注意避免溢出。即使在您的示例中,底部和右侧边缘也将超出
imageArr的范围。我认为您打算测试< numRows - 1等。对于均匀大小的窗口,显然窗口的中心点不是对称的,因此需要特别注意定义您的有效操作空间。更清洁的解决方案可能只使用一个循环和std::copy_n、memcpy甚至std::valarray。 -
感谢您的回复。您能否通过添加另一个嵌套的 for 循环进一步详细说明您的意思?
-
有像 Eigen 这样的库,可以让您从更大的数组中提取任意子数组。对这样的东西很有用。或者,您可以使用模板函数从另一个给定中心行和列的数组中提取
std::array<std::array<int,N>,N>之类的内容。 -
我认为是时候坐下来在纸上画一个网格,然后在顶部和左侧边缘写下数字(从 0 开始)来表示列和行索引。现在在其中某处绘制一个大小为 N 的“窗口”。将窗口视为图像,因此您当然会使用两个循环来遍历每个值。它的局部左上角始终位于位置 (0,0)。它在图像上下文中的左上角与
row和col的值相关。你会明白的,我相信。 -
就个人而言,我会避免你正在做的所有这些额外的数学运算,试图循环中心点。它只是使事情复杂化,并没有增加任何东西。只需在
[0, numRows-N)和[0, numCols-N)范围内运行主循环,内部两个循环都在[0, N)上运行。如果您需要知道窗口的中心点,那么它将是row+N/2, col+N/2。当然,如果window是一维数组,那么使用 2D 索引它是标准的,当您使用基于行的图像时,您可能应该记住:window[y * N + x]通常。跨度>
标签: c++ algorithm image-processing multidimensional-array pixel