bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.52k stars 1.58k forks source link

[Q] Convert YUV raw data to RGBA in Android #695

Closed hnvn closed 7 years ago

hnvn commented 7 years ago

I'm trying to convert YUV raw data grabbed from the camera of Android device to RGBA to display in SurfaceView in right way. I try this code: cvtColor(yuvMat, rgbaMat, CV_YUV420sp2RGB); but it's wrong.

screenshot_20170512-180132

What's exact format to convert?

saudet commented 7 years ago

Well, instead of CV_YUV420sp2RGB what about CV_YUV420sp2RGBA?

hnvn commented 7 years ago

Nothing changes. I've already succeeded in using FFmpegFrameFilter before (code). But using FFmpegFrameFilter causes some problems:

So that, I want to replace FFmpegFrameFilter by some operators of OpenCV like cvtColor, transpose, flip to do the same thing. But it still doesn't work.

hnvn commented 7 years ago

@saudet I want to process directly in Mat instead of Frame like that: [Camera] ---- emit---> [byte array] --- put ---> [Mat] ---- convert ----> [Bitmap] ---- draw ----> [Canvas] I try to use some functions of Mat like

mat.data().put(raw);

And convert Mat to Bitmap like:

        Bitmap.Config config = null;
        switch(mat.channels()) {
            case 1:
            case 3:
            case 4:
                config = Bitmap.Config.ARGB_8888;
                break;
            case 2:
                config = Bitmap.Config.RGB_565;
                break;
            default:
                assert false;
        }
        if (cacheBitmap == null || cacheBitmap.isRecycled()
                || cacheBitmap.getWidth() != mat.cols() || cacheBitmap.getHeight() != mat.rows()
                || cacheBitmap.getConfig() != config) {
            if (cacheBitmap != null) cacheBitmap.recycle();
            cacheBitmap = Bitmap.createBitmap(mat.rows(), mat.cols(), config);
        }
        Mat tmp = new Mat(mat.rows(), mat.cols(), CV_8UC4);
        if (mat.type() == CV_8UC1) {
            cvtColor(mat, tmp, COLOR_GRAY2RGBA);
        } else if (mat.type() == CV_8UC3) {
            cvtColor(mat, tmp, COLOR_RGB2RGBA);
        } else if (mat.type() == CV_8UC4) {
            mat.copyTo(tmp);
        }
        cacheBitmap.copyPixelsFromBuffer(tmp.createBuffer());

But it doesn't work.

hnvn commented 7 years ago

I've already tackled this problem by myself. Thanks!

saudet commented 7 years ago

Awesome, if you could provide an explanation for others that are having the same issue, that would be great! Thanks

hnvn commented 7 years ago

The key is a YUV Mat should have frameHeight + frameHeight / 2 rows and frameWidth cols.

saudet commented 7 years ago

Ah yes, that's correct: https://code.google.com/archive/p/javacv/issues/376#c32

That comes up from time to time, a good sample would work wonders.