我想计算给定图像中每个像素的8邻接的最大像素灰度值。
我使用以下代码在C中实现它。
signInWithCredential()
上面的代码按预期工作。然而,这看起来像迭代一样缓慢。
是否有提高速度的改进范围?
答案 0 :(得分:4)
是的,使用大if-else语句,而不是几个if语句。这样,您就不必评估所有语句,更不用说分支预测了。
这应该是开始优化代码的好方法。除此之外,您可以在Code Review中发帖以获取更多信息。祝你好运!
答案 1 :(得分:2)
在任意两个相邻像素之间有六个共享表达式,表明有可能提高约66%的速度。
在实践中,可以在垂直和水平方向分别计算最大值:
for (i=0;i<h-2;i++) {
for (j=0;j<w;j++)
M[j] = max3(img[i][j], img[i+1][j], img[i+2]);
for (j=0;j<w-2;j++)
Out[i][j] = max4(M[j], img[i][j+1], img[i+2][j+1], M[j+2];
}
这完全避免了超出范围的测试并略微减少了比较。结果图像在每个方向上当然缩短了2个像素。
答案 2 :(得分:0)
您有八个特殊情况或多或少发生,有时这些情况可能会重合,如果您只有一行或只有一列或两者:
[]====+=====================================+====[]
|| UL | Upper row | UR ||
++----+-------------------------------------+----++
|| Le | Main block | Ri ||
|| ft | | gh ||
|| c | | t ||
|| ol | | co ||
|| | | l ||
|| | | ||
++----+-------------------------------------+----++
|| LL | Lower row | LR ||
[]====+=====================================+====[]
我应该为每个使用不同的循环,因此您知道一个小修道院可以访问哪些单元格而不必进行任何测试。如果数组只有一行或一列,你必须考虑特殊情况,但这就是全部。
我假设您有一个数组指针数组,正如您所说,但它简化了使用[]
运算符对矩阵单元格的访问。
inline int max2(int a, int b)
{
return a > b ? a : b;
}
inline int max3(int a, int b, int c)
{
return max2(max2(a, b), c);
}
inline int max4(int a, int b, int c, int d)
{
return max2(max2(a, b), max2(c, d));
}
inline int max6(
int a, int b, int c,
int d, int e, int f)
{
return max2(max3(a, b, c), max3(d, e, f));
}
inline int max9(
int a, int b, int c,
int d, int e, int f,
int g, int h, int i)
{
return max3(max3(a, b, c), max3(d, e, f), max3(g, h, i));
}
void max_value(int **in, int **out, int rows, int cols)
{
if (rows > 1) {
/* to avoid many calculations */
int rows_1 = rows - 1, rows_2 = rows - 2;
if (cols > 1) { /* cols > 1 && rows > 1 */
int cols_1 = cols - 1, cols_2 = cols - 2;
/* first consider the four corners */
/* UL */
out[0][0] = max4(
in[0][0], in[0][1],
in[1][0], in[1][1]);
/* LR */
out[rows_1][cols_1] = max4(
in[rows_2][cols_2],in[rows_2][cols_1],
in[rows_1][cols_2],in[rows_1][cols_1]);
/* LL */
out[rows_1][0] = max4(
in[rows_2][0], in[rows_2][1],
in[rows_1][0], in[rows_1][1]);
/* UR */
out[0][cols_1] = max4(
in[0][cols_2], in[1][cols_2],
in[0][cols_1], in[1][cols_1]);
/* next the two side columns */
for(row = 1; row < rows_1; row++) {
/* left */
out[row][0] = max6(
in[row-1][0], in[row-1][1],
in[row][0], in[row][1],
in[row+1][0], in[row+1][1]);
/* right */
out[row][cols_1] = max6(
in[row-1][cols_2], in[row-1][cols_1],
in[row][cols_2], in[row][cols_1],
in[row+1][cols_2], in[row+1][cols_1]);
} /* for */
/* ... and the top/bottom rows */
for(col = 1; col < cols_1; col++) {
/* top */
out[0][col] = max6(
in[0][col-1], in[0][col], in[0][col+1],
in[1][col-1], in[0][col], in[0][col+1]);
/* bottom */
out[row_1][col] = max6(
in[row_2][col-1], in[row_2][col], in[row_2][col+1],
in[row_1][col-1], in[row_1][col], in[row_1][col+1]);
} /* for */
/* and finally, the main block */
for(row=1; row < row_1; row++) {
for(col=1; col < col_1; col++) {
out[row][col] = max9(
in[row-1][col-1],in[row-1][col],in[row-1][col+1],
in[row][col-1],in[row][col],in[row][col+1],
in[row+1][col-1],in[row+1][col],in[row+1][col+1]);
} /* for */
} /* for */
} else { /* rows > 1 && cols == 1 */
/* we collapsed to three zones in one column */
/* UL == UR */
out[0][0] = max2(
in[0][0],
in[1][0]);
/* LL == LR */
out[row_1][0] = max2(
in[row_2][0],
in[row_1][0]);
/* main block */
for(row = 1; row < rows_1; row++) {
out[row][0] = max3(
in[row-1][0],
in[row][0],
in[row+1][0]);
} /* for */
} /* if */
} else { /* rows == 1 */
/* the nine zones collapse to three */
if (cols > 1) {
/* UL == LL */
out[0][0] = max2(in[0][0], in[0][1]);
/* UR == LR */
out[0][col_1] = max2(in[0][col_2], in[0][col_1]);
/* the main part */
for(col=1; col < cols_1; col++)
out[0][col] = max3(in[0][col-1],in[0][col],in[0][col+1]);
} /* for */
} else { /* rows == 1 && cols == 1 */
/* ... or one */
out[0][0] = in[0][0];
}
} /* if */
} /* max_value */