- Android has a library that allows from Bitmap to Mat and viceversa: org.opencv.android.Utils. This probably would work for us as finally we want to run this on Android, but still, not for the time being (we are in PC...).
- http://stackoverflow.com/questions/14958643/converting-bufferedimage-to-mat-in-opencv
- http://stackoverflow.com/questions/15670933/opencv-java-load-image-to-gui
- http://answers.opencv.org/question/10344/opencv-java-load-image-to-gui/
- http://enfanote.blogspot.com/2013/06/converting-java-bufferedimage-to-opencv.html
UPDATE: please see the code on the first comment below, that ngeen left. I have not tried it in here, but I used it in this other example and it works nicely!!
UPDATE2: triggered by another nice way to do this Mat to BufferedImage conversion, I decided to benchmark all these methods. See here this post for the results.
// Import the basic graphics classes.
// The problem here is that we read the image with OpenCV into a Mat object.
// But OpenCV for java doesn't have the method "imshow", so, we got to use
// java for that (drawImage) that uses Image or BufferedImage (?)
// So, how to go from one the other...
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
//import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
public class Panel extends JPanel{
private static final long serialVersionUID = 1L;
String pic_name="resources/DSC01638.jpg";
Mat picture;
BufferedImage image;
/**
* Converts/writes a Mat into a BufferedImage.
*
* @param matrix Mat of type CV_8UC3 or CV_8UC1
* @return BufferedImage of type TYPE_3BYTE_BGR or TYPE_BYTE_GRAY
*/
public static BufferedImage matToBufferedImage(Mat matrix) {
int cols = matrix.cols();
int rows = matrix.rows();
int elemSize = (int)matrix.elemSize();
byte[] data = new byte[cols * rows * elemSize];
int type;
matrix.get(0, 0, data);
switch (matrix.channels()) {
case 1:
type = BufferedImage.TYPE_BYTE_GRAY;
break;
case 3:
type = BufferedImage.TYPE_3BYTE_BGR;
// bgr to rgb
byte b;
for(int i=0; i<data.length; i=i+3) {
b = data[i];
data[i] = data[i+2];
data[i+2] = b;
}
break;
default:
return null;
}
BufferedImage image = new BufferedImage(cols, rows, type);
image.getRaster().setDataElements(0, 0, cols, rows, data);
return image;
}
// Create a constructor method
public Panel(){
super(); // Calls the parent constructor
picture = Highgui.imread(pic_name);
// Got to cast picture into Image
image=matToBufferedImage(picture);
}
public void paintComponent(Graphics g){
g.drawImage(image,50,10,400,400, this);
}
public static void main(String arg[]){
// Load the native library.
System.loadLibrary("opencv_java245");
JFrame frame = new JFrame("BasicPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,400);
Panel panel = new Panel();
frame.setContentPane(panel);
frame.setVisible(true);
}
}
Then, we want to display the webcam. So, not read from file...
// Import the basic graphics classes.
// The problem here is that we read the image with OpenCV into a Mat object.
// But OpenCV for java doesn't have the method "imshow", so, we got to use
// java for that (drawImage) that uses Image or BufferedImage.
// So, how to go from one the other... Here is the way...
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import org.opencv.core.Mat;
import org.opencv.highgui.VideoCapture;
public class Panel extends JPanel{
private static final long serialVersionUID = 1L;
private BufferedImage image;
// Create a constructor method
public Panel(){
super();
}
private BufferedImage getimage(){
return image;
}
private void setimage(BufferedImage newimage){
image=newimage;
return;
}
/**
* Converts/writes a Mat into a BufferedImage.
*
* @param matrix Mat of type CV_8UC3 or CV_8UC1
* @return BufferedImage of type TYPE_3BYTE_BGR or TYPE_BYTE_GRAY
*/
public static BufferedImage matToBufferedImage(Mat matrix) {
int cols = matrix.cols();
int rows = matrix.rows();
int elemSize = (int)matrix.elemSize();
byte[] data = new byte[cols * rows * elemSize];
int type;
matrix.get(0, 0, data);
switch (matrix.channels()) {
case 1:
type = BufferedImage.TYPE_BYTE_GRAY;
break;
case 3:
type = BufferedImage.TYPE_3BYTE_BGR;
// bgr to rgb
byte b;
for(int i=0; i<data.length; i=i+3) {
b = data[i];
data[i] = data[i+2];
data[i+2] = b;
}
break;
default:
return null;
}
BufferedImage image2 = new BufferedImage(cols, rows, type);
image2.getRaster().setDataElements(0, 0, cols, rows, data);
return image2;
}
public void paintComponent(Graphics g){
BufferedImage temp=getimage();
g.drawImage(temp,10,10,temp.getWidth(),temp.getHeight(), this);
}
public static void main(String arg[]){
// Load the native library.
System.loadLibrary("opencv_java245");
JFrame frame = new JFrame("BasicPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,400);
Panel panel = new Panel();
frame.setContentPane(panel);
frame.setVisible(true);
Mat webcam_image=new Mat();
BufferedImage temp;
VideoCapture capture =new VideoCapture(0);
if( capture.isOpened())
{
while( true )
{
capture.read(webcam_image);
if( !webcam_image.empty() )
{
frame.setSize(webcam_image.width()+40,webcam_image.height()+60);
temp=matToBufferedImage(webcam_image);
panel.setimage(temp);
panel.repaint();
}
else
{
System.out.println(" --(!) No captured frame -- Break!");
break;
}
}
}
return;
}
}
And as we are here, let's finish with the tracking of face and eyes... Tomorrow :)
PS.: Click here to see the index of these series of posts on OpenCV