Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Is there any function in OpenCV to convert Mat 2 BufferedImage & Vice Versa

I am using Java wrapper to use OpenCV, but converting Mat to BufferedIamge & Vice Versa it takes some time, for Example when I want to convert Mat to BufferedImage it takes 16ms and BufferedImage to Mat it takes 35ms in my machine (4 CPUs, Core i7 2.2GHz, 8G RAM). If I want to continuously perform image processing, the result maybe a little bit slows. Because it is looping all over the image every time. The code which I used is below. My question is, is there any way to do such staff faster? Or is there any function in the OpenCV API that can do this work? If anyone know about, please share with me. Thanks in advance! Note: My machine performance is not bad, if it run in lower configuration than my machine maybe more slow...

public static BufferedImage mat2BufferedImg(Mat in) {
        BufferedImage out;
        byte[] data = new byte[320 * 240 * (int) in.elemSize()];
        int type;
        in.get(0, 0, data);
        if (in.channels() == 1) {
            type = BufferedImage.TYPE_BYTE_GRAY;
        } else {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        out = new BufferedImage(320, 240, type);
        out.getRaster().setDataElements(0, 0, 320, 240, data);
        return out;
    }


public static Mat bufferedImg2Mat(BufferedImage in) {
        Mat out;
        byte[] data;
        int r, g, b;

        if (in.getType() == BufferedImage.TYPE_INT_RGB) {
            out = new Mat(240, 320, CvType.CV_8UC3);
            data = new byte[320 * 240 * (int) out.elemSize()];
            int[] dataBuff = in.getRGB(0, 0, 320, 240, null, 0, 320);
            for (int i = 0; i < dataBuff.length; i++) {
                data[i * 3] = (byte) ((dataBuff[i] >> 16) & 0xFF);
                data[i * 3 + 1] = (byte) ((dataBuff[i] >> 8) & 0xFF);
                data[i * 3 + 2] = (byte) ((dataBuff[i] >> 0) & 0xFF);
            }
        } else {
            out = new Mat(240, 320, CvType.CV_8UC1);
            data = new byte[320 * 240 * (int) out.elemSize()];
            int[] dataBuff = in.getRGB(0, 0, 320, 240, null, 0, 320);
            for (int i = 0; i < dataBuff.length; i++) {
                r = (byte) ((dataBuff[i] >> 16) & 0xFF);
                g = (byte) ((dataBuff[i] >> 8) & 0xFF);
                b = (byte) ((dataBuff[i] >> 0) & 0xFF);
                data[i] = (byte) ((0.21 * r) + (0.71 * g) + (0.07 * b)); // luminosity
            }
        }
        out.put(0, 0, data);
        return out;
    }