How to get and modify the pixel of Mat in Java?
I want to read and modify some pixels in my matrix. How can I do that in Java? Is there any equivalent for the C++ Mat::at method?
I want to read and modify some pixels in my matrix. How can I do that in Java? Is there any equivalent for the C++ Mat::at method?
In Java you can use Mat::get()
and Mat::put()
methods.
One pixel can be read by
double[] Mat::get(int row, int col)
One or few pixels can be written by
Mat::put(int row, int col, double... data)
But if you're going to work with many pixels, it's better to get all the Mat data at once to Java primitive array, work with it in Java, and then put it back to Mat with a single JNI call. The corresponding Java primitive array type depends on the Mat type:
CV_8U and CV_8S -> byte[],
CV_16U and CV_16S -> short[],
CV_32S -> int[],
CV_32F -> float[],
CV_64F-> double[].
So the code will look like following:
Mat m = ... // assuming it's of CV_8U type
byte buff[] = new byte[m.total() * m.channels()];
m.get(0, 0, buff);
// working with buff
// ...
m.put(0, 0, buff);
Thanks for the answer. However I don't quite understand the use of the byte array. I tried, based on the above suggestion, using m.get(0, 0, buff), and m.get(0,0)[0] (for a grayscale image). The latter resulted in the expected value; the former however (using the byte array) gave a large value (exceeding 255) that I don't understand. My image is of type CV_8U.
Role of an array in Mat Pixel access/modify:
Consideran Mat 2*2 with single channel of type byte.Represent it with by m
get the image data m.rows->2; m.cols->2; m.typ->8uc1;
suppose elements in m are,
5 10 15 20
m.get(0,0)[0] -->5;;//returns only specified location element.
Means we have to call m.get() 4 times to get all elements in m.
Use af array in accessing;
Suppose byte [] b=new byte[2];//size is 2 here
m.get(0,b)--> {5,10};//retuns the row of length specified by byte b
where 0--> id for row of mat ..To get next row we should use 1
now, b[0]-->5; b[1]-->10;
Means we have to call m.get() 2 times to get all elements in m.
"m.get() 2 times" is speeder than "m.get() 4 times ...(more)
How do I get the value of R, G and B from the Mat of type CV_8UC3?
To separate from serial to parallel arrangement of the channels, for example to get R, B, and B from the Mat of type CV_8UC3
public static byte[][] getMultiChannelArray(Mat m) {
//first index is pixel, second index is channel
int numChannels=m.channels();//is 3 for 8UC3 (e.g. RGB)
int frameSize=m.rows()*m.cols();
byte[] byteBuffer= new byte[frameSize*numChannels];
m.get(0,0,byteBuffer);
//write to separate R,G,B arrays
byte[][] out=new byte[frameSize][numChannels];
for (int p=0,i = 0; p < frameSize; p++) {
for (int n = 0; n < numChannels; n++,i++) {
out[p][n]=byteBuffer[i];
}
}
return out;
}
Note: signed byte in java may need to be promoted to int
Asked: 2012-06-08 08:47:00 -0600
Seen: 60,314 times
Last updated: Aug 20 '17
android: how to put a column into Mat
Unresolved inclusion in OpenCV+Android tutorial
What is the most effective way to access cv::Mat elements in a loop?
How to convert Floating point image to 32-bit single-channel?
Is there penalty for reference counting in Mat?
Saving an image with unset pixels
How to translate this to Java?