Ask Your Question
0

Does imdecode return modified image?

asked 2017-03-16 17:15:42 -0600

tom269 gravatar image

Hi guys,

I prepared a grayscale image of dimensions 256x1 and made it contain a gradient of gray (i.e. the left most pixel starts with value 0 (black), the next pixel 1, then 2, 3 and so on until the right most pixel ends with 255 (white)).

When I call imdecode(new Mat(bytes), 6)on this image I would expect to get back a Mat-object that contains just those values. But instead I get a Mat-object with slightly modified values as if it was filtered by Photoshop through a gradation curve similar to the following one (sorry, I am neither allowed to upload an image nor to publish a link, yet). You'll need to follow the link by copy-paste. Gradation Curve: http://www.dropbox.com/s/qs6myb5j03i8vfa/opencvForumQuestion0GradationCurve.jpg?dl=0 (www.dropbox.com/s/qs6myb5j03i8vfa/ope...)

Is this intentional (if so why?), is it a bug or am I doing something wrong?

I very much appreciate your help. Thank you.

Kind regards Thomas

edit retag flag offensive close merge delete

Comments

I don't think you're using imdecode right. First of all, you should almost never do a new Mat(). Certainly not as a parameter to imdecode.

Second, what format did you save the image as?

Tetragramm gravatar imageTetragramm ( 2017-03-16 21:05:54 -0600 )edit

is that java ?

and yes, jpeg compression will modify your color ramp ,(it's not really imdecode related)

if you're concerned about this, avoid jpgs, and rather use png

berak gravatar imageberak ( 2017-03-17 02:16:21 -0600 )edit

I call it from Java, yes. I tried it with PNG first and got my described results. Then I tried JPG, BMP and even TIF all giving me the same results. I understand, that some algorithm (like JPG for example) does some fancy stuff internally, i.e. when storing the image. But I wouldn't expect it from BMP or TIF.

tom269 gravatar imagetom269 ( 2017-03-17 07:27:10 -0600 )edit

@all Thank you for your comments @Tetragramm Why should you not call imdecode the way I described? Btw. I am not calling with new Mat() as parameter but new Mat(bytes) where bytes is an array of bytes (byte[]), just to make sure I understood you correctly. I found this code in a library called DataVec which can be found here: github.com/deeplearning4j/DataVec The lines of code where the magic happens is in a class called NativeImageLoader:

public INDArray asMatrix(InputStream is) throws IOException {
    byte[] bytes = IOUtils.toByteArray(is);
    Mat image = opencv_imgcodecs.imdecode(new Mat(bytes), 6);

I will also file this question in the forum of DataVec but as DataVec directly calls opencv I thought this forum is the right place.

Any idea why this happens?

tom269 gravatar imagetom269 ( 2017-03-17 07:43:54 -0600 )edit

My apologies, I thought it was C++, not Java.

Tetragramm gravatar imageTetragramm ( 2017-03-17 16:38:29 -0600 )edit

1 answer

Sort by » oldest newest most voted
0

answered 2017-03-20 20:16:50 -0600

tom269 gravatar image

I checked it precisely again and found, that opencv's imdecode seems to be correct. It returns back the image I created. This time I made sure, the image contained the values I wanted. I wrote a pgm (P2 mode) image of 256x1 pixels showing a gray scale (so every pixel holds it the same gray value as its position in the row). Then: imdecode returned exactly those values. So Photoshop seems to fail here in this experiment. The first time I created the image with Photoshop. This time I did it by hand (i.e. text editor).

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-03-16 17:15:42 -0600

Seen: 614 times

Last updated: Mar 20 '17