Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting `BufferedImage` to `Mat` in OpenCV

How can I convert a BufferedImage to a Mat in OpenCV?

I'm using the JAVA wrapper for OpenCV(not JavaCV). As I am new to OpenCV I have some problems understanding how Mat works.

I want to do something like this. (Based on Ted W. reply):

BufferedImage image = ImageIO.read(b.getClass().getResource("Lena.png"));  int rows = image.getWidth(); int cols = image.getHeight(); int type = CvType.CV_16UC1; Mat newMat = new Mat(rows, cols, type);  for (int r = 0; r < rows; r++) {     for (int c = 0; c < cols; c++) {         newMat.put(r, c, image.getRGB(r, c));     } }  Highgui.imwrite("Lena_copy.png", newMat); 

This doesn't work. Lena_copy.png is just a black picture with the correct dimensions.

like image 504
Jompa234 Avatar asked Feb 19 '13 13:02

Jompa234


2 Answers

I also was trying to do the same thing, because of need to combining image processed with two libraries. And what I’ve tried to do is to put byte[] in to Mat instead of RGB value. And it worked! So what I did was:

1.Converted BufferedImage to byte array with:

byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); 

2. Then you can simply put it to Mat if you set type to CV_8UC3

image_final.put(0, 0, pixels); 

Edit: Also you can try to do the inverse as on this answer

like image 87
andriy Avatar answered Sep 19 '22 03:09

andriy


Don't want to deal with big pixel array? Simply use this

BufferedImage to Mat

public static Mat BufferedImage2Mat(BufferedImage image) throws IOException {     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();     ImageIO.write(image, "jpg", byteArrayOutputStream);     byteArrayOutputStream.flush();     return Imgcodecs.imdecode(new MatOfByte(byteArrayOutputStream.toByteArray()), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED); } 

Mat to BufferedImage

public static BufferedImage Mat2BufferedImage(Mat matrix)throws IOException {     MatOfByte mob=new MatOfByte();     Imgcodecs.imencode(".jpg", matrix, mob);     return ImageIO.read(new ByteArrayInputStream(mob.toArray())); } 

Note, Though it's very negligible. However, in this way, you can get a reliable solution but it uses encoding + decoding. So you lose some performance. It's generally 10 to 20 milliseconds. JPG encoding loses some image quality also it's slow (may take 10 to 20ms). BMP is lossless and fast (1 or 2 ms) but requires little more memory (negligible). PNG is lossless but a little more time to encode than BMP. Using BMP should fit the most cases I think.

like image 33
Sumsuddin Shojib Avatar answered Sep 18 '22 03:09

Sumsuddin Shojib