RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1435933
Accepted
DeNRuDi
DeNRuDi
Asked:2022-08-04 04:13:51 +0000 UTC2022-08-04 04:13:51 +0000 UTC 2022-08-04 04:13:51 +0000 UTC

为什么在转换 BGR -> RGBA 时位图中的每 2 行像素都是白色的?

  • 772

UPD。尚未找到解决方案,并且在评论中,有人可能会说,一种水,它没有明确解决问题。他们在评论中写道,他们说,由于整数除法,我得到了这样的结果。如果我将除以 4,那么为什么我会得到一个带有覆盖像素的相似图像?有趣的是,在java我附加的链接的实现中 - 没有除以 4 并且结果正确显示。我还不明白为什么除以 4c++给我的图片比例是 1 比 1,而java没有它的比例是相同的。如果你没有在加号中写除以 4,那么我只能得到四分之一的图片,而且还有白线。

UPD2。找到解决方案。但是我只是想了解-为什么在加号中我们除以rowBytes4,而在我附加的链接中的那个例子中的java中-没有除法,只有+4。然而,结果是一样的。有什么问题,或者我在哪里错过了什么?

我需要将bgr-array 转换为rgb-array。我很想使用现有库中的实现,但它们对我的项目来说太慢了。

我有我自己的jni- 函数c++,它可以转换一个数组,或者更确切地说是Frame从FFmpegFrameGrabber,它将在转换为Bitmap. 我只从那里取这个包:

(ByteBuffer) frame.image[0]; // здесь кадр в bgr-формате

我知道 和 中有不同的转换器opencv,javacv但性能对我的项目非常重要,因为框架必须到达我的神经元。因此,转换为矩阵,然后通过Utils.matToBitmapor转换AndroidFrameConverter,延迟约为 50 ms,不适合我。虽然 native 方法matToBitmap非常快,但它不适合,因为转换javacv Mat到opencvMat需要 ~100ms,这很多。cvtColor不适合类似的问题,因为它需要一个矩阵作为输入。

c++我基于AndroidFrameConverter从方法编写了自己的转换器:

ByteBuffer bgr2rgba(ByteBuffer in, int width, int height, int stride, int rowBytes{...}

我只为 编写了一个转换器ARGB_8888,即每像素 4 个字节。现在我的代码需要大约 8-15 毫秒来转换。但我不明白我在哪里错过了每 2 行像素 yBitmap不显示的部分代码。由于我的专业不强,所以我整理了这段代码:

#include <jni.h>
#include <endian.h>

extern "C"
JNIEXPORT jbyteArray JNICALL Java_com_example_testcpp_MainActivity_frameToBitmap(JNIEnv *env, jobject thiz, jobject in,
                                                    jint width, jint height, jint imageStride,
                                                    jint rowBytes) {

 auto* buf = (uint8_t*)  env->GetDirectBufferAddress(in);

    int* new_buff = new int [4*width*height];

    int _width = width - 1;
    int _height = height - 1;

    for (int y = 0; y < height; y++) {
        int ro = y * imageStride;
        for (int x = 0; x < width; x++) {
            int rgb;
            if (x < _width || y < _height) {
                rgb = *(int*)(buf + y * imageStride + 3 * x);
            } else {
                int b = buf[ro + 3 * x    ] & 0xff;
                int g = buf[ro + 3 * x + 1] & 0xff;
                int r = buf[ro + 3 * x + 2] & 0xff;
                rgb = (r << 16) | (g << 8) | b;
            }
            new_buff[y / 4 * rowBytes + x] = htobe32((rgb << 8) | 0xff);
        }
    }
    jbyteArray jByteArray = env->NewByteArray((jsize)4*width*height);
    env->SetByteArrayRegion(jByteArray, 0, 4*width*height, reinterpret_cast<const jbyte*>(new_buff));
    delete[] new_buff;
    return jByteArray;
}

这是输出图像: 在此处输入图像描述

我在哪里犯c++了代码错误?

java函数调用:

Frame frame = grabber.grabImage();
ByteBuffer in = (ByteBuffer)frame.image[0];
Bitmap bmp = Bitmap.createBitmap(frame.imageWidth, frame.imageHeight, Bitmap.Config.ARGB_8888);
byte [] data = frameToBitmap(in, frame.imageWidth, frame.imageHeight, frame.imageStride, bmp.getRowBytes());
bmp.copyPixelsFromBuffer(ByteBuffer.wrap(data).position(0));

也许有人知道如何快速转换javacv Mat为opencv Mat然后通过快速的本机方法进行转换,Utils.matToBitmap以免创建自己的jni-function?很高兴听到更多关于如何优化和加速此代码的信息。

android java
  • 1 1 个回答
  • 118 Views

1 个回答

  • Voted
  1. Best Answer
    MBo
    2022-08-05T05:25:06Z2022-08-05T05:25:06Z

    在引用代码中,缓冲区中的地址(以字节为单位)是在写入 int 时计算的,这里有一个 int 数组,其中的索引少 4 倍。

    使用整数除法时,如注释中所述,结果不是您所期望的,因为 0/4 = 1/4 = 2/4 = 3/4 = 0. 这就是整数除法在 C 和 Java 中的工作方式。

    在这种情况下,为了得到正确的结果,首先执行乘法然后除法就足够了:

    new_buff[y * rowBytes / 4 + x] =  
    
    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5