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);
}
}
}
}
}