Reading Image for Template Matching for Java
Im using OpenCV in java and the images are read this way for template matching.
String inFile = "C:/image.png";
Mat img = Highgui.imread(inFile);
This is nice but my images are not in my local computer. I should compare 2000 images on a server in mysql database. Saving 2000 images to my computer and then reading them does not make sense.
So what I need is that Highgui.imread(inFile) reads an image: Highgui.imread(Image inImage) or maybe Highgui.imread(File inFile) , I couldnt find the java source to edit modify. I need someway to convert my images which will be coming from the DB to Mat type for comparison(template matching) ...
More info: I have a mysql table: ID, Name, Description, Image1, Image2. The type of Image1 and 2 columns are "mediumblob" and when you right click to the column Image1 or Image2 in MySQL Workbench I choose "Open Value in Editor" then there are 3 tabs; Binary, Text, Image, at Image my image is displayed perfectly. The type of Images are png. In the end I want to Compare Image1 with Image2. Image2 is inFile and Image1 is templateFile.
I'm sorry I thought my question was clear. I will try to rephrase it. I have a local computer and a server. The images are stored in the mysql database on server. I want to run an application from my local computer that retrieves/accesses 2 images on the server and then compares them via OpenCV template matching. So how Im planning to retrieve the images, havent tried yet but the plan is :
Blob imageBlob = resultSet.getBlob(yourBlobColumnIndex);
InputStream binaryStream = imageBlob.getBinaryStream(0, imageBlob.length());
Or
InputStream binaryStream = resultSet.getBinaryStream(yourBlobColumnIndex);
Or
try{
Class.forName(driverName);
con = DriverManager.getConnection(url+dbName,userName,password);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select image from image");
int i = 0;
while (rs.next()) {
InputStream in = rs.getBinaryStream(1);
OutputStream f = new FileOutputStream(new File("test"+i+".jpg"));
i++;
int c = 0;
while ((c = in.read()) > -1) {
f.write(c);
}
f.close();
in.close();
}
}catch(Exception ex){
System.out.println(ex.getMessage());
}
My Question: I want to compare 2 images, I retrieved from the mysql database.
Highgui.imread();
This method expects a String but I want to give the InputStream or the OutputStream file... Like I said I don't want to save 2000 images on my local computer. I'm open for alternative ways as well.
Final Simplest Rephrasing : How can I use template matching of java OpenCV on 2 images stored on a mysql database.
Thanks for reading.
I'm sorry, but I don't understand what you want. In which format do you have your images? Do you want to read them from a binary format from the db?
imdecode) at least lets you read an image from memory
@FooBar I have a mysql table: ID, Name, Description, Image1, Image2. The type of Image1 and 2 columns are "mediumblob" and when you right click to the column Image1 or Image2 in MySQL Workbench I choose "Open Value in Editor" Then there are 3 Tabs, Binary, Text, Image, at Image my image is displayed perfectly. The type of Images are png. In the end I want to Compare Image1 with Image2. Image2 is inFile and Image1 is templateFile.
could you add, in what format you get your images from the db ? like is it a byte[] ? from your description we already know, that it's a 'complete' image ( like on disk), so the missing link is, how to feed it to imdecode again, to get a Mat.
@berak I updated the question, but imdecode() is expecting a Mat file which I dont have...
untested, so not an answer (yet):
@berak imdecode() requires a flag as well, and when I go to imdecode() explanation it says the same flags as imread, but imread() does not have flags... So what integer value shall I give? I will also check the cpp equivalents...
here's the flags the default is 1 (force to bgr), but you probably want -1 (leave as is)
I guess according to http://docs.opencv.org/java/constant-values.html#org.opencv.highgui.Highgui.CV_LOAD_IMAGE_ANYDEPTH it should be 1,2,4 ?
well, one of it. i'd still propose CV_LOAD_IMAGE_UNCHANGED (you'd want to preserve alpha in a png, if present)
Thanks will try in few minutes.
@berak
OpenCV Error: Assertion failed (buf.data && buf.isContinuous()) in cv::imdecode_, file ........\opencv\modules\highgui\src\loadsave.cpp, line 307 Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: ........\opencv\modules\highgui\src\loadsave.cpp:307: error: (-215) buf.data && buf.isContinuous() in function cv::imdecode_ ] at org.opencv.highgui.Highgui.imdecode_0(Native Method) at org.opencv.highgui.Highgui.imdecode(Highgui.java:181) at MatchingDemo.run(MatchingDemo.java:45) Line 45 I have : Mat img = Highgui.imdecode(mb, -1);
aww, sorry my bad. try Mat , not MatOfByte
(did not work for MatOfByte, no idea why, it's empty)
@break what is numBytesRead ? where do I get it?
return value of in.read(), probably.
or, better even, - imageBlob.length(). (that's probably also the amount of bytes to allocate)
@berak this is the new error I got,
libpng error: PNG input buffer is incomplete OpenCV Error: Assertion failed (corrsize.height <= img.rows + templ.rows - 1 && corrsize.width <= img.cols + templ.cols - 1) in cv::crossCorr, file ........\opencv\modules\imgproc\src\templmatch.cpp, line 70 Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: ........\opencv\modules\imgproc\src\templmatch.cpp:70: error: (-215) corrsize.height <= img.rows + templ.rows - 1 && corrsize.width <= img.cols + templ.cols - 1 in function cv::crossCorr ] at org.opencv.imgproc.Imgproc.matchTemplate_0(Native Method) at org.opencv.imgproc.Imgproc.matchTemplate(Imgproc.java:7621) at MatchingDemo.run(MatchingDemo.java:74) Line 74: Imgproc.matchTemplate(img, templ, reslt, matchmetod);
@berak I found the answer, we were close : http://answers.opencv.org/question/31855/java-api-loading-image-from-any-java-inputstream/ works perfect