package tools; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.xml.bind.DatatypeConverter; import jdk.nashorn.internal.parser.JSONParser; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfByte; import org.opencv.core.MatOfKeyPoint; import org.opencv.core.Point; import org.opencv.features2d.KeyPoint; import org.opencv.highgui.Highgui; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; public class OpenCVUtils { static int windowNo = 0; /** * Display image in a frame * * @param title * @param img */ public static void imshow(String title, Mat img) { // Convert image Mat to a jpeg MatOfByte imageBytes = new MatOfByte(); Highgui.imencode(".jpg", img, imageBytes); try { // Put the jpeg bytes into a JFrame window and show. JFrame frame = new JFrame(title); frame.getContentPane().add(new JLabel(new ImageIcon(ImageIO.read(new ByteArrayInputStream(imageBytes.toArray()))))); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); frame.setLocation(30 + (windowNo*20), 30 + (windowNo*20)); windowNo++; } catch (Exception e) { e.printStackTrace(); } } public static String matToJson(Mat mat){ JsonObject obj = new JsonObject(); if(mat.isContinuous()){ int cols = mat.cols(); int rows = mat.rows(); int elemSize = (int) mat.elemSize(); byte[] data = new byte[cols * rows * elemSize]; mat.get(0, 0, data); obj.addProperty("rows", mat.rows()); obj.addProperty("cols", mat.cols()); obj.addProperty("type", mat.type()); // We cannot set binary data to a json object, so: // Encoding data byte array to Base64. String dataString = DatatypeConverter.printBase64Binary(data); // String dataString = new String(Base64.encode(data, Base64.DEFAULT)); obj.addProperty("data", dataString); Gson gson = new Gson(); String json = gson.toJson(obj); return json; } else { System.err.println("mat not continuous"); } return "{}"; } public static Mat matFromJson(String json){ JsonParser parser = new JsonParser(); JsonObject JsonObject = parser.parse(json).getAsJsonObject(); int rows = JsonObject.get("rows").getAsInt(); int cols = JsonObject.get("cols").getAsInt(); int type = JsonObject.get("type").getAsInt(); String dataString = JsonObject.get("data").getAsString(); byte[] data = DatatypeConverter.parseBase64Binary(dataString); // byte[] data = Base64.decode(dataString.getBytes(), Base64.DEFAULT); Mat mat = new Mat(rows, cols, type); mat.put(0, 0, data); return mat; } public static double euclideanDist(double[] array1, double[] array2) { double Sum = 0.0; for(int i=0;i<array1.length;i++) { Sum = Sum + (array1[i]-array2[i])*(array1[i]-array2[i]); } return Math.sqrt(Sum); } public static boolean saveMatToFile(File file, Mat mat) { Writer fw = null; try { fw = new FileWriter( file ); String jsonString = matToJson(mat); System.out.println("json string:" + jsonString); fw.write( jsonString ); fw.append( System.getProperty("line.separator") ); // e.g. "\n" } catch ( Exception e ) { System.err.println( "I/O error" ); e.printStackTrace(); } finally { if ( fw != null ) try { fw.close(); System.out.println("wrote file...");return true; } catch ( IOException e ) { e.printStackTrace(); } } return false; } public static Mat loadMatFromFile(File file) { BufferedReader br; Mat mat = null; try { br = new BufferedReader(new FileReader(file)); String line; String jsonString= ""; while((line = br.readLine()) != null) { jsonString+=line; } mat = matFromJson(jsonString); br.close(); } catch (Exception e) { e.printStackTrace(); } return mat; } public static double getEuclideanDistance(Point a, Point b) { return Math.sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); } public static MatOfKeyPoint loadKeyPointsFromFile(File file) { BufferedReader br; Mat mat = null; String jsonString= ""; try { br = new BufferedReader(new FileReader(file)); String line; while((line = br.readLine()) != null) { jsonString+=line; } br.close(); } catch (Exception e) { e.printStackTrace(); } return keypointsFromJson(jsonString); } public static boolean saveKeyPointsToFile(File file, MatOfKeyPoint matOfKeyPoint) { Writer fw = null; try { fw = new FileWriter( file ); String jsonString = keypointsToJson(matOfKeyPoint); System.out.println("json string:" + jsonString); fw.write( jsonString ); fw.append( System.getProperty("line.separator") ); // e.g. "\n" } catch ( Exception e ) { System.err.println( "I/O error" ); e.printStackTrace(); } finally { if ( fw != null ) try { fw.close(); System.out.println("wrote file...");return true; } catch ( IOException e ) { e.printStackTrace(); } } return false; } public static String keypointsToJson(MatOfKeyPoint mat){ if(mat!=null && !mat.empty()){ Gson gson = new Gson(); JsonArray jsonArr = new JsonArray(); KeyPoint[] array = mat.toArray(); for(int i=0; i<array.length; i++){ KeyPoint kp = array[i]; JsonObject obj = new JsonObject(); obj.addProperty("class_id", kp.class_id); obj.addProperty("x", kp.pt.x); obj.addProperty("y", kp.pt.y); obj.addProperty("size", kp.size); obj.addProperty("angle", kp.angle); obj.addProperty("octave", kp.octave); obj.addProperty("response", kp.response); jsonArr.add(obj); } String json = gson.toJson(jsonArr); return json; } return "{}"; } public static MatOfKeyPoint keypointsFromJson(String json){ MatOfKeyPoint result = new MatOfKeyPoint(); JsonParser parser = new JsonParser(); JsonArray jsonArr = parser.parse(json).getAsJsonArray(); int size = jsonArr.size(); KeyPoint[] kpArray = new KeyPoint[size]; for(int i=0; i<size; i++){ KeyPoint kp = new KeyPoint(); JsonObject obj = (JsonObject) jsonArr.get(i); Point point = new Point( obj.get("x").getAsDouble(), obj.get("y").getAsDouble() ); kp.pt = point; kp.class_id = obj.get("class_id").getAsInt(); kp.size = obj.get("size").getAsFloat(); kp.angle = obj.get("angle").getAsFloat(); kp.octave = obj.get("octave").getAsInt(); kp.response = obj.get("response").getAsFloat(); kpArray[i] = kp; } result.fromArray(kpArray); return result; } public static BufferedImage mat2Img(Mat in) { BufferedImage out; int w = in.cols(); int h = in.rows(); byte[] data = new byte[w * h * (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(w, h, type); out.getRaster().setDataElements(0, 0, w, h, data); return out; } public static Mat img2Mat(BufferedImage in) { Mat out; byte[] data; int r, g, b; int w = in.getWidth(); int h = in.getHeight(); // if(in.getType() == BufferedImage.TYPE_INT_BGR) // if(in.getType() == BufferedImage.TYPE_INT_RGB) if(in.getType() == BufferedImage.TYPE_INT_ARGB) { out = new Mat(h, w, CvType.CV_8UC3); data = new byte[w * h * (int)out.elemSize()]; int[] dataBuff = in.getRGB(0, 0, w, h, null, 0, w); 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); // data[i*3] = (byte) ((dataBuff[i] >> 24) & 0xFF); // data[i*3 + 1] = (byte) ((dataBuff[i] >> 16) & 0xFF); // data[i*3 + 2] = (byte) ((dataBuff[i] >> 8) & 0xFF); // 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 { System.out.println("bw"); out = new Mat(h, w, CvType.CV_8UC1); data = new byte[w * h * (int)out.elemSize()]; int[] dataBuff = in.getRGB(0, 0, w, h, null, 0, w); for(int i = 0; i < dataBuff.length; i++) { r = (byte) ((dataBuff[i] >> 24) & 0xFF); g = (byte) ((dataBuff[i] >> 16) & 0xFF); b = (byte) ((dataBuff[i] >> 8) & 0xFF); // 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; } }