【问题标题】:GrayScaled Image losing its brightness in NDK(C/C++) Android灰度图像在 NDK/C++) Android 中失去亮度
【发布时间】:2014-04-08 08:11:52
【问题描述】:

我正在使用 ARGB_8888 配置传递位图。 我可以将灰度效果应用于图像,但应用后我失去了亮度。

我用谷歌搜索了很多,但找到了与我相同的实现。

这是我的原生实现::

JNIEXPORT void JNICALL Java_com_example_ndksampleproject_MainActivity_jniConvertToGray(JNIEnv * env, jobject  obj, jobject bitmapcolor,jobject bitmapgray)
{
    AndroidBitmapInfo  infocolor;
    void*              pixelscolor;
    AndroidBitmapInfo  infogray;
    void*              pixelsgray;
    int                ret;
    int             y;
    int             x;

    LOGI("convertToGray");
    if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }

    if ((ret = AndroidBitmap_getInfo(env, bitmapgray, &infogray)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }

    LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infocolor.width,infocolor.height,infocolor.stride,infocolor.format,infocolor.flags);
    if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGE("Bitmap format is not RGBA_8888 !");
        return;
    }

    LOGI("gray image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infogray.width,infogray.height,infogray.stride,infogray.format,infogray.flags);
    if (infogray.format != ANDROID_BITMAP_FORMAT_A_8) {
        LOGE("Bitmap format is not A_8 !");
        return;
    }

    if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    if ((ret = AndroidBitmap_lockPixels(env, bitmapgray, &pixelsgray)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    LOGI("unlocking pixels height = %d",infocolor.height);

    // modify pixels with image processing algorithm

    for (y=0;y<infocolor.height;y++) {
        argb * line = (argb *) pixelscolor;
        uint8_t * grayline = (uint8_t *) pixelsgray;
        for (x=0;x<infocolor.width;x++) {
            grayline[x] = ((255-0.3 * line[x].red) + (255-0.59 * line[x].green) + (255-0.11*line[x].blue))/3;
        }

        pixelscolor = (char *)pixelscolor + infocolor.stride;
        pixelsgray = (char *) pixelsgray + infogray.stride;
    }

    LOGI("unlocking pixels");
    AndroidBitmap_unlockPixels(env, bitmapcolor);
    AndroidBitmap_unlockPixels(env, bitmapgray);
}

结果 ::

如果您需要我这边的任何东西,请告诉我。 请帮助我摆脱这个问题,因为我已经陷入了很多小时。 非常感谢提前!!!

编辑 ::

应用 Mark Setchell 的建议后 ::

已编辑

如果你反转上面的图像,你会得到这个——这对我来说是正确的:

【问题讨论】:

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


【解决方案1】:

不要在计算 grayline[x] 的行上除以 3。您的答案已经正确加权,因为 0.3 + 0.59 + 0.11 = 1

grayline[x] = (255-0.3 * line[x].red) + (255-0.59 * line[x].green) + (255-0.11*line[x].blue);

【讨论】:

  • 我已经尝试过你的建议,但它显示了一些奇怪的结果。请检查我的编辑。
  • 您的图像现在完全正确,只是它倒置了。我已经更正了。
  • 如果我将除以 3,结果保持不变。
  • 没有。使用我的代码后您发布的图像的亮度完全正确,只是倒置了。请复制并粘贴上面的代码行,然后重试 - 现在绝对正确。
  • 如果像我说的那样除以 3,图像必须更亮!
【解决方案2】:

您当前的代码有两个问题。

1)正如其他人所说,不要将最终结果除以三。如果您使用 平均法 计算灰度(例如,gray = (R + G + B) / 3),则需要进行除法。对于您正在使用的 ITU 转换公式,不需要额外的除法,因为小数的总和已经为 1。

2) 发生反转是因为您从 255 中减去每个颜色值。没有必要这样做。

当前公式的正确灰度转换代码是:

grayline[x] = ((0.3 * line[x].red) + (0.59 * line[x].green) + (0.11*line[x].blue));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    相关资源
    最近更新 更多