Get jpeg encoded in base64 string into Mat in Java.
I am trying to do a simple face detection example in Java, similar to what was done in the Introduction to Java Development article. When I load a jpeg image using Highgui.imread(path)
, everything works fine. But the images I am using come from an API that returns base64 encoded jpegs. My code for handling the base64 strings looks like this:
CascadeClassifier classifier = new CascadeClassifier(getClass().getResource("/lbpcascade_frontalface.xml").getPath());
// img is a String
byte[] bytes = parseBase64Binary(img); // This function is found in javax.xml.bind.DatatypeConverter
Mat image = new Mat;
image.put(0, 0, bytes);
MatOfRect faceDetections = new MatOfRect();
classifier.detectMultiScale(image, faceDetections);
This does not work. I tested it by encoding an image in which a face was successfully detected when loaded directly:
DataBufferByte byteBuffer = (DataBufferByte) ImageIO.read(new File(path_to_file_that_worked_before)).getRaster.getDataBuffer();
String img = printBase64Binary(byteBuffer.getData);
No faces are detected. Any idea what I am doing wrong?
parseBase64Binary probably does not return pixels, but a whole image. headers, compression and all.
you'll have to imdecode the bytes[] to make a Mat
http://docs.opencv.org/java/org/opencv/highgui/Highgui.html#imdecode(org.opencv.core.Mat,%20int)
@berak Can you elaborate? I had seen that function before, but it takes a Mat as input.
Mat ocvImg = Highgui.imdecode(new MatOfByte(bytes), Highgui.IMREAD_UNCHANGED);
@berak The results didn't change. However, I noticed that when I tried writing out the image using
Highgui.imwrite
, the image is empty. This might explain why no faces are detected. Any thoughts on why the image turns up empty? The byte array that I am using to create the Mat is not empty.yes you're right. empty image -- no faces detected.
i'm a bit out of ideas. but it was a jpg, no ?
if the byte array does not start with ff d8 and end with ff d9, then it's corrupted.
you'er sure, parseBase64Binary is doing the right thing there ? (is it the right func to use even ?)