package com.drawbridge.utils; import java.awt.Color; import java.awt.Point; import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.io.ByteArrayInputStream; import java.io.InputStream; import javax.imageio.ImageIO; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfByte; import org.opencv.core.MatOfPoint; import org.opencv.core.Size; import org.opencv.highgui.Highgui; public class CVUtils { /** * Translates each point in the contour by a specified amount * @param contour * @param translation * @return */ public static MatOfPoint translateMatOfPoints(MatOfPoint contour, Point translation) { org.opencv.core.Point[] points = contour.toArray(); for (int i = 0; i < points.length; i++) { points[i].x -= translation.x; points[i].y -= translation.y; } contour.fromArray(points); return contour; } /** * Inverts the matrix. * @param Mat mat -- requires a 3 byte CvType.CV8UC1 * @return */ public static Mat invertMat(Mat mat) { if (mat.type() != CvType.CV_8UC1) throw new RuntimeException("Exception: InvertMat expects mat with type: CV_8UC1"); for (int i = 0; i < mat.rows(); i++) { for (int j = 0; j < mat.cols(); j++) { byte[] data = new byte[3]; mat.get(i, j, data); data[0] = (byte) (255 - data[0]); mat.put(i, j, data); } } return mat; } /** * Returns a buffered image of the mat * @param org.opencv.core.Mat mat * @return */ public static BufferedImage getBufferedImageFromMat(Mat mat) { MatOfByte matOfByte = new MatOfByte(); Highgui.imencode(".jpg", mat, matOfByte); byte[] byteArray = matOfByte.toArray(); BufferedImage bufImage = null; try { InputStream in = new ByteArrayInputStream(byteArray); bufImage = ImageIO.read(in); } catch (Exception e) { e.printStackTrace(); } return bufImage; } /** * Returns a buffered image with transparency based on the given mask * @param org.opencv.core.Mat mat * @param org.opencv.core.Mat Mask * @return */ public static BufferedImage getAlphaBufferedImageFromMat(Mat mat, Mat mask) { if (mask.type() != CvType.CV_32SC1) { throw new RuntimeException("Expected CV_32SC1 in applyMask"); } else if (!mat.size().equals(mask.size())) { throw new RuntimeException("Expected same sized inputs in applyMask"); } MatOfByte matOfByte = new MatOfByte(); Highgui.imencode(".jpg", mat, matOfByte); // was mat byte[] byteArray = matOfByte.toArray(); BufferedImage bufImage = null; try { InputStream in = new ByteArrayInputStream(byteArray); bufImage = ImageIO.read(in); } catch (Exception e) { e.printStackTrace(); } BufferedImage convertedImg = new BufferedImage(bufImage.getWidth(), bufImage.getHeight(), BufferedImage.TYPE_INT_ARGB); convertedImg.getGraphics().drawImage(bufImage, 0, 0, null); // Set alpha according to mask for (int i = 0; i < mask.rows(); i++) { for (int j = 0; j < mask.cols(); j++) { int[] contourVal = new int[1]; mask.get(i, j, contourVal); if (contourVal[0] != -1) { Color transRed = new Color( 0, 0, 0, 0 ); convertedImg.setRGB(j, i, transRed.getRGB()); } } } return convertedImg; } /** * @param BufferedImage image -- expects BufferedImage.TYPE_3BYTE_BGR * @return */ public static Mat getMatFromBufferedImage(BufferedImage image) { if (image.getType() != BufferedImage.TYPE_3BYTE_BGR) throw new RuntimeException("Exception: getMatFromBufferedImage expects BufferedImage.TYPE_3BYTE_BGR as input"); DataBufferByte dbi = (DataBufferByte) image.getRaster().getDataBuffer(); byte[] buff = dbi.getData(); Mat mat = Mat.zeros(new Size(image.getWidth(), image.getHeight()), CvType.CV_8UC3); mat.put(0, 0, buff); return mat; } /** * * @param Mat mat * @param Mat contourMask */ public static void applyMask(Mat mat, Mat contourMask) { if (contourMask.type() != CvType.CV_32SC1) { throw new RuntimeException("Expected CV_32SC1 in applyMask"); } else if (!mat.size().equals(contourMask.size())) { throw new RuntimeException("Expected same sized inputs in applyMask"); } for (int i = 0; i < mat.rows(); i++) { for (int j = 0; j < mat.cols(); j++) { byte[] data = new byte[3]; int[] contourVal = new int[1]; contourMask.get(i, j, contourVal); if (contourVal[0] == 0) { mat.get(i, j, data); data[0] = 0; data[1] = 0; data[2] = 0; mat.put(i, j, data); } } } } }