Skip to content

Commit cb9a310

Browse files
Add files via upload
1 parent 865d66e commit cb9a310

File tree

5 files changed

+342
-0
lines changed

5 files changed

+342
-0
lines changed

Diff for: CMakeLists.txt

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
2+
PROJECT( OpenJpegTrial )
3+
4+
# Check system type by counting bytes
5+
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
6+
MESSAGE( "64 bits compiler detected" )
7+
SET( EX_PLATFORM "64" )
8+
SET( EX_PLATFORM_NAME "x64" )
9+
else()
10+
MESSAGE( "32 bits compiler detected" )
11+
SET( EX_PLATFORM "86" )
12+
SET( EX_PLATFORM_NAME "x86" )
13+
endif()
14+
15+
# Instruct CMake to prepare files for c++11
16+
SET(CMAKE_CXX_FLAGS "-std=c++11")
17+
18+
# Find includes in corresponding build directories
19+
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
20+
21+
# Find useful libs
22+
FIND_PACKAGE( OpenCV )
23+
FIND_PACKAGE( OpenJPEG )
24+
25+
#Includes are used at compilation time
26+
#At runtime, dlls are searched if no static lib are embedded
27+
#if dlls not found, search the path
28+
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
29+
INCLUDE_DIRECTORIES(${OPENJPEG_INCLUDE_DIRS}
30+
"D:/lib/openjpeg/build${EX_PLATFORM}/src/lib/openjp2"
31+
"D:/lib/openjpeg/build${EX_PLATFORM}/src/bin/common"
32+
"D:/lib/openjpeg/src/lib/"
33+
"D:/lib/openjpeg//src/bin/")
34+
35+
FILE(GLOB SRC
36+
"*.cpp"
37+
38+
)
39+
40+
41+
FILE(GLOB dlls
42+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ocv331/msvc2015_${EX_PLATFORM_NAME}/Release/opencv_core331.dll"
43+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ocv331/msvc2015_${EX_PLATFORM_NAME}/Release/opencv_imgproc331.dll"
44+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ocv331/msvc2015_${EX_PLATFORM_NAME}/Release/opencv_imgcodecs331.dll"
45+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ocv331/msvc2015_${EX_PLATFORM_NAME}/Release/opencv_highgui331.dll"
46+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ojpg230/msvc2015_${EX_PLATFORM_NAME}/Release/*.dll"
47+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ojpg230/msvc2015_${EX_PLATFORM_NAME}/Release/*.lib")
48+
49+
FILE(GLOB platformsplugins
50+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/qt510/msvc2015_${EX_PLATFORM_NAME}/plugins/platforms/qwindows.dll")
51+
52+
add_executable(${PROJECT_NAME}
53+
${SRC}
54+
${RESSOURCES})
55+
56+
target_link_libraries(${PROJECT_NAME}
57+
${OpenCV_LIBS}
58+
#${OPENJPEG_LIBRARIES}
59+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ojpg230/msvc2015_${EX_PLATFORM_NAME}/Release/*.lib")
60+
61+
# Instruct CMake to use NSIS with CPACK to create an intaller
62+
SET(CPACK_GENERATOR NSIS)
63+
SET(CPACK_PACKAGE_NAME "OpenJpegTrial")
64+
SET(CPACK_PACKAGE_VENDOR "CMake.org")
65+
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OpenJpegTrial - Because we need it")
66+
SET(CPACK_PACKAGE_VERSION "0.0.1")
67+
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
68+
SET(CPACK_PACKAGE_VERSION_MINOR "0")
69+
SET(CPACK_PACKAGE_VERSION_PATCH "1")
70+
SET(CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME})
71+
SET(CPACK_NSIS_MODIFY_PATH ON)
72+
73+
# TARGETS are executables, they should be located on the side of the dlls
74+
install(TARGETS OpenJpegTrial
75+
76+
RUNTIME DESTINATION bin
77+
78+
COMPONENT app)
79+
80+
# Install VC redist (see on visual studio website)
81+
install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/vc2015/vc_redist_2015_${EX_PLATFORM_NAME}.exe
82+
DESTINATION tmp
83+
COMPONENT redistributables)
84+
85+
# Our dll
86+
install(FILES ${dlls}
87+
DESTINATION bin
88+
COMPONENT dependencies)
89+
90+
91+
INCLUDE(CPack) #should be at the end
92+
cpack_add_install_type(Full DISPLAY_NAME "Install everything")
93+
cpack_add_install_type(Extra DISPLAY_NAME "Install lib for developers")
94+
cpack_add_component(app
95+
INSTALL_TYPES Full)
96+
cpack_add_component(redistributables
97+
INSTALL_TYPES Full)
98+
cpack_add_component(dependencies
99+
INSTALL_TYPES Full)
100+
#cpack_add_component(lib
101+
# INSTALL_TYPES Full Extra) #Define that component "lib" is installed when selecting "Full" and "Extra" type
102+
103+
104+
#Add postbuild commands
105+
#L'avantage, c'est quand on nettoie ça nettoie vraiment tout ce qu'il faut
106+
#For OpenCV dll
107+
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
108+
COMMAND ${CMAKE_COMMAND} -E copy_directory
109+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ocv331/msvc2015_${EX_PLATFORM_NAME}/Release/"
110+
"$<TARGET_FILE_DIR:${PROJECT_NAME}>"
111+
)
112+
113+
#For OpenJpeg dll
114+
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
115+
COMMAND ${CMAKE_COMMAND} -E copy_directory
116+
"${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ojpg230/msvc2015_${EX_PLATFORM_NAME}/Release/"
117+
"$<TARGET_FILE_DIR:${PROJECT_NAME}>"
118+
)

Diff for: README.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# OpenJPEG x OpenCV
2+
3+
A minimal example for integrating OpenJPEG with OpenCV as a replacement for Jasper.
4+
5+
6+
## Why this file ?
7+
This sample code is a minimal example for :
8+
9+
1) using OpenJPEG for decoding .jp2 files - official demonstration
10+
files for OpenJPEG are great but they are far from being "minimal
11+
working versions" of themselves, which complicates the adoption of
12+
OpenJPEG for beginners ; plus the docs of OpenJPEG are still a
13+
work in progress.
14+
15+
2) integrating OpenJPEG with OpenCV in the hope to, one day,
16+
replace Jasper with OpenJPEG in OpenCV - see Issues on
17+
OpenCV's Github.
18+
19+
20+
## What does it do ?
21+
22+
In summary, it demonstrates how to read and decode a .jp2 file
23+
using OpenJPEG. It also demonstrates how to access OpenJPEG data
24+
using simple pointers arithmetics. Finally, it demonstrates how
25+
to painlessly copy OpenJPEG data in an OpenCV cv::Mat. The cv::Mat
26+
is further written as a .jpg file on the disk using the OpenCV
27+
cv::imwrite method to complete the use case demonstration.
28+
29+
Please, be aware that the current version of OpenCV (3.4.1 at the
30+
time) is still using Jasper which is not anymore able to handle
31+
.jp2 files properly. Therefore, if you want to write a .jp2 file
32+
from a cv::Mat, you should better rely on the OpenJPEG encoders
33+
(not demonstrated in this file for the moment).
34+
35+
## Dependencies
36+
- OpenCV >= 3.3.1
37+
- OpenJPEG 2.3.0
38+
- CMake >= 2.8

Diff for: data/res.jpg

23.4 MB
Loading

Diff for: data/trial.jp2

16.5 MB
Binary file not shown.

Diff for: main.cpp

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* File : main.cpp
3+
*
4+
* License : MIT
5+
* Date : 06/2018 (MM/YYYY)
6+
* Author : Rémi Ratajczak (c) Copyright @LIRIS @CLB @ADEME @UnivLyon
7+
* LIRIS stands for
8+
* CLB stands for
9+
* ADEME stands for
10+
* UnivLyon stads for
11+
*
12+
* ------------------------------------------------------------------
13+
* Why this file?
14+
* ------------------------------------------------------------------
15+
* This sample code is a minimal example for :
16+
*
17+
* 1) using OpenJPEG for decoding .jp2 files - official demonstration
18+
* files for OpenJPEG are great but they are far from being "minimal
19+
* working versions" of themselves, which complicates the adoption of
20+
* OpenJPEG for beginners ; plus the docs of OpenJPEG are still a
21+
* work in progress.
22+
*
23+
* 2) integrating OpenJPEG with OpenCV in the hope to, one day,
24+
* replace Jasper with OpenJPEG in OpenCV - see Issues on
25+
* OpenCV's Github.
26+
*
27+
* ------------------------------------------------------------------
28+
* What does it do?
29+
* ------------------------------------------------------------------
30+
* In summary, it demonstrates how to read and decode a .jp2 file
31+
* using OpenJPEG. It also demonstrates how to access OpenJPEG data
32+
* using simple pointers arithmetics. Finally, it demonstrates how
33+
* to painlessly copy OpenJPEG data in an OpenCV cv::Mat. The cv::Mat
34+
* is further written as a .jpg file on the disk using the OpenCV
35+
* cv::imwrite method to complete the use case demonstration.
36+
*
37+
* Please, be aware that the current version of OpenCV (3.4.1 at the
38+
* time) is still using Jasper which is not anymore able to handle
39+
* .jp2 files properly. Therefore, if you want to write a .jp2 file
40+
* from a cv::Mat, you should better rely on the OpenJPEG encoders
41+
* (not demonstrated in this file for the moment).
42+
*
43+
* ------------------------------------------------------------------
44+
* Dependencies
45+
* ------------------------------------------------------------------
46+
* OpenCV >= 3.3.1
47+
* OpenJPEG 2.3.0
48+
* CMake >= 2.8
49+
*
50+
*
51+
*/
52+
53+
////////////////////////////////////////////////////////////////////
54+
// File includes:
55+
#include <opencv2/imgproc.hpp> //OpenCV
56+
#include <opencv2/highgui.hpp> //OpenCV
57+
#include <opencv2/imgcodecs.hpp> //OpenCV
58+
#include <opencv2/core/utility.hpp> //OpenCV
59+
#include <iostream> //stl
60+
#include "openjp2\openjpeg.h" //OpenJPEG
61+
#include "openjp2\opj_common.h" //OpenJPEG
62+
#include "opj_apps_config.h" //OpenJPEG
63+
#include "opj_config.h" //OpenJPEG
64+
65+
////////////////////////////////////////////////////////////////////
66+
// Useful namespaces
67+
using namespace cv;
68+
using namespace std;
69+
70+
////////////////////////////////////////////////////////////////////
71+
// Useful namespaces
72+
bool DEBUG = true;
73+
74+
75+
////////////////////////////////////////////////////////////////////
76+
// Utility for error messages
77+
int error_message(std::string message)
78+
{
79+
std::cerr << message << std::endl;
80+
return false;
81+
}
82+
83+
////////////////////////////////////////////////////////////////////
84+
// Debug messages for an opj_image object
85+
void debug_messages_opj_img(opj_image* opj_img)
86+
{
87+
if (opj_img != NULL && opj_img != nullptr)
88+
{
89+
std::cout << "width : " << opj_img->x0 << " to " << opj_img->x1 << std::endl;
90+
std::cout << "height : " << opj_img->y0 << " to " << opj_img->y1 << std::endl;
91+
std::cout << "numcomps (channels) : " << opj_img->numcomps << std::endl;
92+
std::cout << "colorspace : " << opj_img->color_space << std::endl;
93+
}
94+
}
95+
96+
97+
////////////////////////////////////////////////////////////////////
98+
// Initialize our opj_parameters for a decoder (opj_dparameters)
99+
// Parameters are commidity classes / structs to store data in memory
100+
void set_default_parameters(opj_dparameters* parameters)
101+
{
102+
if (parameters) {
103+
memset(parameters, 0, sizeof(opj_dparameters));
104+
105+
/* default decoding parameters (command line specific) */
106+
parameters->decod_format = -1;
107+
parameters->cod_format = -1;
108+
109+
/* default decoding parameters (core) */
110+
opj_set_default_decoder_parameters(parameters);
111+
}
112+
}
113+
114+
////////////////////////////////////////////////////////////////////
115+
// Stream and decode an .jp2 file, store it in a cv::Mat passed as
116+
// reference
117+
bool getJP2Image(const char* pathToImgWithExtension, cv::Mat & opcv_output)
118+
{
119+
// [x] Check with only opencv 331 compiled in 32 bits (x86) with msvc15 using Visual Studio Community 2017 on Windows 10 and linked through CMake- passed
120+
// [x] Check with opencv 331 and openjpeg 230 both compiled in 32 bits (x86) with msvc12 using Visual Studio Community 2017 on Windows 10 and both linked through CMake - passed
121+
// - Needed to modify the macro in the target_link_libraries instruction in CMakeFile from ${OPENJPEG_LIBRARIES} to path on disk
122+
// (akka : "${CMAKE_CURRENT_SOURCE_DIR}/../redistributables/ojpg230/msvc2015_${EX_PLATFORM_NAME}/Release/*.lib") to compile
123+
// - Needed to modify the macro in the include_directories instruction in CMakeFiles from ${OPENJPEG_BINARY_DIR} to path on disk
124+
// (akka : "D:/lib/openjpeg/build86/src/lib/" ; also included "D:/lib/openjpeg/build86/src/bin/") - did the same with ${OPENJPEG_SOURCE_DIR}
125+
126+
/* Sample OpenJpeg imread image */
127+
opj_dparameters* mparameters = new opj_dparameters();
128+
std::strcpy(mparameters->infile, pathToImgWithExtension);
129+
130+
/* Open a stream on a .jp2 image */
131+
opj_stream_t* mopj_stream_fname = NULL; /* Stream */
132+
mopj_stream_fname = opj_stream_create_default_file_stream(mparameters->infile, true);
133+
if (!mopj_stream_fname) {
134+
fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n", mparameters->infile);
135+
return false;
136+
}
137+
138+
/* Create a decompressor codec */
139+
opj_codec_t* mopj_codec = NULL; /* Handle to a decompressor */
140+
mopj_codec = opj_create_decompress(OPJ_CODEC_JP2); /* select JP2 codec for .jp2 files */
141+
opj_setup_decoder(mopj_codec, mparameters); /* init the decoder */
142+
opj_codec_set_threads(mopj_codec, 4); /* tell the decoder to work on 4 threads */
143+
144+
/* Decode an image with .jp2 format */
145+
opj_image_t* mopj_img = NULL; /* output image */
146+
if (!opj_read_header(mopj_stream_fname, mopj_codec, &mopj_img)) /* you need to read the header before decoding */
147+
return error_message("Unable to read_header in main.");
148+
if (!opj_decode(mopj_codec, mopj_stream_fname, mopj_img)) /* decoding */
149+
return error_message("Unable to decode in main.");
150+
if (DEBUG) debug_messages_opj_img(mopj_img);
151+
152+
/* Copy decoded data in cv::Mat using pointers arithmetics - note that we are copying the data to avoid segfaults */
153+
/* NB : as this is a minimal example, we assume that the .jp2 file represents a grayscale image - a bit more work would be involved to handle multichannels images */
154+
int width = mopj_img->x1;
155+
int height = mopj_img->y1;
156+
int channels = mopj_img->numcomps;
157+
opcv_output = cv::Mat(cv::Size(width, height), CV_8UC1); /* latter, we will need to cast OPJ_INT32 data to uchar */
158+
for(int channel = 0; channel < channels; channel++) /* iterate through the image pixels stored in the components data of an opj_image pointer */
159+
for (int col = 0; col < width; col++)
160+
for (int row = 0; row < height; row++)
161+
opcv_output.at<uchar>(cv::Point(col, row)) = (uchar)*(mopj_img->comps->data++); /* we assume file is continuous on memory adress ; plus be aware of the cast to uchar */
162+
163+
/* Clean memory */
164+
if (mparameters != NULL &&
165+
mparameters != nullptr) delete mparameters;
166+
if (mopj_stream_fname != NULL &&
167+
mopj_stream_fname != nullptr) delete mopj_stream_fname;
168+
if (mopj_codec != NULL &&
169+
mopj_codec != nullptr) delete mopj_codec;
170+
if (mopj_img != NULL &&
171+
mopj_img != nullptr) delete mopj_img;
172+
173+
return true;
174+
}
175+
176+
////////////////////////////////////////////////////////////////////
177+
// Main
178+
int main(void)
179+
{
180+
cv::Mat result; /* create our cv::Mat */
181+
if ( !getJP2Image("../data/trial.jp2", result) ) /* load .jp2 file in it */
182+
return -1;
183+
if ( !result.empty() )
184+
cv::imwrite("../data/res.jpg", result); /* save it as a .jpg file */
185+
return 0;
186+
}

0 commit comments

Comments
 (0)