* Move STB internally, comment functions if not

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Comment for now STB including macros

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Modify CMake and tests accordingly

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the license and update the date.

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Move STB to its own directory

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Adding the functrions of image resize and crop

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Update the API not finished yet

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Start adding tests

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Add flowers images for test

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Bring image from the coco dataset

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Include all of STB header in this file

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix STB configs

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Clean CMakeLists and look for stb_resize

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Make it compile with STB integrated

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix stb path

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the endif at the end of the file

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Update LICENSE.txt

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update CMakeLists.txt

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/config.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Adding the function and test, not finished

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Remove crop from this PR, and add tests

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Update LICENSE.txt

Co-authored-by: Dirk Eddelbuettel <edd@debian.org>

* Update CMakeLists.txt

Co-authored-by: Dirk Eddelbuettel <edd@debian.org>

* merge master

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Add @rcutin suggestion for stb

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Improve the logic to include edge cases

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the bundle that if we are using system stb

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Make it possible to disable the entire build with STB

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the else if condition

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the else condition

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the tests accordindly

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Add dummpy functions and complete the Resize function

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Reorder to see if this fix the problem

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the resize for a set of images

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Add STATIC for resize and write

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix all the problem with this function

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Be able to resize N images easily

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Add the tests, already passing

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Use sheep instead of Umbrella

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Fix STB directory

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Fix Cmake and docs

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Apply comments from @rcurtin

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Integrate @rcurtin comments

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Fix tests and remove generated images

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Add docs

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Update the API with new resize version

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Fix to resize2

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Adding resize2

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Add the necessary fix to avoid linker errors

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Add configs to allow correct repacking

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Redo the ResizeImages function

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Pack the images as tzr.bz2

Signed-off-by: Omar Shrit <omar@shrit.fr>

* Fix the function calls and create an internal one

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Make the message shorter to have under 80 chars

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Solve linter errors

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Solve linter error

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix linter issues

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Update doc/user/load_save.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/tests/image_test.cpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/core/data/image_resize_crop.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/core/data/image_resize_crop.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/load_save.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/load_save.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/tests/image_test.cpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/tests/image_test.cpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/tests/image_test.cpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/tests/image_test.cpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/core/data/image_resize_crop.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Apply @rcurtin comments

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Add an example usage of these two functions

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Apply @rcurtin comments

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Re-organize directories for STB

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Apply rcurtin comments

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Merge two resize functions into one

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Get rid of MLPACK_DISABLE_STB

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix forgetting docs

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Update CMake/FindStbImage.cmake

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update CMake/FindStbImage.cmake

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/install.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/compile.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/core/data/image_resize_crop.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/load_save.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/load_save.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/load_save.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/load_save.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/core/data/image_resize_crop.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/core/data/image_resize_crop.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update src/mlpack/core/data/image_resize_crop.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update doc/user/load_save.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Apply comments from @rcurtin

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Adding the test to test if it is identical

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix image tests

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the example

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Add the link and the patch to download the images

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Fix the script and make all of them green

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Remove wget not needed

Signed-off-by: Omar Shrit <omar@avontech.fr>

* Minor style fixes.

* Avoid temporary matrices, and test with multiple different types.

* Update src/mlpack/config.hpp

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Update HISTORY.md

Co-authored-by: Ryan Curtin <ryan@ratml.org>

* Fix R build by including bundled STB headers in package.

---------

Signed-off-by: Omar Shrit <omar@avontech.fr>
Signed-off-by: Omar Shrit <omar@shrit.fr>
Co-authored-by: Ryan Curtin <ryan@ratml.org>
Co-authored-by: Dirk Eddelbuettel <edd@debian.org>
This commit is contained in:
Omar Shrit
2025-02-05 21:06:26 +01:00
committed by GitHub
co-authored by Ryan Curtin Dirk Eddelbuettel
parent 9fd815144d
commit 821a95ff56
26 changed files with 20762 additions and 196 deletions
+2 -2
View File
@@ -12,7 +12,7 @@ file(GLOB STB_IMAGE_SEARCH_PATHS
${CMAKE_BINARY_DIR}/deps/
${CMAKE_BINARY_DIR}/deps/stb)
find_path(STB_IMAGE_INCLUDE_DIR_1
NAMES stb_image.h stb_image_write.h
NAMES stb_image.h stb_image_write.h stb_image_resize2.h
PATHS ${STB_IMAGE_SEARCH_PATHS} ${STB_IMAGE_INCLUDE_DIR})
if(STB_IMAGE_INCLUDE_DIR_1)
@@ -26,7 +26,7 @@ if(STB_IMAGE_INCLUDE_DIR_1)
set(STB_INCLUDE_NEEDS_STB_SUFFIX "NO")
else ()
find_path(STB_IMAGE_INCLUDE_DIR_2
NAMES stb_image.h stb_image_write.h
NAMES stb_image.h stb_image_write.h stb_image_resize2.h
PATHS ${STB_IMAGE_SEARCH_PATHS} ${STB_IMAGE_INCLUDE_DIR}
PATH_SUFFIXES stb/)
+12 -20
View File
@@ -16,6 +16,7 @@ option(BUILD_CLI_EXECUTABLES "Build command-line executables." ON)
option(DOWNLOAD_DEPENDENCIES "Automatically download dependencies if not available." OFF)
option(BUILD_GO_SHLIB "Build Go shared library." OFF)
option(USE_PRECOMPILED_HEADERS "Use precompiled headers for mlpack_test build." ON)
option(USE_SYSTEM_STB "Use system STB instead of version bundled with mlpack." OFF)
# Set minimum library versions required by mlpack.
#
@@ -314,20 +315,12 @@ endif()
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS})
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${ARMADILLO_LIBRARIES})
# Find stb_image.h and stb_image_write.h.
if (NOT DOWNLOAD_DEPENDENCIES)
find_package(StbImage)
else()
find_package(StbImage)
if (NOT StbImage_FOUND)
get_deps(https://mlpack.org/files/stb.tar.gz stb stb.tar.gz)
set(STB_IMAGE_INCLUDE_DIR ${GENERIC_INCLUDE_DIR})
find_package(StbImage REQUIRED)
endif()
if (USE_SYSTEM_STB)
find_package(StbImage REQUIRED)
endif()
if (StbImage_FOUND)
set(STB_AVAILABLE "1")
add_definitions(-DMLPACK_USE_SYSTEM_STB)
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} "${STB_IMAGE_INCLUDE_DIR}")
# Make sure that we can link STB in multiple translation units.
@@ -337,7 +330,7 @@ if (StbImage_FOUND)
"multiple translation units! Try upgrading your STB implementation, "
"or using the auto-downloader (set DOWNLOAD_DEPENDENCIES=ON in the "
"CMake configuration command.")
endif ()
endif()
endif()
# Find ensmallen.
@@ -483,18 +476,17 @@ if (BFD_DL_AVAILABLE)
string(REGEX REPLACE "// #define MLPACK_HAS_BFD_DL\n"
"#define MLPACK_HAS_BFD_DL\n" CONFIG_CONTENTS "${CONFIG_CONTENTS}")
endif ()
if (STB_AVAILABLE)
string(REGEX REPLACE "// #define MLPACK_HAS_STB\n"
"#define MLPACK_HAS_STB\n" CONFIG_CONTENTS "${CONFIG_CONTENTS}")
if (NOT STB_INCLUDE_NEEDS_STB_SUFFIX)
string(REGEX REPLACE "// #define MLPACK_HAS_NO_STB_DIR\n"
"#define MLPACK_HAS_NO_STB_DIR\n" CONFIG_CONTENTS "${CONFIG_CONTENTS}")
endif ()
endif ()
if (USING_GIT)
string(REGEX REPLACE "// #define MLPACK_GIT_VERSION\n"
"#define MLPACK_GIT_VERSION\n" CONFIG_CONTENTS "${CONFIG_CONTENTS}")
endif ()
if (USE_SYSTEM_STB)
string(REGEX REPLACE "// #define MLPACK_USE_SYSTEM_STB\n"
"#define MLPACK_USE_SYSTEM_STB\n" CONFIG_CONTENTS "${CONFIG_CONTENTS}")
endif()
file(WRITE ${CMAKE_BINARY_DIR}/include/mlpack/config-local.hpp "${CONFIG_CONTENTS}")
include_directories(${CMAKE_BINARY_DIR}/include/)
add_definitions(-DMLPACK_CUSTOM_CONFIG_FILE=mlpack/config-local.hpp)
+2
View File
@@ -10,6 +10,8 @@ _????-??-??_
* Add `MLPACK_NO_STD_MUTEX` to allow disabling `std::mutex` (#3868).
* Bundle STB with mlpack and add `ResizeImages()` functionality (#3823).
## mlpack 4.5.1
_2024-12-02_
+5 -5
View File
@@ -3,7 +3,7 @@ can redistribute the library and/or modify it under the terms of the 3-clause
BSD license. The text of the 3-clause BSD license is contained below.
----
Copyright (c) 2007-2023, mlpack contributors (see COPYRIGHT.txt)
Copyright (c) 2007-2025, mlpack contributors (see COPYRIGHT.txt)
All rights reserved.
Redistribution and use of mlpack in source and binary forms, with or without
@@ -32,7 +32,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
------
mlpack also contains some usage of the source code of MNMLSTC Core library,
which is a backport of C++17 features to C++11. MNMLSTC is licensed under the
Apache 2.0 License. This code can be found in src/mlpack/core/std_backport/ and
more details about licensing can be found there.
mlpack also contains some usage of the source code of the STB library,
which is providing support for image loading, saving and resizing. STB is
dual-licensed under the MIT license and the public domain. This code can be
found in src/mlpack/core/stb/ for more details about licensing and usage.
+4 -1
View File
@@ -61,8 +61,11 @@ program (before including mlpack or Armadillo!).
|---------------------------|-------------------|---------------|
|*Functionality.* |||
| `-DMLPACK_ENABLE_ANN_SERIALIZATION` | `#define MLPACK_ENABLE_ANN_SERIALIZATION` | Allow neural network layers to be serialized. |
| `-DMLPACK_DISABLE_STB` | `#define MLPACK_DISABLE_STB` | Disable [STB](https://github.com/nothings/stb)-related [image functionality](load_save.md#image-data). |
| `-DMLPACK_NO_STD_MUTEX` | `#define MLPACK_NO_STD_MUTEX` | Disable mutexes inside mlpack; use this if your system has no support for `std::mutex` and has only one core. You may also need to define `ARMA_DO_NOT_USE_STD_MUTEX` for Armadillo. |
|---------------------------|-------------------|---------------|
|*Configuration.* |||
| `-DMLPACK_USE_SYSTEM_STB` | `#define MLPACK_USE_SYSTEM_STB` | Use the version of STB available on the system instead of the version bundled with mlpack. If set, make sure `stb_image.h`, `stb_image_write.h`, and `stb_image_resize2.h` are available. |
| `-DMLPACK_DONT_USE_SYSTEM_STB` | `#define MLPACK_DONT_USE_SYSTEM_STB` | Force usage of the bundled version of STB. Only necessary if mlpack was [configured](install.md#cmake-options) with `USE_SYSTEM_STB=ON`. |
***Note:*** If your code serializes (saves or loads) mlpack neural networks, the
`MLPACK_ENABLE_ANN_SERIALIZATION` option must be enabled. This option is not
+1
View File
@@ -194,6 +194,7 @@ The following options can be used when configuring mlpack.
| `-DBUILD_TESTS=ON` | Build `mlpack_test`. | `OFF` |
| `-DUSE_OPENMP=ON` | Use OpenMP for parallelization. | `ON` |
| `-DUSE_PRECOMPILED_HEADERS=OFF` | Disable precompiled headers during build. | `OFF` |
| `-DUSE_SYSTEM_STB=OFF` | Use version of STB bundled with mlpack. If set to `ON` make sure `stb_image.h`, `stb_image_write.h`, and `stb_image_resize2.h` are available. | `OFF` |
|--------------|-------------------|---------------|
| ***Dependency locations*** |||
| `-DARMADILLO_INCLUDE_DIR=/path/to/arma/include/` | Path containing `armadillo` header file. ||
+86
View File
@@ -523,6 +523,92 @@ outImages.push_back("bandicoot-favicon-inv.jpeg");
mlpack::data::Save(outImages, matrix, info);
```
### Resize images
It is possible to resize images in mlpack with the following function:
- `ResizeImages(images, info, newWidth, newHeight)`
* `images` is a [column-major matrix](matrices.md) containing a set of
images; each image is represented as a flattened vector in one column.
* `info` is a [`data::ImageInfo&`](#dataimageinfo) containing details about
the images in `images`, and will be modified to contain the new size of the
images.
* `newWidth` and `newHeight` (of type `size_t`) are the desired new
dimensions of the resized images.
* This function returns `void` and modifies `info` and `images`.
* ***NOTE:*** if the element type of `images` is not `unsigned char` or
`float` (e.g. if `image` is not `arma::Mat<unsigned char>` or
`arma::fmat`), the matrix will be temporarily converted during resizing;
therefore, using `unsigned char` or `float` as the element type is the most
efficient.
* This function expects all the images to have identical
dimensions. If this is not the case, iteratively call `ResizeImages()` with
a single image/column in `images`.
Example usage of the `ResizeImages()` function on a set of images with
different dimensions:
```c++
// See https://datasets.mlpack.org/sheep.tar.bz2
arma::Mat<unsigned char> image;
mlpack::data::ImageInfo info;
// The images are located in our test/data directory. However, any image could
// be used instead.
std::vector<std::string> files =
{"sheep_1.jpg", "sheep_2.jpg", "sheep_3.jpg", "sheep_4.jpg",
"sheep_5.jpg", "sheep_6.jpg"};
// The resized images will be saved locally. We are declaring the vector that
// contains the names of the resized images.
std::vector<std::string> reSheeps =
{"re_sheep_1.jpg", "re_sheep_2.jpg", "re_sheep_3.jpg", "re_sheep_4.jpg",
"re_sheep_5.jpg", "re_sheep_6.jpg"};
// Load and Resize each one of them individually, because they do not have
// the same dimensions. The `info` will contain the dimension for each one.
for (size_t i = 0; i < files.size(); i++)
{
mlpack::data::Load(files.at(i), image, info, false);
mlpack::data::ResizeImages(image, info, 320, 320);
mlpack::data::Save(reSheeps.at(i), image, info, false);
}
```
Example usage of `ResizeImages()` function on a set of images that have the
same dimensions.
```c++
// All images have the same dimension, It would be possible to load all of
// them into one matrix
// See https://datasets.mlpack.org/sheep.tar.bz2
arma::Mat<unsigned char> images;
mlpack::data::ImageInfo info;
std::vector<std::string> reSheeps =
{"re_sheep_1.jpg", "re_sheep_2.jpg", "re_sheep_3.jpg", "re_sheep_4.jpg",
"re_sheep_5.jpg", "re_sheep_6.jpg"};
mlpack::data::Load(reSheeps, images, info, false);
// Now let us resize all these images at once, to specific dimensions.
mlpack::data::ResizeImages(images, info, 160, 160);
// The resized images will be saved locally. We are declaring the vector that
// contains the names of the resized images.
std::vector<std::string> smSheeps =
{"sm_sheep_1.jpg", "sm_sheep_2.jpg", "sm_sheep_3.jpg", "sm_sheep_4.jpg",
"sm_sheep_5.jpg", "sm_sheep_6.jpg"};
mlpack::data::Save(smSheeps, images, info, false);
```
## mlpack objects
All mlpack objects can be saved with `data::Save()` and loaded with
+13 -1
View File
@@ -239,7 +239,7 @@ download_http_artifacts()
sed 's/^.*\(http[^ ]*\).*$/\1/' |\
sort |\
uniq |\
grep 'csv\|arff\|bin\|png' |\
grep 'csv\|arff\|bin\|png\|jpg\|bz2\|gz' |\
sed 's/\.$//'`;
cd $output_dir;
for a in $artifacts;
@@ -253,6 +253,18 @@ download_http_artifacts()
echo "Error downloading $a!";
exit 1;
fi
if [[ $a == *.gz ]];
then
echo "Unpacking $a...";
tar -xzpf *.gz;
fi
if [[ $a == *.bz2 ]];
then
echo "Unpacking $a...";
tar -xjpf *.bz2;
fi
fi
done
cd - >/dev/null;
+2 -1
View File
@@ -403,7 +403,8 @@ macro (post_r_setup)
# Collect all header and source files in the library.
file(GLOB_RECURSE R_SRC_HPP_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.hpp)
file(GLOB_RECURSE R_SRC_CPP_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.cpp)
set(R_SRC_FILES ${R_SRC_HPP_FILES} ${R_SRC_CPP_FILES})
file(GLOB_RECURSE R_SRC_H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.h)
set(R_SRC_FILES ${R_SRC_HPP_FILES} ${R_SRC_CPP_FILES} ${R_SRC_H_FILES})
# In case of R_Bindings we are copying all of these header to
# <package>/src/cereal/ because the currently-packaged version
+7 -53
View File
@@ -23,29 +23,6 @@
// #define MLPACK_HAS_BFD_DL
#endif
//
// mlpack provides image loading and saving support via STB, if available. STB
// is an optional dependency of mlpack. When STB is found on a system,
// MLPACK_HAS_STB will be defined and the files `stb_image.h` and
// `stb_image_write.h` are expected to be found in the compiler include path.
//
#ifndef MLPACK_HAS_STB
// #define MLPACK_HAS_STB
#endif
//
// If STB support is available but the STB headers do not live in an stb/
// directory, then MLPACK_HAS_NO_STB_DIR should be defined.
//
// Note that this is ignored in newer compilers where __has_include is available
// (C++17 and newer compilers support it).
//
#ifdef MLPACK_HAS_STB
#ifndef MLPACK_HAS_NO_STB_DIR
// #define MLPACK_HAS_NO_STB_DIR
#endif
#endif
//
// If the version of mlpack is built from a git repository and is not an
// official release, then MLPACK_GIT_VERSION will be defined. This causes
@@ -82,41 +59,18 @@
#endif
//
// Perform autodetection of STB if possible.
// MLPACK_USE_SYSTEM_STB is used to enable usage of locally installed STB.
//
#ifndef MLPACK_HAS_STB
#if defined __has_include
#if __has_include("stb_image.h")
#define MLPACK_HAS_STB_IMAGE
#elif __has_include("stb/stb_image.h")
#define MLPACK_HAS_STB_IMAGE
#endif
#if __has_include("stb_image_write.h")
#define MLPACK_HAS_STB_IMAGE_WRITE
#elif __has_include("stb/stb_image_write.h")
#define MLPACK_HAS_STB_IMAGE_WRITE
#endif
#if defined(MLPACK_HAS_STB_IMAGE) && defined(MLPACK_HAS_STB_IMAGE_WRITE)
#define MLPACK_HAS_STB
#endif
#undef MLPACK_HAS_STB_IMAGE
#undef MLPACK_HAS_STB_IMAGE_WRITE
#endif
#if !defined(MLPACK_USE_SYSTEM_STB)
// #define MLPACK_USE_SYSTEM_STB
#endif
//
// These macros can be defined to disable support that is defined above. (This
// is useful if you cannot or do not want to modify config.hpp.)
// This is necessary if we would like to overwrite the default packaging
// condition.
//
#ifdef MLPACK_DISABLE_STB
#undef MLPACK_HAS_STB
#endif
#ifdef MLPACK_DISABLE_NO_STB_DIR
#undef MLPACK_HAS_NO_STB_DIR
#if defined(MLPACK_DONT_USE_SYSTEM_STB) && defined(MLPACK_USE_SYSTEM_STB)
#undef MLPACK_USE_SYSTEM_STB
#endif
#ifdef MLPACK_DISABLE_BFD_DL
+1
View File
@@ -35,6 +35,7 @@
#include <mlpack/prereqs.hpp>
// Now the core mlpack classes.
#include <mlpack/core/stb/stb.hpp>
#include <mlpack/core/util/arma_traits.hpp>
#include <mlpack/core/util/ens_traits.hpp>
#include <mlpack/core/util/first_element_is_arma.hpp>
+1
View File
@@ -31,6 +31,7 @@
#include "confusion_matrix.hpp"
#include "dataset_mapper.hpp"
#include "image_info.hpp"
#include "image_resize_crop.hpp"
#include "imputer.hpp"
#include "is_naninf.hpp"
#include "normalize_labels.hpp"
-4
View File
@@ -30,8 +30,6 @@ inline const std::vector<std::string> SaveFileTypes()
} // namespace data
} // namespace mlpack
#ifdef MLPACK_HAS_STB // Compile this only if stb is present.
// In case it hasn't been included yet.
#include "image_info.hpp"
@@ -65,8 +63,6 @@ inline bool ImageFormatSupported(const std::string& fileName, const bool save)
} // namespace data
} // namespace mlpack
#endif // MLPACK_HAS_STB.
namespace mlpack {
namespace data {
+135
View File
@@ -0,0 +1,135 @@
/**
* @file core/data/image_resize_crop.hpp
* @author Omar Shrit
*
* Image resize and crop functionalities.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_DATA_IMAGE_RESIZE_CROP_HPP
#define MLPACK_CORE_DATA_IMAGE_RESIZE_CROP_HPP
#include <mlpack/prereqs.hpp>
#include <mlpack/core/stb/stb.hpp>
#include "image_info.hpp"
namespace mlpack {
namespace data {
/**
* Image resize/crop interfaces.
*/
/**
* Resize one single image matrix or a set of images.
*
* This function should be used if the image is loaded as an armadillo matrix
* and the number of cols equal to the Width and the number of rows equal
* the Height of the image, or the total number of image pixels is equal to the
* number of element in an armadillo matrix.
*
* The same applies if a set of images is loaded, but all of them need to have
* identical dimension when loaded to this matrix.
*
* @param image The input matrix that contains the image to be resized.
* @param info Contains relevant input images information.
* @param newWidth The new requested width for the resized image.
* @param newHeight The new requested height for the resized image.
*/
template<typename eT>
inline void ResizeImages(arma::Mat<eT>& images, data::ImageInfo& info,
const size_t newWidth, const size_t newHeight)
{
// First check if we are resizing one image or a group of images, the check
// is going to be different depending on the dimension.
// If the user would like to resize a set of images of different dimensions,
// then they need to consider passing them image by image. Otherwise, as
// assume that all images have identical dimension and need to be resized.
if (images.n_cols == 1)
{
if (images.n_elem != (info.Width() * info.Height() * info.Channels()))
{
Log::Fatal << "ResizeImages(): dimensions mismatch: the number of pixels "
<< "is not equal to the dimension provided by the given ImageInfo."
<< std::endl;
}
}
else
{
if (images.n_rows != (info.Width() * info.Height() * info.Channels()))
{
Log::Fatal << "ResizeImages(): dimension mismatch: in the case of "
<< "several images, please check that all the images have the same "
<< "dimensions; if not, load each image in one column and call this "
<< "function iteratively." << std::endl;
}
}
stbir_pixel_layout channels;
if (info.Channels() == 1)
{
channels = STBIR_1CHANNEL;
}
else if (info.Channels() == 3)
{
channels = STBIR_RGB;
}
// This is required since STB only accept unsigned chars.
// set the new matrix size for copy
size_t newDimension = newWidth * newHeight * info.Channels();
arma::Mat<float> resizedFloatImages;
arma::Mat<unsigned char> resizedImages;
// This is not optimal, but I do not want to allocate memory for nothing.
if (std::is_same<eT, float>::value)
resizedFloatImages.set_size(newDimension, images.n_cols);
else
resizedImages.set_size(newDimension, images.n_cols);
for (size_t i = 0; i < images.n_cols; ++i)
{
if constexpr (std::is_same<eT, unsigned char>::value)
{
stbir_resize_uint8_linear(images.colptr(i), info.Width(), info.Height(),
0, resizedImages.colptr(i), newWidth, newHeight, 0, channels);
}
else if constexpr (std::is_same<eT, float>::value)
{
stbir_resize_float_linear(images.colptr(i), info.Width(), info.Height(),
0, resizedFloatImages.colptr(i), newWidth, newHeight, 0, channels);
}
else
{
arma::Mat<unsigned char> tempSrc =
arma::conv_to<arma::Mat<unsigned char>>::from(images);
stbir_resize_uint8_linear(tempSrc.colptr(i), info.Width(), info.Height(),
0, resizedImages.colptr(i), newWidth, newHeight, 0, channels);
}
}
if (std::is_same<eT, float>::value)
{
// The conv_to is needed here so that this code compiles even when this
// branch isn't taken.
images = arma::conv_to<arma::Mat<eT>>::from(std::move(resizedFloatImages));
}
else
{
images = arma::conv_to<arma::Mat<eT>>::from(std::move(resizedImages));
}
info.Width() = newWidth;
info.Height() = newHeight;
}
} // namespace data
} // namespace mlpack
#endif
+2 -26
View File
@@ -13,34 +13,10 @@
#ifndef MLPACK_CORE_DATA_LOAD_IMAGE_HPP
#define MLPACK_CORE_DATA_LOAD_IMAGE_HPP
#include <mlpack/core/stb/stb.hpp>
#include "image_info.hpp"
#ifdef MLPACK_HAS_STB
// The definition of STB_IMAGE_IMPLEMENTATION means that the implementation will
// be included here directly.
#define STB_IMAGE_STATIC
#define STB_IMAGE_IMPLEMENTATION
#if defined __has_include
#if __has_include("stb_image.h")
#include "stb_image.h"
#elif __has_include("stb/stb_image.h")
#include "stb/stb_image.h"
#else
#undef MLPACK_HAS_STB
#pragma message("Warning: STB disabled; stb_image.h header not found")
#endif
#else
#ifdef MLPACK_HAS_STB_DIR
#include "stb/stb_image.h"
#else
#include "stb_image.h"
#endif
#endif
#endif // MLPACK_HAS_STB
namespace mlpack {
namespace data {
-25
View File
@@ -90,8 +90,6 @@ bool Load(const std::vector<std::string>& files,
return true;
}
#ifdef MLPACK_HAS_STB
inline bool LoadImage(const std::string& filename,
arma::Mat<unsigned char>& matrix,
ImageInfo& info,
@@ -167,29 +165,6 @@ inline bool LoadImage(const std::string& filename,
return true;
}
#else // MLPACK_HAS_STB
inline bool LoadImage(const std::string& /* filename */,
arma::Mat<unsigned char>& /* matrix */,
ImageInfo& /* info */,
const bool fatal)
{
if (fatal)
{
Log::Fatal << "Load(): mlpack was not compiled with STB support, so images "
<< "cannot be loaded!" << std::endl;
}
else
{
Log::Warn << "Load(): mlpack was not compiled with STB support, so images "
<< "cannot be loaded!" << std::endl;
}
return false;
}
#endif
} // namespace data
} // namespace mlpack
+2 -24
View File
@@ -12,32 +12,10 @@
#ifndef MLPACK_CORE_DATA_SAVE_IMAGE_HPP
#define MLPACK_CORE_DATA_SAVE_IMAGE_HPP
#include <mlpack/core/stb/stb.hpp>
#include "image_info.hpp"
#ifdef MLPACK_HAS_STB
#define STB_IMAGE_WRITE_STATIC
#define STB_IMAGE_WRITE_IMPLEMENTATION
#if defined __has_include
#if __has_include("stb_image_write.h")
#include "stb_image_write.h"
#elif __has_include("stb/stb_image_write.h")
#include "stb/stb_image_write.h"
#else
#undef MLPACK_HAS_STB
#pragma message("Warning: STB disabled; stb_image_write.h header not found")
#endif
#else
#ifdef MLPACK_HAS_STB_DIR
#include "stb/stb_image_write.h"
#else
#include "stb_image_write.h"
#endif
#endif
#endif // MLPACK_HAS_STB
namespace mlpack {
namespace data {
-25
View File
@@ -75,8 +75,6 @@ bool Save(const std::vector<std::string>& files,
return status;
}
#ifdef MLPACK_HAS_STB
inline bool SaveImage(const std::string& filename,
arma::Mat<unsigned char>& image,
ImageInfo& info,
@@ -166,29 +164,6 @@ inline bool SaveImage(const std::string& filename,
return status;
}
#else // MLPACK_HAS_STB
inline bool SaveImage(const std::string& /* filename */,
arma::Mat<unsigned char>& /* image */,
ImageInfo& /* info */,
const bool fatal)
{
if (fatal)
{
Log::Fatal << "Save(): mlpack was not compiled with STB support, so images "
<< "cannot be saved!" << std::endl;
}
else
{
Log::Warn << "Save(): mlpack was not compiled with STB support, so images "
<< "cannot be saved!" << std::endl;
}
return false;
}
#endif
} // namespace data
} // namespace mlpack
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+85
View File
@@ -0,0 +1,85 @@
/**
* @file core/data/stb.hpp
* @author Omar Shrit
*
* Header to include stb in mlpack, in addition to allow the user to disable
* all of these includes.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_STB_STB_HPP
#define MLPACK_CORE_STB_STB_HPP
#ifndef STB_IMAGE_STATIC
#define STB_IMAGE_STATIC
#endif
#ifndef STB_IMAGE_WRITE_STATIC
#define STB_IMAGE_WRITE_STATIC
#endif
#ifndef STB_IMAGE_RESIZE_STATIC
#define STB_IMAGE_RESIZE_STATIC
#endif
#ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#endif
#ifndef STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#endif
#ifndef STB_IMAGE_RESIZE_IMPLEMENTATION
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#endif
#if defined(MLPACK_USE_SYSTEM_STB)
#if defined __has_include
#if __has_include(<stb_image.h>)
#include <stb_image.h>
#elif __has_include(<stb/stb_image.h>)
#include <stb/stb_image.h>
#else
#pragma warning("System's STB not found; including bundled STB")
#include "bundled/stb_image.h"
#endif
#endif
#if defined __has_include
#if __has_include(<stb_image_write.h>)
#include <stb_image_write.h>
#elif __has_include(<stb/stb_image_write.h>)
#include <stb/stb_image_write.h>
#else
#pragma warning("System's STB not found; including bundled STB")
#include "bundled/stb_image_write.h"
#endif
#endif
#if defined __has_include
#if __has_include(<stb_image_resize2.h>)
#include <stb_image_resize2.h>
#elif __has_include(<stb/stb_image_resize2.h>)
#include <stb/stb_image_resize2.h>
#else
#pragma warning("System's STB not found; including bundled STB")
#include "bundled/stb_image_resize2.h"
#endif
#endif
#else
// Now include STB headers
#include "bundled/stb_image.h"
#include "bundled/stb_image_write.h"
#include "bundled/stb_image_resize2.h"
#endif
#endif
+2 -1
View File
@@ -68,7 +68,7 @@ add_executable(mlpack_test
hpt_test.cpp
hoeffding_tree_test.cpp
hyperplane_test.cpp
image_load_test.cpp
image_test.cpp
imputation_test.cpp
io_test.cpp
kde_model_test.cpp
@@ -269,6 +269,7 @@ add_custom_command(TARGET mlpack_test
COMMAND ${CMAKE_COMMAND} -E tar xjf digits_test.tar.bz2
COMMAND ${CMAKE_COMMAND} -E tar xjf digits_train_label.tar.bz2
COMMAND ${CMAKE_COMMAND} -E tar xjf digits_test_label.tar.bz2
COMMAND ${CMAKE_COMMAND} -E tar xjf sheep.tar.bz2
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
)
Binary file not shown.
@@ -19,8 +19,6 @@ using namespace mlpack;
using namespace mlpack::data;
using namespace std;
#ifdef MLPACK_HAS_STB // Compile this only if stb is present.
/**
* Test if an image with an unsupported extension throws an expected
* exception.
@@ -30,7 +28,7 @@ TEST_CASE("LoadInvalidExtensionFile", "[ImageLoadTest]")
arma::Mat<unsigned char> matrix;
data::ImageInfo info;
REQUIRE_THROWS_AS(data::Load("invalidExtendion.p4ng", matrix, info,
REQUIRE_THROWS_AS(data::Load("invalidExtension.p4ng", matrix, info,
true), std::runtime_error);
}
@@ -152,4 +150,89 @@ TEST_CASE("ImageInfoSerialization", "[ImageLoadTest]")
REQUIRE(info.Quality() == binaryInfo.Quality());
}
#endif // MLPACK_HAS_STB.
/**
* Test resize the image if this is done correctly. Try it with a few different
* types.
*/
TEMPLATE_TEST_CASE("ImagesResizeTest", "[ImageTest]", unsigned char, size_t,
float, double)
{
typedef TestType eT;
arma::Mat<eT> image, images;
data::ImageInfo info, resizedInfo, resizedInfo2;
std::vector<std::string> files =
{"sheep_1.jpg", "sheep_2.jpg", "sheep_3.jpg", "sheep_4.jpg",
"sheep_5.jpg", "sheep_6.jpg"};
std::vector<std::string> reSheeps =
{"re_sheep_1.jpg", "re_sheep_2.jpg", "re_sheep_3.jpg", "re_sheep_4.jpg",
"re_sheep_5.jpg", "re_sheep_6.jpg"};
std::vector<std::string> smSheeps =
{"sm_sheep_1.jpg", "sm_sheep_2.jpg", "sm_sheep_3.jpg", "sm_sheep_4.jpg",
"sm_sheep_5.jpg", "sm_sheep_6.jpg"};
// Load and Resize each one of them individually, because they do not have
// the same sizes, and then the resized images, will be used in the next
// test.
for (size_t i = 0; i < files.size(); i++)
{
REQUIRE(data::Load(files.at(i), image, info, false) == true);
ResizeImages(image, info, 320, 320);
REQUIRE(data::Save(reSheeps.at(i), image, info, false) == true);
}
// Since they are all resized, this should passes
REQUIRE(data::Load(reSheeps, images, resizedInfo, false) == true);
REQUIRE(info.Width() == resizedInfo.Width());
REQUIRE(info.Height() == resizedInfo.Height());
REQUIRE(data::Load(reSheeps, images, info, false) == true);
ResizeImages(images, info, 160, 160);
REQUIRE(data::Save(smSheeps, images, info, false) == true);
REQUIRE(data::Load(smSheeps, images, resizedInfo2, false) == true);
REQUIRE(info.Width() == resizedInfo2.Width());
REQUIRE(info.Height() == resizedInfo2.Height());
// cleanup generated images.
for (size_t i = 0; i < reSheeps.size(); ++i)
{
remove(reSheeps.at(i).c_str());
remove(smSheeps.at(i).c_str());
}
}
/**
* Test if we resize to the same original dimension we will get the same pixels
* and no modification to the image. Try it with a few different types.
*/
TEMPLATE_TEST_CASE("IdenticalResizeTest", "[ImageTest]", unsigned char, size_t,
float, double)
{
typedef TestType eT;
arma::Mat<eT> image;
data::ImageInfo info;
std::vector<std::string> files =
{"sheep_1.jpg", "sheep_2.jpg", "sheep_3.jpg", "sheep_4.jpg",
"sheep_5.jpg", "sheep_6.jpg"};
for (size_t i = 0; i < files.size(); i++)
{
REQUIRE(data::Load(files.at(i), image, info, false) == true);
arma::Mat<eT> originalImage = image;
ResizeImages(image, info, info.Width(), info.Height());
for (size_t i = 0; i < originalImage.n_rows; ++i)
{
for (size_t j = 0; j < originalImage.n_cols; ++j)
{
REQUIRE(originalImage.at(i, j) == image.at(i, j));
}
}
}
}
@@ -22,8 +22,6 @@
using namespace mlpack;
#ifdef MLPACK_HAS_STB // Compile this only if stb is present.
BINDING_TEST_FIXTURE(ImageConverterTestFixture);
TEST_CASE_METHOD(ImageConverterTestFixture, "LoadImageTest",
@@ -164,5 +162,3 @@ TEST_CASE_METHOD(ImageConverterTestFixture, "EmptyInputTest",
REQUIRE_THROWS_AS(RUN_BINDING(), std::runtime_error);
}
#endif // MLPACK_HAS_STB.