安卓相机 : How to process byte data in onPictureTaken using openCV

标签 android opencv

我正在尝试像这样处理来自 JpegImageCallback 的图像

    mContentView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mContentView.getCamera().setPreviewCallback(null);
            mContentView.getCamera().takePicture(null, null, new JpegImageCallback());
        }
    });

JpegImageCallback 看起来像这样

    class JpegImageCallback implements Camera.PictureCallback {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.d(TAG, "onPictureTaken: I am here! data.length=" + data.length);

        Camera.Parameters params = camera.getParameters();
        int fw = params.getPictureSize().width;
        int fh = params.getPictureSize().height;

        Log.d(TAG, "onPictureTaken: PictureFormat: " + params.getPictureFormat()); /* ImageFormat.NV21 */
        Log.d(TAG, "onPictureTaken: PreviewFormat: " + params.getPreviewFormat()); /* ImageFormat.NV21 */

        /* conversion data to Mat */
        Mat mYuvFrameData = new Mat(fh + (fh/2), fw, CvType.CV_8UC1);
        mYuvFrameData.put(0, 0, data);
        Mat rgbImage = new Mat();
        Imgproc.cvtColor(mYuvFrameData, rgbImage, Imgproc.COLOR_YUV2RGBA_NV21, 4);
        Mat gryImage = mYuvFrameData.submat(0, fh, 0, fw);
    }
}

数据到org.opencv.core.Mat的转换是从org.opencv.android.JavaCameraView复制过来的。当数据进入 Camera.PreviewCallback 中的 onPreviewFrame(byte[] frame, Camera camera) 时,它工作得很好。但是在上面的 Camera.PictureCallback 中,我得到的图像是错误的。

拍摄图像后,我将其显示在 ResultActivity 中,如下所示:左侧来自预览且正确,右侧来自图片且错误(绿色)。

Image comes correct in onPreviewFrame image comes wrong in onPictureTaken

我已经将预览和图片中的图像格式更改为相同 (ImageFormat.NV21),但这并没有什么不同。图片的图像格式是ImageFormat.JPEG 如果我不改变的话。

所以问题是:如何将数据转换为 Mat 以便在 onPictureTaken 中获得正确的图像,就像在 onPreviewFrame 中一样?

感谢任何想法!

编辑: 我不想将图像保存到磁盘,也不想将其转换为位图。

最佳答案

这个有效:

        Mat mat = new Mat(new Size(fw, fh), CvType.CV_8U);
        mat.put(0, 0, data);

        Mat rgbImage = Imgcodecs.imdecode(mat, Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
        Mat gryImage = new Mat();
        Imgproc.cvtColor(rgbImage, gryImage, Imgproc.COLOR_RGB2GRAY);

在这里找到:How to retrieve a new picture taken by the camera as OpenCV Mat on Android?

Imgcodecs.imdecode 发挥所有魔力!

顺便说一句,不需要更改图像格式。

关于安卓相机 : How to process byte data in onPictureTaken using openCV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53447626/

相关文章:

visual-studio-2008 - Visual Studio中有关退出声明的错误

c++ - OpenCV:如何从提供的图片中检测粗红线及其轮廓

python - 通过 OpenCV 4.2 利用 GPU

android - findViewById() 为对话框中的 View 返回 null

android - PopupWindow 中 GridView 的 setOnItemClickListener 不起作用

Android - 计时器布局未更新

python - 类型错误 : array is not a numpy array, 都不是标量

Android NDK -multlib 支持使用 gradle

java - Android 计时器的运行速度能否超过 1 毫秒

opencv - 有没有比K更快的聚类方法?