【问题标题】:CS50 (Pset4) Filter more "edges" code went wrongCS50 (Pset4) 过滤更多“边缘”代码出错
【发布时间】:2020-11-19 09:39:08
【问题描述】:

我首先编写了中间像素的代码,但它不能正常工作,我不知道为什么。不知道是代码少了什么还是算法理解有误?

中间像素的代码:

  RGBTRIPLE edge[height][width];

  for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
      edge[i][j].rgbtBlue = image[i][j].rgbtBlue;
      edge[i][j].rgbtGreen = image[i][j].rgbtGreen;
      edge[i][j].rgbtRed = image[i][j].rgbtRed;
    }
  }

  for (int h = 0; h < height; h++) {
    for (int w = 0; w < width; w++) {
      int red1 = (edge[h - 1][w - 1].rgbtRed * -1)
          + (edge[h - 1][w + 1].rgbtRed) + (edge[h][w - 1].rgbtRed * -2)
          + (edge[h][w + 1].rgbtRed * 2) + (edge[h + 1][w - 1].rgbtRed * -1)
          + (edge[h + 1][w + 1].rgbtRed * 1);
      int red2 = (edge[h - 1][w - 1].rgbtRed * -1)
          + (edge[h - 1][w].rgbtRed * -2) + (edge[h - 1][w + 1].rgbtRed * -1)
          + (edge[h + 1][w - 1].rgbtRed) + (edge[h + 1][w].rgbtRed * 2)
          + (edge[h + 1][w + 1].rgbtRed);

      int g_red = round(pow(red1 * red1 + red2 * red2, 0.5));
      if (g_red > 255)
        g_red = 255;
      image[h][w].rgbtRed = g_red;

      int blue1 = edge[h - 1][w - 1].rgbtBlue * -1 + edge[h - 1][w + 1].rgbtBlue
          + edge[h][w - 1].rgbtBlue * -2 + edge[h][w + 1].rgbtBlue * 2
          + edge[h + 1][w - 1].rgbtBlue * -1 + edge[h + 1][w + 1].rgbtBlue;
      int blue2 = edge[h - 1][w - 1].rgbtBlue * -1
          + edge[h - 1][w].rgbtBlue * -2 + edge[h - 1][w + 1].rgbtBlue * -1
          + edge[h + 1][w - 1].rgbtBlue + edge[h + 1][w].rgbtBlue * 2
          + edge[h + 1][w + 1].rgbtBlue;

      int g_blue = round(sqrt(blue1 * blue1 + blue2 * blue2));
      if (g_blue > 255)
        g_blue = 255;
      image[h][w].rgbtRed = g_blue;

      int green1 = edge[h - 1][w - 1].rgbtGreen * -1
          + edge[h - 1][w + 1].rgbtGreen + edge[h][w - 1].rgbtGreen * -2
          + edge[h][w + 1].rgbtGreen * 2 + edge[h + 1][w - 1].rgbtGreen * -1
          + edge[h + 1][w + 1].rgbtGreen;
      int green2 = edge[h - 1][w - 1].rgbtGreen * -1
          + edge[h - 1][w].rgbtGreen * -2 + edge[h - 1][w + 1].rgbtGreen * -1
          + edge[h + 1][w - 1].rgbtGreen + edge[h + 1][w].rgbtGreen * 2
          + edge[h + 1][w + 1].rgbtGreen;

      int g_green = round(sqrt(green1 * green1 + green2 * green2));
      if (g_green > 255)
        g_green = 255;
      image[h][w].rgbtRed = g_green;

    }
  }

检查 50 输出:
:( 边缘正确过滤中间像素
预期为“210 150 60\n”,而不是“150 40 100\n”

【问题讨论】:

  • 我不明白您为什么要对来自不同相邻像素的值进行加权并取平方根。此处发布的 CS50 代码通常只是找到每个 r、g、b 分量的简单平均值。在边缘和角落,您还可以计算地图上像素的数量以用作除数。
  • @WeatherVane 这可能不是模糊任务,而是使用 Sobel 算子进行边缘检测。
  • @WeatherVane 我不明白你的意思。我使用了他们告诉我们使用的内核
  • 如 Gerhardh 所解释的
  • @WeatherVane 好的,谢谢你和格哈德,我会在谷歌上进一步了解它

标签: c cs50


【解决方案1】:

至少这个问题:

访问范围之外的数组

示例:在第一次迭代中,代码尝试访问 edge[-1][-1]
这不仅仅是“中间像素代码”。

for(int h = 0 ; h < height ; h ++) {
    for(int w = 0 ; w < width ; w ++) {
       int red1 = (edge[h - 1][w - 1].rgbtRed * -1) + ...

代码需要重写以处理边缘和角落的情况。


有问题的算法

目前尚不清楚访问 8 个像素中的 6 个像素是如何统一检测边缘的。

我希望 /6 在某个地方保持 image[][] 的大小与 edge[][] 相同。

【讨论】:

  • 我只为中间像素制作了它,但它不起作用。它假设根据内核访问它周围的 6 个像素
  • 我只为中间像素制作了它--> 不,发布的代码也适用于角/边缘像素。它以一种调用未定义行为的方式执行此操作。现在,尝试for(int h = 1 ; h + 1 &lt; height ; h ++) 和类似的width 仅对中间像素进行操作。
  • “根据内核”不清楚。发布描述该算法的文档的链接。
猜你喜欢
  • 2021-02-01
  • 2020-11-13
  • 2023-03-22
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多