-
Notifications
You must be signed in to change notification settings - Fork 605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Image Decoder to have consistent behavior across backends #2843
Conversation
f32d81d
to
124cb79
Compare
CI MESSAGE: [2240196]: BUILD STARTED |
CI MESSAGE: [2240196]: BUILD FAILED |
124cb79
to
2db85ec
Compare
CI MESSAGE: [2242201]: BUILD STARTED |
CI MESSAGE: [2242201]: BUILD FAILED |
dali/image/generic_image.cc
Outdated
DALI_ENFORCE(image_type != DALI_ANY_DATA, "Host decoder doesn't support ANY_DATA image type for " | ||
"this image"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can pass IMREAD_ANYCOLOR
and/or IMREAD_UNCHANGED
to imdecode to keep the original number of channels.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checked: neither of these would force OpenCV to keep original color format in JPEGs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is to make sure we are at least consistent and fail instead of providing random results or out-of-bound memory access.
Supporting multichannel image formats is a full-fledged feature, not a quick fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why it would result in out-of-bounds access. Just throwing away support for alpha in PNGs (which OpenCV does support) seems quite wasteful.
batch_size=batch_size_alias_test, N_iterations=10, | ||
eps = 1e-03) | ||
|
||
def test_image_decoder_multi_fail(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fails for CUDA 10 as we don't have nvJPEG2000 there, and we just use host fallback that doesn't apply enforce, but just converts the image to RGB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
- adds a check inside the decoder if the requested image format matches the underlying image - adds check only or JPEG2000 as in case of JPEG only RGB images are supported, for the host fallback DALI always convert to the expected format if requested Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
…g. RGBA) to RGB. Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
fd693eb
to
c5995be
Compare
dali/image/generic_image.cc
Outdated
const auto shape = PeekShapeImpl(encoded_buffer, length); | ||
if (image_type == DALI_ANY_DATA) | ||
image_type = shape[2] == 1 ? DALI_GRAY : DALI_RGB; | ||
const auto C = IsColor(image_type) ? 3 : 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const auto shape = PeekShapeImpl(encoded_buffer, length); | |
if (image_type == DALI_ANY_DATA) | |
image_type = shape[2] == 1 ? DALI_GRAY : DALI_RGB; | |
const auto C = IsColor(image_type) ? 3 : 1; | |
if (image_type == DALI_ANY_DATA) { | |
const auto shape = PeekShapeImpl(encoded_buffer, length); | |
image_type = shape[2] == 1 ? DALI_GRAY : DALI_RGB; | |
} | |
const auto C = IsColor(image_type) ? 3 : 1; |
Peek shape is not free.
dali/image/generic_image.cc
Outdated
assert(shape[0] == H); | ||
assert(shape[1] == W); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we do not need that.
auto r = input[tid]; | ||
auto g = input[tid + comp_size]; | ||
auto b = input[tid + 2 * comp_size]; | ||
output[tid] = 0.299f * r + 0.587f * g + 0.114f * b; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just use rgb_to_y
?
files = glob.glob(os.path.join(test_data_root, "db/single/multichannel/tiff_multichannel") + "/*.tif*") | ||
_testimpl_image_decoder_consistency_multichannel(files) | ||
|
||
def test_image_decoder_consistenty_multichannel_png_with_alpha(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is png and jp2 with alpha.
def test_image_decoder_consistenty_jpeg(): | ||
files = glob.glob(os.path.join(test_data_root, "db/single/jpeg/113") + "/*.jpg*") | ||
_testimpl_image_decoder_consistency(files) | ||
|
||
def test_image_decoder_consistenty_jpeg2k(): | ||
files = glob.glob(os.path.join(test_data_root, "db/single/jpeg2k/0") + "/*.jp2*") | ||
_testimpl_image_decoder_consistency(files) | ||
|
||
def test_image_decoder_consistenty_bmp(): | ||
files = glob.glob(os.path.join(test_data_root, "db/single/bmp/0") + "/*.bmp*") | ||
_testimpl_image_decoder_consistency(files) | ||
|
||
def test_image_decoder_consistenty_png(): | ||
files = glob.glob(os.path.join(test_data_root, "db/single/png/0") + "/*.png*") | ||
_testimpl_image_decoder_consistency(files) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def test_image_decoder_consistenty_jpeg(): | |
files = glob.glob(os.path.join(test_data_root, "db/single/jpeg/113") + "/*.jpg*") | |
_testimpl_image_decoder_consistency(files) | |
def test_image_decoder_consistenty_jpeg2k(): | |
files = glob.glob(os.path.join(test_data_root, "db/single/jpeg2k/0") + "/*.jp2*") | |
_testimpl_image_decoder_consistency(files) | |
def test_image_decoder_consistenty_bmp(): | |
files = glob.glob(os.path.join(test_data_root, "db/single/bmp/0") + "/*.bmp*") | |
_testimpl_image_decoder_consistency(files) | |
def test_image_decoder_consistenty_png(): | |
files = glob.glob(os.path.join(test_data_root, "db/single/png/0") + "/*.png*") | |
_testimpl_image_decoder_consistency(files) | |
def test_image_decoder_consistency(): | |
for img_type in test_good_path: | |
data_path = os.path.join(test_data_root, good_path, img_type) | |
files = glob.glob(data_path + "/*/*.[!txt]*") | |
yield _testimpl_image_decoder_consistency, files[0:10] |
Signed-off-by: Joaquin Anton <janton@nvidia.com>
_testimpl_image_decoder_consistency_multichannel(files) | ||
|
||
def _testimpl_image_decoder_consistency(img_format, img_out_type): | ||
files = get_img_files(os.path.join(test_data_root, good_path, img_format)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to limit the files to 10 or so?
Or it is better to run the test for all of them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the need of limiting the files we send to the reader, we'll test more or less files depending on the batch size and number of iterations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but I cannot approve as this PR is based on my own.
Closed in favor of #2867 |
Why we need this PR?
Pick one, remove the rest
What happened in this PR?
Fill relevant points, put NA otherwise. Replace anything inside []
Consistent handling of ANY_DATA image type. TIFFs support any number of channels, the rest of the formats are limited to 1-channel and 3-channel
Added tests to check that mixed and CPU backends produce the same results.
nvjpeg_decoder_decoupled_api.h
image decoder tests
NA
new tests are added
NA
Relates to #2842
JIRA TASK: [DALI-1948]