Skip to content

RFC: Jpeg2000 OpenJPEG port#16494

Merged
alalek merged 14 commits intoopencv:masterfrom
StefanBruens:jpeg2000_openjpeg_port
Mar 27, 2020
Merged

RFC: Jpeg2000 OpenJPEG port#16494
alalek merged 14 commits intoopencv:masterfrom
StefanBruens:jpeg2000_openjpeg_port

Conversation

@StefanBruens
Copy link
Copy Markdown
Contributor

@StefanBruens StefanBruens commented Feb 3, 2020

resolves #5849
relates #14058

Currently missing/incomplete:

  • Write support
  • Reading of "signed" components
  • Reading of precision > 16
  • Reading of > 4 components
  • Color conversion e.g. YUV -> BGR
ci_branch=pr16494
buildworker:Linux x64=linux-4
buildworker:Linux OpenCL=linux-2

Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution!

@StefanBruens StefanBruens force-pushed the jpeg2000_openjpeg_port branch from f9026c8 to fbe7e0f Compare February 3, 2020 21:33
@asmorkalov
Copy link
Copy Markdown
Contributor

@StefanBruens Great job! Could you make find_package for new format silent. See CI bot warnings: https://pullrequest.opencv.org/buildbot/builders/precommit_linux64/builds/24663/steps/cmake/logs/stdio.
Also Imgcodecs module contains some tests for image IO in Jpeg2000 format that are guarded by defined(HAVE_JASPER) && defined(OPENCV_IMGCODECS_ENABLE_JASPER_TESTS) macros. Could you enable them for OpenJPEG too to have automated regression testing with CI bot too.

@alalek
Copy link
Copy Markdown
Member

alalek commented Feb 4, 2020

Please ignore CMake warnings for now. I need to upgrade builders and their configurations first.

Let enable tests for OpenJPEG first.

@StefanBruens StefanBruens force-pushed the jpeg2000_openjpeg_port branch from fbe7e0f to 86142b0 Compare February 4, 2020 12:48
@StefanBruens StefanBruens force-pushed the jpeg2000_openjpeg_port branch 4 times, most recently from 8677157 to e7f039a Compare February 6, 2020 16:19
@StefanBruens
Copy link
Copy Markdown
Contributor Author

The Mac build already uses the OpenJPEG path.

It fails due to the unimplemented RGB->gray conversion when IMREAD_GRAY is used.

Should this just use cv::cvtColor, or fail?

@alalek
Copy link
Copy Markdown
Member

alalek commented Feb 6, 2020

cvtColor call is allowed in imgcodecs module. Yes, you can use it.

@StefanBruens
Copy link
Copy Markdown
Contributor Author

Last remaining error:

CMake Warning at /build/precommit_linux64/ci/cmake_checks/cmake_checks.cmake:105 (message):
  Manual validation is requied.  Variable is not defined: HAVE_OPENJPEG
Call Stack (most recent call first):
  /build/precommit_linux64/ci/cmake_checks/precommit_linux64/POST_FINALIZE.cmake:115 (build_validate_enabled_flag)
  cmake/OpenCVUtils.cmake:52 (include)
  CMakeLists.txt:1596 (ocv_cmake_hook)

Currently, the following input color spaces and depth conversions are
supported:

- 8 bit -> 8 bit
- 16 bit -> 16 bit (IMREAD_UNCHANGED, IMREAD_ANYDEPTH)

- RGB(a) -> BGR
- RGBA -> BGRA (IMREAD_UNCHANGED)
- Y(a) -> Y(a) (IMREAD_ANYCOLOR, IMREAD_GRAY, IMREAD_UNCHANGED))
- YCC -> Y (IMREAD_GRAY)
@alalek
Copy link
Copy Markdown
Member

alalek commented Feb 7, 2020

HAVE_OPENJPEG

Please ignore this for now (this issue is related to infrastructure which will be updated before merge).

There are several packages of OpenJPEG on Ubuntu 16.04:

Looks like they have different versions of OpenJPEG: 1.5 vs 2.1

Please adapt CMake to check applicable version of OpenJPEG (perhaps >= 2.0).
Try something like this

find_package(OpenJPEG 2.0 QUIET)

or check version after that:

if(NOT OPENJPEG_MAJOR_VERSION VERSION_LESS "2")
  ... use OpenJPEG ...
endif()

This enables OpenJPEG based JPEG2000 imread support by default, which
can be disabled by -DWITH_OPENJPEG=OFF. In case OpenJPEG is enabled
and found, any checks for Jasper are skipped.
…ANGED

With IMREAD_UNCHANGED, values are kept from the input image, without it
components are downscaled to CV_8U range.
Support IMREAD_GRAY when input color space is RGB or unspecified.
Support YUV input color space for BGR output.
@StefanBruens
Copy link
Copy Markdown
Contributor Author

find_package(OpenJPEG 2.0 QUIET)

No OpenJPEGVersion.cmake -> manual check required.

@StefanBruens StefanBruens force-pushed the jpeg2000_openjpeg_port branch from 2b0cee3 to 6d6424e Compare February 7, 2020 18:40
@asmorkalov
Copy link
Copy Markdown
Contributor

@StefanBruens Do you have a chance to finish your patch? it brings a lot of value to the library.

@asmorkalov asmorkalov added the Hackathon https://opencv.org/opencv-hackathon-starts-next-week/ label Feb 28, 2020
@VadimLevin VadimLevin force-pushed the jpeg2000_openjpeg_port branch from e857531 to 98f498e Compare March 13, 2020 07:36
@VadimLevin VadimLevin force-pushed the jpeg2000_openjpeg_port branch from 98f498e to c37fd9a Compare March 13, 2020 07:48
@VadimLevin VadimLevin force-pushed the jpeg2000_openjpeg_port branch from c37fd9a to 6f928f6 Compare March 13, 2020 08:14
StefanBruens and others added 3 commits March 13, 2020 15:16
Images with depth CV_8U and CV_16U are supported, with 1 to 4 channels.
 - Removed code duplication
 - Added error handlers
 - Extracted functions
@VadimLevin VadimLevin force-pushed the jpeg2000_openjpeg_port branch from e97fae5 to 6054d18 Compare March 17, 2020 15:06
…d requirements

 - Removed channels split in copyFromMatImpl. With ChannelsIterator no allocations are performed.
 - Split whole loop into 2 parts in copyToMat -> where std::copy and std::transforms are called.
@VadimLevin VadimLevin force-pushed the jpeg2000_openjpeg_port branch from 6054d18 to c9ff248 Compare March 17, 2020 15:25
@VadimLevin
Copy link
Copy Markdown
Contributor

@alalek I've fixed all issues with the memory management in this PR and cherry-picked changes from #16524. Can you proceed with the review?

The only thing that makes this PR red is CMake warning about HAVE_OPENJPEG

Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!


bool Jpeg2KOpjDecoder::readHeader()
{
stream_.reset(opj_stream_create_default_file_stream(m_filename.c_str(), OPJ_STREAM_READ));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_filename.c_str()

Looks like imdecode() from in-memory buffers is not supported at this moment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added support, based on the following PR:

 - Changed `nullptr` in CV_LOG* functions to `NULL`
 - Added `falls through` comment in decoder color space `switch`
 - Added warning about unsupported parameters for the encoder
@VadimLevin VadimLevin force-pushed the jpeg2000_openjpeg_port branch from 42ccb46 to 80838b6 Compare March 26, 2020 08:45
Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done! Thank you 👍

@alalek alalek merged commit 8d78400 into opencv:master Mar 27, 2020
@alalek
Copy link
Copy Markdown
Member

alalek commented Mar 27, 2020

Updated I/O tests (#16922) show large output from OpenJPEG encoding process. Looks like lossless compression is applied.

We need to tune default compression parameters. PSNR 30-35 threshold on mentioned tests should be enough for default compression values.

@arogozhnikov
Copy link
Copy Markdown

arogozhnikov commented Mar 31, 2020

I see this is very recent change (only 4 days ago), but I'm interested in testing openjpeg for my case (uint16 grayscale) to read/write from python.
When should I expect this functionality available in distribution? Thanks!

@asmorkalov
Copy link
Copy Markdown
Contributor

OpenCV 4.3.0 is coming soon.

a-sajjad72 pushed a commit to a-sajjad72/opencv that referenced this pull request Mar 30, 2023
Jpeg2000 OpenJPEG port

* OpenJPEG based JPEG2000 decoder implementation

Currently, the following input color spaces and depth conversions are
supported:

- 8 bit -> 8 bit
- 16 bit -> 16 bit (IMREAD_UNCHANGED, IMREAD_ANYDEPTH)

- RGB(a) -> BGR
- RGBA -> BGRA (IMREAD_UNCHANGED)
- Y(a) -> Y(a) (IMREAD_ANYCOLOR, IMREAD_GRAY, IMREAD_UNCHANGED))
- YCC -> Y (IMREAD_GRAY)

* Check for OpenJPEG availability

This enables OpenJPEG based JPEG2000 imread support by default, which
can be disabled by -DWITH_OPENJPEG=OFF. In case OpenJPEG is enabled
and found, any checks for Jasper are skipped.

* Implement precision downscaling for precision > 8 without IMREAD_UNCHANGED

With IMREAD_UNCHANGED, values are kept from the input image, without it
components are downscaled to CV_8U range.

* Enable Jpeg2K tests when OpenJPEG is available

* Add support for some more color conversions

Support IMREAD_GRAY when input color space is RGB or unspecified.
Support YUV input color space for BGR output.

* fix: problems with unmanaged memory

* fix: CMake warning - HAVE_OPENJPEG is undefined

Removed trailing whitespaces

* fix: CMake find_package OpenJPEG add minimal version

* Basic JPEG2K encoder

Images with depth CV_8U and CV_16U are supported, with 1 to 4 channels.

* feature: Improved code for OpenJPEG2000 encoder/decoder

 - Removed code duplication
 - Added error handlers
 - Extracted functions

* feature: Update conversion openjpeg array from/to Mat

* feature: Extend ChannelsIterator to fulfill RandomAccessIterator named requirements

 - Removed channels split in copyFromMatImpl. With ChannelsIterator no allocations are performed.
 - Split whole loop into 2 parts in copyToMat -> where std::copy and std::transforms are called.

* fix: Applied review comments.

 - Changed `nullptr` in CV_LOG* functions to `NULL`
 - Added `falls through` comment in decoder color space `switch`
 - Added warning about unsupported parameters for the encoder

* feature: Added decode from in-memory buffers.

Co-authored-by: Vadim Levin <vadim.levin@xperience.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: imgcodecs feature Hackathon https://opencv.org/opencv-hackathon-starts-next-week/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Application crashed when imdecode() is called for .jp2 image

5 participants