how to get Integer array from mat object and viceversa - java

I have tried with this 1 code but I am not sure if am right
this is the code which I have tried :
Mat originalImage = Highgui.imread(path);
int[] imageInByte = new int[(int) (originalImage.total() * originalImage.channels())];
also I want to know how to get mat from integer array?

After allocating the array,
byte imageInByte[] = new byte[originalImage.total() * originalImage.channels()];
You can copy the array from C++/JNI,
originalImage.get(0, 0, imageInByte);
To update the array in C++/JNI
originalImage.put(0, 0, imageInByte);

Mat mRgb = Imgcodecs.imread("test.jpg");
MatOfInt iRgb = new MatOfInt(CvType.CV_32S);// middle type
mRgb.convertTo(iRgb, CvType.CV_32S);// 复制mRgb的数据到 iRgb
int[] dataArray = new int[(int)(iRgb.total()*iRgb.channels())];
iRgb.get(0,0, dataArray);// iRgb数据 int[]

Related

Best way to convert RGB byte[][] image to byte[]

Have frame data in the form of a byte[][] object, where each row corresponds to a (R,G,B) channel and is of length (frame width*frame height). I wish to convert it to a byte[] format in a similar vein as follows:
byte[][] original_frame;
byte[] converted_frame = convert(original_frame);
ByteArrayInputStream bis = new ByteArrayInputStream(frame);
BufferedImage bImage2 = ImageIO.read(bis);
From what I can tell, ImageIO assumes a jpeg format. Do I need to convert every frame to a JPEG image, or is there a more natural way to do this?
I believe that you are asking how to convert from a 2D array to 1D array. How to do this if all rows are length 3 is as follows:
ArrayList<byte> x = new ArrayList<byte>();
for(int i=0; i<original_frame.length; i++){
x.add(original_frame[i][0]);
x.add(original_frame[i][1]);
x.add(original_frame[i][2]);
}
byte[] converted_frame= new byte[x.size()];
for(int i=0;i<x.size();i++){
converted_frame[i]=x.get(i);
}
I hope this helps

How to convert Mat to byte array, store the value and then convert it back again? java opencv [duplicate]

This question already has answers here:
OpenCV Mat object serialization in java
(4 answers)
Closed 5 years ago.
I have a Mat image for my system and I want to be able to store it in my sqlite database. So I am thinking I need to try convert it to a byte array to be able to store it. But then Im not sure that is right because I'm unsure how to use the value I get if I was to access it from the db to be able to turn it back into its original Mat image.
Below is what I have come up with so far:
static byte[] matToByte(Mat mat) throws SQLException {
int length = (int) (mat.total()*mat.elemSize());
byte buffer[] = new byte[length];
int converted = mat.get(0, 0, buffer);
IrisInitialDatabase.addFeatures(converted);
return buffer;
}
static Mat byteToMat(byte[] value) {
Mat m = new Mat();
m.put(0, 0, value);
return m;
}
thanks :)
Save it to the database in Base64 format.
Mat to bitmap
Bitmap image = Bitmap.createBitmap(rgba.cols(),
rgba.rows(), Bitmap.Config.RGB_565);
Utils.matToBitmap(rgba, image);
Bitmap bitmap = (Bitmap) image;
bitmap = Bitmap.createScaledBitmap(bitmap, 600, 450, false);
bitmap to byte array
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
---save to database---
get mat back
m = Highgui.imdecode(new MatOfByte(Base64.decode(base64ImageFromDB,0)),Highgui.IMREAD_UNCHANGED);

OpenCV color analysis in HSV

As the title suggests, I am interested in getting the HSV value of a specific pixel using java CV. This sounds easy enough, and it seems to be straight forward in C++ or Python, but I simply cant figure out how to do it in Java. I am pretty new to OpenCV, and if I decide to do more projects using this library I will definitely write them in C++ or Python.
For reference, my goal is to do a color analysis of an object that has varying levels of lighting. The end goal is to be able to take an image of something like a t-shirt and be able to say "this t shirt is x% red".
Here is some of the code I was using. Surprisingly inRange() takes much longer than just looping through every pixel and getting RGB one by one. I want to be able to do exactly this, just with the HSV color space. If you know of a better way to accomplish this goal, please let me know as this has destroyed my entire Saturday. Thanks!
Scalar min = new Scalar(22,11,3);
Scalar max = new Scalar(103,87,74);
int sum = 0;
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
File input = new File("bluesample.jpg");
BufferedImage image = ImageIO.read(input);
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
Mat mat1 = new Mat(image.getHeight(),image.getWidth(),CvType.CV_8UC3);
mat.put(0, 0, data);
Core.inRange(mat, min, max, mat1);
System.out.println(mat1.total());
System.out.println(mat1.total());
for (int i=0;i<mat1.rows(); i++ ){
for (int j=0;i<mat1.cols();j++){
sum += mat1.get(j, i, data);
}
}
System.out.println(sum/mat1.total());
EDIT:
try { System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
File input = new File("singlehsvpix.jpg");
BufferedImage image = ImageIO.read(input);
byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
mat.put(0, 0, data);
Mat mat1 = new Mat(image.getHeight(),image.getWidth(),CvType.CV_8UC1);
Imgproc.cvtColor(mat, mat1, Imgproc.COLOR_RGB2HSV);
System.out.println(mat1.dump());
byte[] data1 = new byte[mat1.rows() * mat1.cols() * (int)(mat1.elemSize())];
mat1.get(0, 0, data1);
//BufferedImage image1 = new BufferedImage(mat1.cols(),mat1.rows(), BufferedImage.TYPE_BYTE_GRAY);
BufferedImage image1 = new BufferedImage(mat1.cols(),mat1.rows(), 5);
image1.getRaster().setDataElements(0, 0, mat1.cols(), mat1.rows(), data1);
File output = new File("PLS!.jpg");
ImageIO.write(image1, "jpg", output);
System.out.println(mat1.get(0, 0, data1)); // RELEVANT LINE
System.out.println("Done");
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
Is printing:
[ 54, 213, 193]
3
Done
For this pic, 54, 213, 193 are the BGR values... I guess I don't understand enough about OpenCV to know why my mat1.get is printing 3
So, you want to convert rgb to hsv.
Imgproc.cvtColor(im_rgb, im_hsv, Imgproc.COLOR_RGB2HSV);
Then, process as you like
Edit: in your code, change mat to mat1
for (int i=0;i<mat1.rows(); i++ ){
for (int j=0;i<mat1.cols();j++){
sum += mat.get(j, i, data); //this line
}
}
System.out.println(sum/mat1.total());
You are adding the value in original matrix.

How to convert mat(OpenCV) to image(JavaFX)?

How to convert mat(OpenCV) to image(JavaFX)?
I think this isn't not best method:
MatOfByte byteMat = new MatOfByte();
Highgui.imencode(".bmp", mat, byteMat);
return new Image(new ByteArrayInputStream(byteMat.toArray()));
P.S.
Image - import javafx.scene.image.Image;
One way to do it would be this.I do not remember the source from where I got this:-
private Image mat2Image(Mat frame)
{
int type = BufferedImage.TYPE_BYTE_GRAY;
if ( frame.channels() > 1 ) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = frame.channels()*frame.cols()*frame.rows();
byte [] b = new byte[bufferSize];
frame.get(0,0,b); // get all the pixels
BufferedImage image = new BufferedImage(frame.cols(),frame.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(b, 0, targetPixels, 0, b.length);
return SwingFXUtils.toFXImage(image,null);
}
There may be a way to make it neater using the Converters class from Opencv along with JDK8. I will update this if I find any such thing.
Paritosh, the issue with your method is that it only applies to the Mats with the type of CvType.CV_8U or CvType.CV_8S, since those Mats can be contained in a byte array. If the type of the Mat is, lets say, CvType.CV_32F, you would need a float array to hold the data. The float array cannot be System.arraycopied into a byte[] targetPixels array.

Converting int[] to bytes[] Java

I am trying to convert an int[] to bytes . It gets converted also.
My code for conversion is this.
public static byte[] convertIntoBytes(int[] menuIds){
byte[] byteConverted;
ByteBuffer byteBuffer = ByteBuffer.allocate(menuIds.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(menuIds);
byteConverted = byteBuffer.array();
for (int i = 0; i < 840; i++) {
Log.d("Bytes sfter Insert", ""+byteConverted[i]);
}
return byteConverted;
}
Suppose i an inputting an int[] = {10,11,15,41,12,8,4,23,5,17,23,36,6}
Now i want the byte array to be like this
{10,0,0,0,11,0,0,0,15,0,0,0,41,0,0,0,12,0,0,0,8,0,0,0,4,0,0,0,23,0,0,0,5,0,0,0,17,0,0,0,23,0,0,0,36,0,0,0,6,0,0,0}
But the byte array coming to be is
{0,0,0,10,0,0,0,11,0,0,0,15,0,0,0,41,0,0,0,12,0,0,0,8,0,0,0,4,0,0,0,23,0,0,0,5,0,0,0,17,0,0,0,23,0,0,0,36,0,0,0,6,}
Actually i am trying to get the byte array to be start from first position.
try this
...
ByteBuffer byteBuffer = ByteBuffer.allocate(menuIds.length * 4);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
...
That depends on bits order on current machine.

Categories