0

该功能应该逐个像素地通过将每个像素的颜色转换为 2n+1“半径”内周围颜色的平均值来模糊图像。

(它跳到下一个像素的部分已经实现,不用担心)。

我成功编译了这段代码:

void
blur_pixels(image *img, pixel *p, size_t i, size_t j)
{
  //i = current height of pixel, j = current width of pixel
  int side = 2*blurRate+1;
  int total = 0;
  int leftRight = i-blurRate;
  int upDown = j-blurRate;
  int tmpHr = 0, tmpHg = 0, tmpHb = 0;

  for(; upDown < j+blurRate; upDown++) {
    if(upDown >= 0 && upDown < img->height) {
      for(; leftRight < i+blurRate; leftRight++) {
        if(leftRight >= 0 && leftRight < img->width) {
          tmpHr += (p+leftRight)->r;
          tmpHg += (p+leftRight)->g;
          tmpHb += (p+leftRight)->b;
          total++;
        }
      }
    }
  }
  p->r=tmpHr/total;
  p->g=tmpHg/total;
  p->b=tmpHb/total;
}

但是当我运行代码时,出现以下异常:

Floating point exception

有谁知道为什么?

4

1 回答 1

3

代码正在执行除以 0p->r=tmpHr/total;

total可能为零,因为未打开编译器警告以显示for()循环的混合有符号/无符号数学。打开所有编译器警告。

比较upDown < j+blurRate和其他代码是使用无符号数学完成的,可能不像 OP 所期望的那样,内部total++;永远不会发生。如果upDown < 0,则upDowninupDown < j+blurRate变成一个大的无符号值。然后比较是假的。

size_t j  // an unsigned type
...
int upDown = j-blurRate;
...
for(; upDown < j+blurRate; upDown++) {  // not firing

一种解决方案是仅使用int变量。更强大的解决方案将使用无符号数学,但需要更多更高级别的代码才能获得好的答案。

就像是:

blur_pixels(image *img, pixel *p, size_t i, size_t j) {
  //i = current height of pixel, j = current width of pixel
  size_t side = 2u*blurRate+1;
  size_t total = 0;
  size_t leftRight = (i > blurRate) ? i-blurRate : 0;
  size_t upDown = (j > blurRate) ? j-blurRate : 0;
  int tmpHr = 0, tmpHg = 0, tmpHb = 0;

  for(; upDown < j+blurRate; upDown++) {
    if (upDown < img->height) {
      // I suspect leftRight needs to be set here each iteration
      size_t leftRight = (i > blurRate) ? i-blurRate : 0;
      for(; leftRight < i+blurRate; leftRight++) {
        if (leftRight < img->width) {
          tmpHr += (p+leftRight)->r;
          tmpHg += (p+leftRight)->g;
          tmpHb += (p+leftRight)->b;
          total++;
        }
      }
    }
  }
  if (total) {
    p->r = tmpHr/total;
    p->g = tmpHg/total;
    p->b = tmpHb/total;
  } else {
    p->r = p->g = p->b = 0;
  }
}
于 2017-05-08T17:02:19.483 回答