Delin
September 21, 2022, 8:07am
1
Hi,
I have read some HDR images with imread()
function but got some negative values in an “OpenEXR” format image. The code is like this:
import os
os.environ["OPENCV_IO_ENABLE_OPENEXR"]="1"
import cv2
exr_neg = cv2.imread('-.exr', cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH | cv2.IMREAD_UNCHANGED)
exr_pos = cv2.imread('+.exr', cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH | cv2.IMREAD_UNCHANGED)
hdr = cv2.imread('0005.hdr', cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)
print('exr_neg: min {} | max {}'.format(exr_neg.min(), exr_neg.max()))
print('exr_pos: min {} | max {}'.format(exr_pos.min(), exr_pos.max()))
print('hdr: min {} | max {}'.format(hdr.min(), hdr.max()))
What I am confused about is why the imread()
function return numpy
matrix with some negative pixels. The HDR image file can be download from here .
Could your please share with me what the problem is or any suggestions? Thank you so much in advance!
maybe this is correct? what do other EXR tools (imagemagick, …) tell you about the contents of that file?
This is correct for EXR-format with high-dynamic range images. EXR has support for color floating-point depths. You just need to normalize the matrices.
import os
os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"
import cv2 as cv
exr_neg = cv.imread('-.exr', cv.IMREAD_UNCHANGED)
exr_pos = cv.imread('+.exr', cv.IMREAD_UNCHANGED)
hdr = cv.imread('0005.hdr', cv.IMREAD_UNCHANGED)
cv.namedWindow('exr_neg',
cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO | cv.WINDOW_GUI_EXPANDED)
cv.namedWindow('exr_pos',
cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO | cv.WINDOW_GUI_EXPANDED)
cv.namedWindow('hdr',
cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO | cv.WINDOW_GUI_EXPANDED)
exr_neg = cv.normalize(exr_neg, None, 0, 255, cv.NORM_MINMAX, cv.CV_8U)
exr_pos = cv.normalize(exr_pos, None, 0, 255, cv.NORM_MINMAX, cv.CV_8U)
hdr = cv.normalize(hdr, None, 0, 255, cv.NORM_MINMAX, cv.CV_8U)
print('exr_neg: min {} | max {}'.format(exr_neg.min(), exr_neg.max()))
print('exr_pos: min {} | max {}'.format(exr_pos.min(), exr_pos.max()))
print('hdr: min {} | max {}'.format(hdr.min(), hdr.max()))
cv.imshow('exr_neg', exr_neg)
cv.imshow('exr_pos', exr_pos)
cv.imshow('hdr', hdr)
cv.waitKey(0)
cv.destroyAllWindows()
or
cv.normalize(mat, None, 0, 1, cv.NORM_MINMAX, cv.CV_64F)
numerical inaccuracies. always expect them. your negative numbers (-0.001) are close to 0 anyway, so…
what color space does that file have natively? OpenCV likes to convert to RGB/BGR, while some pictures have some type of yuv space, or lab, or who knows what. that can be a source of numerical errors.
Delin
September 21, 2022, 11:19am
6
Hi crackwitz ,
I print the information of -.exr
:
$ identify -verbose -.exr
Image: -.exr
Format: EXR (High Dynamic-range (HDR))
Class: DirectClass
Geometry: 4288x2412+0+0
Units: Undefined
Colorspace: RGB
Type: TrueColorAlpha
Base type: Undefined
Endianess: Undefined
Depth: 16-bit
Channel depth:
red: 16-bit
green: 16-bit
blue: 16-bit
alpha: 1-bit
Channel statistics:
Pixels: 10342656
Red:
min: 0 (0)
max: 65535 (1)
mean: 27428.7 (0.418535)
standard deviation: 20484.1 (0.312568)
kurtosis: -0.721404
skewness: 0.894195
entropy: 0.82117
Green:
min: 0 (0)
max: 65535 (1)
mean: 34510.8 (0.526601)
standard deviation: 20908 (0.319035)
kurtosis: -1.19547
skewness: 0.471033
entropy: 0.70769
Blue:
min: 71 (0.00108339)
max: 65535 (1)
mean: 45589.1 (0.695645)
standard deviation: 18410 (0.280919)
kurtosis: 0.000131018
skewness: -0.788791
entropy: 0.623624
Alpha:
min: 65535 (1)
max: 65535 (1)
mean: 65535 (1)
standard deviation: -nan (-nan)
kurtosis: -1.61532e+58
skewness: 1.32891e+41
entropy: 0
Image statistics:
Overall:
min: 0 (0)
max: 65535 (1)
mean: 43265.9 (0.660195)
standard deviation: -nan (-nan)
kurtosis: -1.4721
skewness: -0.341945
entropy: 0.538121
Rendering intent: Undefined
Gamma: 1
Background color: rgba(255,255,255,1)
Border color: rgba(223,223,223,1)
Matte color: rgba(189,189,189,1)
Transparent color: rgba(0,0,0,0)
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 4288x2412+0+0
Dispose: Undefined
Iterations: 0
Compression: Undefined
Orientation: Undefined
Properties:
date:create: 2022-09-21T19:08:26+08:00
date:modify: 2022-09-21T19:08:26+08:00
signature: dff017f48502e894aadb188b9ada4fe1cc5316858de1eb3e7b41c2688f6253a4
Artifacts:
filename: -.exr
verbose: true
Tainted: False
Filesize: 32.2277MiB
Number pixels: 10.3427M
Pixels per second: 44.9681MB
User time: 0.230u
Elapsed time: 0:01.230
Version: ImageMagick 6.9.10-23 Q16 x86_64 20190101 https://imagemagick.org
It seems that the image statistics don’t contain negative values
1 Like
fascinating.
your file seems to contain uint16, not floats, yet you get floats, even with IMREAD_UNCHANGED!
does OpenEXR even support uint16? wikipedia says it supports 16 bit floats , and 32 bit unsigned integers.
the identify
suggests that you actually have uint16, not just “half floats” reinterpreted as uint16, because if that were the case, I wouldn’t expect to see 0xFFFF (65535) as a maximum, which is a NaN value.
is this perhaps an artefact of using imagemagick? is this what imagemagick works with after decoding the file? your imagemagick is the Q16
variant, so it’s using more than 8 bits internally… but I don’t know if identify
should report decoded data or the data that’s actually in the file.
perhaps browse the issues on the github and if you can’t find your situation, make a bug report? that is, if you’re sure your file can’t contain negative values.
1 Like
Delin
September 21, 2022, 12:16pm
8
Thank you Saracen24 . But I have no idea what the negative number in EXP means, does it means the pixel is blacker than black?