Ask Your Question
2

Is there a way to grab all the pixels of a matrix in Java, operate on every pixel, and then put them all back into the image, using only two JNI calls?

asked 2013-01-19 17:46:31 -0600

Jdban gravatar image

updated 2013-01-19 18:44:16 -0600

I'm trying to do an operation on every pixel (brightness and contrast) and am wondering if I'm missing something. Is there no way to do it smartly in the java?

I'd love my code to look like this:

byte[imagesize*pixels] imagepixels = mRgba.toPixels();

for(int k = 0; k < imagepixels.size; k++
{
   imagepixels[k] = imagepixels[k]*alpha + beta
}

mRgba.put(imagepixels);

But instead it looks like this:

    for( int y = 0;  y < mRgba.rows(); y++)
    {
        for(int x = 0; x < mRgba.cols(); x++)
        {

                dbl = mRgba.get(y, x);
                pix[0] = roundProperly(contrast*(dbl[0]) + brightness);
                pix[1] = roundProperly(contrast*(dbl[1]) + brightness);
                pix[2] = roundProperly(contrast*(dbl[2]) + brightness);
                pix[3] = 0;
                mRgba.put(y, x, pix);
                dbl = null;
        }
    }

There are tons of memory issues because dbl is being malloced extremely frequently and making the garbage collector block, and I'm doing WAY more JNI calls than I'd like.

I plan on porting this into a single C call, but I'm curious to see the straight java performance of this vs the C performance, and I'd prefer there to be a way to do the java this inefficiently.

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
5

answered 2013-01-20 04:50:34 -0600

updated 2013-01-20 09:23:22 -0600

You can use int Mat.get(int row, int col, byte[] data) method of Core.Mat object. Size of retrieved data depends on size of data array. You can call allocate byte array the same size, as matrix data and get all matrix elements. Put method works in the same manner. Your code will be like this:

byte[] data = new byte[mRgba.cols()*mRgba.rows()*mRgba.elemSize()];
mRgba.get(0, 0, data);
...
process(data);
...
mRgba.put(0, 0, data);
edit flag offensive delete link more
2

answered 2013-01-20 05:03:24 -0600

rics gravatar image

I think that you are looking for the more general Mat.convertTo(Mat m, int rtype, double alpha, double beta) function.

The method "converts an array to another data type with optional scaling." The result will reside in m. Moreover "if rtype is negative, the output matrix will have the same type as the input." alpha is the optional scale factor, while beta is the optional delta added to the scaled values.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2013-01-19 17:46:31 -0600

Seen: 1,345 times

Last updated: Jan 20 '13