gpt4 book ai didi

android - 通过 NDK 将数据从 OpenCV Mat 复制到 Surface 会产生小错误。

转载 作者:太空宇宙 更新时间:2023-11-03 23:11:34 24 4
gpt4 key购买 nike

我正在开发一个应用程序,该应用程序将通过 native 方法处理相机帧,然后将处理后的结果发布到 Java TextureView 的 Surface 中。我曾经looking on this application作为引用并将代码实现到我的。但是,我在其中一侧看到一条奇怪的绿色条纹,我认为这是表面宽度和缓冲区步幅之间的差异。我正在尝试制定解决方案,但没有成功。有人可以帮我吗?

本地调用代码如下:

extern "C"
JNIEXPORT jstring JNICALL
Java_com_android_cols2svlc_receiver_utils_JNIHelper_surfaceTest(JNIEnv *env, jclass type, jint srcWidth, jint srcHeight, jobject srcBuffer,
jobject dstSurface, jstring path_, jint savefile) {
const char *str = env->GetStringUTFChars(path_, 0);

// Code

LOGE("bob path:%s saveFile=%d", str, savefile);

uint8_t *srcLumaPtr = reinterpret_cast<uint8_t *>(env->GetDirectBufferAddress(srcBuffer));

if (srcLumaPtr == NULL) {
LOGE("blit NULL pointer ERROR");
return NULL;
}

int dstWidth;
int dstHeight;

cv::Mat mYuv(srcHeight + srcHeight / 2, srcWidth, CV_8UC1, srcLumaPtr);


ANativeWindow *win = ANativeWindow_fromSurface(env, dstSurface);
ANativeWindow_acquire(win);

ANativeWindow_Buffer buf;

dstWidth = srcHeight;
dstHeight = srcWidth;

ANativeWindow_setBuffersGeometry(win, dstWidth, dstHeight, 0 /*format unchanged*/);

if (int32_t err = ANativeWindow_lock(win, &buf, NULL)) {
LOGE("ANativeWindow_lock failed with error code %d\n", err);
ANativeWindow_release(win);
return NULL;
}

uint8_t *dstLumaPtr = reinterpret_cast<uint8_t *>(buf.bits);
Mat dstRgba(dstHeight, buf.stride, CV_8UC4,
dstLumaPtr); // TextureView buffer, use stride as width
Mat srcRgba(srcHeight, srcWidth, CV_8UC4);
Mat flipRgba(dstHeight, dstWidth, CV_8UC4);

// convert YUV -> RGBA
cv::cvtColor(mYuv, flipRgba, CV_YUV2RGBA_NV21);

// Rotate 90 degree
// rotateMat(flipRgba, 2);

LOGE(" ------- DATA ----------- \n dstWidth: %d stride: %d ", dstRgba.cols, buf.stride);

// copy to TextureView surface
uchar *dbuf;
uchar *sbuf;
dbuf = dstRgba.data;
sbuf = flipRgba.data;
int i;
for (i = 0; i < flipRgba.rows; i++) {
dbuf = dstRgba.data + i * buf.stride * 4;
memcpy(dbuf, sbuf, flipRgba.cols * 4);
sbuf += flipRgba.cols * 4;
}


// Draw some rectangles
line(dstRgba, Point(dstWidth/2, 0), Point(dstWidth/2, dstHeight-1),Scalar(255, 255, 255));
line(dstRgba, Point(0,dstHeight-1), Point(dstWidth-1, dstHeight-1),Scalar(255,255,255 ));

LOGE("bob dstWidth=%d height=%d", dstWidth, dstHeight);
ANativeWindow_unlockAndPost(win);
ANativeWindow_release(win);

// Release
env->ReleaseStringUTFChars(path_, str);

//Ret
return env->NewStringUTF("abc");
}

...这就是我得到的输出: Imgur

我还打印了所有尺寸以检查差异:

03-08 10:45:55.234 9681-9706 E/NATIVE_IMPROC:  ------- DATA -----------  
dstWidth: 1152 stride: 1152 dstHeight: 1920

最佳答案

如果 srcBuffer 来自 camera2 图像阅读器,它可能来自 YUV_420_888格式,它有一个可以指定非零步幅的标题,以及到 Y、U 和 V 平面的偏移量。实际上,Y、U、V 帧可能属于不同的 ByteBuffer,但通常相机制造商太懒了。

关于android - 通过 NDK 将数据从 OpenCV Mat 复制到 Surface 会产生小错误。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49171262/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com