【问题标题】:Understanding ImageProcessing code了解图像处理代码
【发布时间】:2012-10-07 15:17:19
【问题描述】:

我是 android ndk 的新手。我已经开始通过
ruckus 和 by IBM blog 的图像处理示例进行学习。我下面没有几行。谁能帮我理解代码sn-p?`

static void brightness(AndroidBitmapInfo* info, void* pixels, float brightnessValue){
    int xx, yy, red, green, blue;
    uint32_t* line;

    for(yy = 0; yy < info->height; yy++){
            line = (uint32_t*)pixels;
            for(xx =0; xx < info->width; xx++){


              //extract the RGB values from the pixel
                red     = (int) ((line[xx] & 0x00FF0000) >> 16);
                green   = (int)((line[xx] & 0x0000FF00) >> 8);
                blue    = (int) (line[xx] & 0x00000FF );

        //manipulate each value
        red = rgb_clamp((int)(red * brightnessValue));
        green = rgb_clamp((int)(green * brightnessValue));
        blue = rgb_clamp((int)(blue * brightnessValue));

        // set the new pixel back in
        line[xx] =
          ((red << 16) & 0x00FF0000) |
          ((green << 8) & 0x0000FF00) |
          (blue & 0x000000FF);
            }

            pixels = (char*)pixels + info->stride;
        }
}
`
    static int rgb_clamp(int value) {
  if(value > 255) {
    return 255;
  }
  if(value < 0) {
    return 0;
  }
  return value;
}

RGB 值是如何被提取的,这个 rgb_clamp 做了什么。为什么我们要设置新的 Pixell 以及像素 = (char*)pixels + info->stride;作品? 我不是 c/c++ 人,对图像处理知之甚少。 谢谢

【问题讨论】:

    标签: android c++ c image-processing android-ndk


    【解决方案1】:

    首先让我们谈谈一个像素。据我所知,它是至少 3 个通道的组合:r、g 和 b,它们都存储在一个 uint32_t 值中,格式为 0x00RRGGBB(32bit / 4 个通道 = 8bit/通道,因此值范围为 0..255)。因此,要获得分离的 r、g 和 b 值,您需要将它们屏蔽掉,这在//extract the RGB values 下方的三行中完成。例如红色组件... 使用掩码 0x00FF0000 和 &amp; 运算符,您将除红色通道中设置的位之外的每个位都设置为 0。但是当你只是用0x00RRGGBB &amp; 0x00FF0000 = 0x00RR0000 屏蔽它们时,你会得到一个非常大的数字。要获得 0 到 255 之间的值,您还必须将位向右移动,这就是 &gt;&gt;-operator 所做的。因此对于后一个示例:应用掩码后,您得到 0x00RR0000,并将这 16 位右移 (&gt;&gt; 16) 得到0x000000RR,这是一个介于 0 和 255 之间的数字。绿色通道也会发生同样的情况,但是右移 8 位,由于蓝色值已经在“右”位位置,因此无需移位。

    第二个问题:rgb_clamp 做了什么很容易解释。它确保您的 r、g 或 b 值乘以您的亮度因子,不会超过 0..255 的值范围。

    在与亮度因子相乘后,新值被写回到内存中,这与上述提取的顺序相反,这次将它们向左移动并删除我们不希望使用掩码的位.

    处理完图像的一行后,会添加 info-&gt;stride,因为出于优化目的,内存可能会对齐以填充 32 字节边界,因此单行可能比图像宽度更长,因此“其余" 字节被添加到指针中。

    【讨论】:

    • 不客气!顺便说一句,也许您发布的代码复制错误,但我认为蓝色值的提取掩码是错误的,因为它应该是 0x000000FF 而不是 0x00000FF(缺少一个 0)
    • 好的,我测试过了。这个数字是错误的,但应该没有什么坏处,因为编译器在 FF 之前用 0 填充了它。
    • 哦,好吧,这不影响结果。
    • @AquilaRapax +1 这对中继很有帮助
    【解决方案2】:

    首先我建议你在这里阅读 C 书:http://publications.gbdirect.co.uk/c_book/

    接下来我会回答你的问题。

    1. 如何提取 RGB 值

      line 设置为指向像素参数:

      line = (uint32_t*)pixels;

      即pixels是一个32位无符号整数数组

      然后,对于位图的高度和宽度,使用按位与 (&amp;) 和位移右 (&gt;&gt;) 的组合提取 RGB 值。

      让我们看看你是怎么变红的:

      red = (int) ((line[xx] &amp; 0x00FF0000) &gt;&gt; 16);

      这里我们得到当前行,然后用0x00FF0000 作为掩码,这从line 中得到第24-16 位。因此,以 RGB 代码 #123456 为例,我们将在 red 变量中留下 0x00120000。但它仍然在 24-16 位的位置,所以我们右移 16 位以将这些位向下移动到 0x00000012。

      我们对绿色和蓝色值执行此操作,调整 AND 掩码和位数以右移。

      关于二进制算术的更多信息可以在这里找到:http://publications.gbdirect.co.uk/c_book/chapter2/expressions_and_arithmetic.html

    2. rgb_clamp 做了什么

      此函数只是确保红色、绿色或蓝色的值为 0 或以上或 255 及以下。

      如果rbg_clamp的参数为-20,则返回0,用于设置RGB值。如果参数为rbg_clamp 为270,则返回255。

      每种颜色的 RGB 值不得超过 225 或低于 0。在此示例中,255 是最亮的值,0 是最暗的值。

    3. 我们为什么要设置像素回来

      看来我们正在改变像素的亮度,并将值设置回准备显示。

    4. pixels = (char*)pixels + info-&gt;stride; 是如何工作的?

      在不知道AndroidBitmapInfo 类型的info 变量的结构的情况下,我猜info-&gt;stride 指的是位图的字节宽度,因此line 将成为下一次循环迭代的下一行。

    希望有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-27
      • 2011-11-03
      • 2013-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多