【发布时间】:2020-10-23 12:00:13
【问题描述】:
问题:给定一个方阵 A,其维数 N 是 64 的除数,找到一种快速平滑 A 的方法,即让 3 x 3 网格在 A 上滑动,s.t.对于每个条目 A_{ij},我们将其替换为附近 8 个邻居的平均值。
我的解决方案:假设 A 是一个 4x4 矩阵,我们初始化为:
int A[NxN] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
相当于:
在第一次迭代中,我们看到 A_ij 等价于 0,它位于 3x3 矩阵的中心。我们意识到 3x3 矩阵的索引 (0,0), (0,1), (0,2), (1,0), (1,3) 试图找到不存在的数字。因此,我们看到结果一定是,如果 $A_{ij}$ = 0,那么我们必须将其替换为 $0+1+4+5 = \frac{10}{4}$。
下一次迭代,我们看到 A_ij 等价于 1,现在是 3x3 矩阵的新中心,我们看到要包括在平均中的数字是:0,1,2,4,5,6 .
所以当我们在矩阵的一个角落A时,我们需要4个数字进行平均,在矩阵的顶部,我们需要6个数字,如果A_{ij} = 6,意味着在中间矩阵,我们需要 9 个数字。
我试图找到的是这些所需数字序列的一般模式,以便在单个 \texttt{for 循环} 中执行此操作。
我发现当 i % dim == 0 时,我们在矩阵的左侧,当 i % dim == 3 我们在左侧时,但我试图找到一个通用的索引模式来定义我的平均函数与我的 if 条件配对。
#include <stdio.h>
int smooth(int dim);
int main() {
smooth(4);
}
int smooth(int dim) {
int A[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int K[dim*dim]; // Replacement array, otherwise we average averages
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++)
{
// Corner cases
if ((i % dim == 0 && j % dim == 0) || (i % dim == dim - 1 && j % dim == 0) || (i % dim == 0 && j % dim == dim -1) || (i % dim == dim -1 && j % dim == dim-1))
{
// Average function on corners
}
// else if not corner and in "edge row", top/bottom {
// Average 6 numbers
}
}
}
return 0;
}
【问题讨论】:
-
您使用的“$”数字令人困惑。我猜是因为格式化尝试不成功。请edit 并使用此信息。 stackoverflow.com/editing-help
-
@Yunnosch 抱歉 - 这是 LaTeX 编写数学的方式,适用于其他堆栈交换站点。我马上更新。
-
不使用通用公式处理边缘并使用四个边缘的规范如何?
-
为了速度,单独处理角 (0,3,12,15),对非角边 (1-2, 4-8, 13-) 分别应用一个专用的边缘情况计算14, 7-11)并将一个无条件(即没有
ifinside)应用于中心休息(5-6-9-19)。或者将图片在 x 和 y 中放大 2 倍。用合理的值填充新添加的角落和边缘,然后将一个无条件公式应用于所有原始图片。 -
另外:您必须构建一个单独的图像,而不是“替换”一个像素,否则您将获得平均值。
标签: c image optimization