Ask Your Question
0

Apply a function to a Mat (like filter2D or map in other language)

asked 2013-09-29 19:03:21 -0600

updated 2013-09-30 06:13:06 -0600

berak gravatar image

Is there a more efficient way than :

Mat mR = new Mat();
    Mat mG = new Mat();
    Mat mB = new Mat(); 
    Core.extractChannel(rgb, mR, 0); mR.convertTo(mR, CvType.CV_64FC1);
    Core.extractChannel(rgb, mG, 1); mG.convertTo(mG, CvType.CV_64FC1);
    Core.extractChannel(rgb, mB, 2); mB.convertTo(mB, CvType.CV_64FC1);
    int size = (int) (mG.total());
    double[] dR = new double[size]; mR.get(0, 0, dR);
    double[] dG = new double[size]; mG.get(0, 0, dG);
    double[] dB = new double[size]; mB.get(0, 0, dB);

    for (int i = size; i-- > 0;) {
        my_function(new Scalar(dR[i],dG[i],dB[i]));     
    }
    mR.put(0, 0, dR);
    mG.put(0, 0, dG);
    mB.put(0, 0, dB);

    mR.convertTo(mR, CvType.CV_8UC1); Core.insertChannel(mR, rgb, 0);
    mG.convertTo(mG, CvType.CV_8UC1); Core.insertChannel(mG, rgb, 1);
    mB.convertTo(mB, CvType.CV_8UC1); Core.insertChannel(mB, rgb, 2);
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2013-10-01 01:54:48 -0600

Michael Burdinov gravatar image

First, you don't need to convert your images from unsigned char to double. Any function that takes double as input will work just as good with unsigned char. And since the output is put inside image of unsigned char, your function should return unsigned char as well. Of course inside your function you can use doubles but its input and output should be unsigned char.

Second, you don't need to split image into channels. The only thing you need to remember is that when you are trying to access neighbor of pixel you should move by three bytes instead of one.

To conclude this: you don't need any temporary containers. Your input and output images are more than enough for functions like filter2D or other similar functions.

P.S. I am not 100% sure about Java since I am working with C++ but I think it should be pretty much the same.

edit flag offensive delete link more

Comments

I've made double because it's the worst, most of opencv use 32F so float

i agree with you to use seperation inside the function

I dont need to split (split doesnt work in my java version), so i use extractchannel), tu as raison, I can use rgb.get(x, y) that give me a double[] with the number of channel

I'm not agree, filter2d give a result like 'multiply then add" i need : point(x, y) = F(point(x, y))

for the moment, i've resolved that by made the mean of a rectangle of (1x1), and apply my_function to this rectangle.

PS :I just need an "map" function to apply a function to each pixel of a Mat(), C++ allow it, not Java.

Pascal66 gravatar imagePascal66 ( 2013-10-01 08:46:35 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2013-09-29 19:03:21 -0600

Seen: 707 times

Last updated: Oct 01 '13