前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java Bufferdimage与opencv Mat在内存中的转化

java Bufferdimage与opencv Mat在内存中的转化

作者头像
Pulsar-V
发布2019-04-01 14:51:33
2.5K0
发布2019-04-01 14:51:33
举报
文章被收录于专栏:Pulsar-VPulsar-V

以前写Java人脸识别爬虫的时候遇到的问题,最早的时候是用tempfile的形式去解决每一个爬虫线程爬取图片到本地,保存为tempfile,然后opencv再读取出来做处理和识别,但是这样涉及磁盘io,爬虫性能异常缓慢,所以后面思考了一段时间琢磨出来再内存里面对图像进行转化,本质上,图像数据对Java来说都是bytes[]串,所以我的转化过程的思路,就是把byte串取出来,重新组装。 opencv Mat转BufferImage

    public static BufferedImage toBufferedImage(Mat matrix) {
        int type = BufferedImage.TYPE_BYTE_GRAY;
        if (matrix.channels() > 1) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        int bufferSize = matrix.channels() * matrix.cols() * matrix.rows();
        byte[] buffer = new byte[bufferSize];
        matrix.get(0, 0, buffer); // get all pixel from martix
        BufferedImage image = new BufferedImage(matrix.cols(), matrix.rows(), type);
        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        System.arraycopy(buffer, 0, targetPixels, 0, buffer.length);
        return image;
    }

BufferImage转为opencv Mat

    public static Mat bufferToMartix(BufferedImage image) {
        Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
        byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        if (mat != null) {
            try {
                mat.put(0, 0, data);
            } catch (Exception e) {
                return null;
            }
        }
        return mat;
    }

byte数组转opencv Mat

    public static Mat bufferToMartix(byte[] image) throws IOException {
        BufferedImage bImage = ImageIO.read(new ByteArrayInputStream(image));
        byte[] bytes = ((DataBufferByte) bImage.getRaster().getDataBuffer()).getData();
        Mat data = new Mat(bImage.getHeight(), bImage.getWidth(), CvType.CV_8UC3);
        data.put(0, 0, bytes);
        return data;
    }

有意思的是,当我让一个BufferedImage嵌套为

//这里假设b_image里面包含有图像数据
BufferedImage b_image=b_image=new BufferedImage();
Mat matrix=toBufferedImage(bufferToMartix(b_image))

的时候,JVM概率死掉报出Core Error,于是我分离了这两个函数避免嵌套使用,没有去深究这个问题,猜测这可能与JVM的GC(垃圾回收)有关系,而且就算不出现JVM致命错误,这样出来的图像也是有问题的,会缺失很多数据,然后变成一堆噪声和一片白,直观感觉就是toBufferedImage调用结束后图像数据内存就被释放掉了,当bufferToMartix从后面执行的时候取了同样大小的内存区块当做图像,随机产生了JVM致命内存冲突,或者不冲突但是数据混乱的问题,因为不是专业Java这个地方还待研究。

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档