A C++17 image representation, processing and I/O library.

Overview

Selene

Build Status

Selene is a C++17 image representation, processing, and I/O library, focusing on ease of use and a clean, modern, type-safe API.

  • Overview: Brief summary of the current feature set.
  • Rationale: Why implement a new library for image representation, processing, and I/O?

Building & usage:

  • Building the library: How to build from source.
  • Dependencies: Description of optional dependencies.
  • Installation: Installation using package managers (vcpkg/Conan).
  • Usage: Using the built and/or installed library as a dependency in other projects.

Documentation & status:

Summary

  • Strongly typed image and multi-channel pixel representations, and functions for image data access.
  • Easy-to-use APIs to read and write images in JPEG, PNG, and TIFF formats (leveraging libjpeg, libpng, and libtiff).
  • Basic image processing algorithms such as color conversions, pixel-wise operations, convolutions, rotation, etc.
  • Lightweight and easy to build using CMake on Linux, MacOS, Windows.

Example

A first impression of the API:

// Decode JPEG image data from disk
DynImage img_data = read_image(FileReader("example.jpg"));
assert(img_data.nr_channels() == 3 && img_data.nr_bytes_per_channel() == 1);

// Convert to strongly typed RGB image
Image<PixelRGB_8u> img_rgb = to_image<PixelRGB_8u>(std::move(img_data));
assert(img_rgb.width() > 400_px && img_rgb.height() > 350_px);

// Create non-owning view on part of the image
MutableImageView<PixelRGB_8u> img_part = view(img_rgb, {100_idx, 100_idx, 300_px, 250_px});

// Darken this part
for_each_pixel(img_part, [](auto& px){ px /= 4; });

// Flip this part horizontally
flip_horizontally_in_place(img_part);

// Apply a convolution to this part (1-D Gaussian kernel in x-direction, sigma=5.0, range: 3 std. deviations)
Kernel<double> kernel = gaussian_kernel(5.0, 3.0);
const auto img_part_copy = convolution_x<BorderAccessMode::Unchecked>(img_part, kernel);

// And copy the result back to the original image (i.e. to the view).
clone(img_part_copy, img_part);

// Convert whole image to RGBA, adding semi-transparent alpha channel
const Image<PixelRGBA_8u> img_rgba =
  convert_image<PixelFormat::RGBA>(img_rgb, std::uint8_t{192});

// Encode in-memory to PNG
std::vector<std::uint8_t> encoded_png_data;
write_image(to_dyn_image_view(img_rgba), ImageFormat::PNG,
          VectorWriter(encoded_png_data));

// Write encoded binary data to disk (or do something else with it...)
write_data_contents("example_out.png", encoded_png_data);

Package managed

Building from source "at head" using CMake is the recommended way to use Selene (see Building the library). But the library is also available as a

Selene's own dependencies can be installed using

besides OS level package managers or from source.

Feedback encouraged

Please send me a message if you're using Selene. I would love to know what you think of it, and what your use cases are! Contributions are also very encouraged; see here for more information.

Issues
  • Some deprecated function

    Some deprecated function

    FileReader.hpp use function fopen and strerror, these functions are marked as deprecated in MSVC(for me, Visual Studio 2017). It requires a definition of macro _CRT_SECURE_NO_WARNINGS or use the suggested fopen_s or strerror_s. Why don't you choose std::ifstream?

    opened by shrinktofit 5
  • Question: Dynamic image to file generates empty file without errors or warnings.

    Question: Dynamic image to file generates empty file without errors or warnings.

    I was experimenting with wrapping the SANE library and everything worked great; other than writing to a jpeg. The "doesn't work" section in the code below produces an empty file. I took a look at the tests and saw the conversion to a typed image and then a typed image view, gave it a try and it worked. Just wondering if I missed something/if the library should give some sort of warning for the way I tried to use the file io.

    #include <sane/sane.h>
    
    #include <selene/base/io/FileUtils.hpp>
    #include <selene/img/dynamic/DynImage.hpp>
    #include <selene/img/pixel/PixelTypeAliases.hpp>
    #include <selene/img/typed/ImageTypeAliases.hpp>
    #include <selene/base/io/FileWriter.hpp>
    #include <selene/img_io/IO.hpp>
    
    #include <selene/img/interop/ImageToDynImage.hpp>
    #include <selene/img/interop/DynImageToImage.hpp>
    
    #include <iostream>
    
    int main(int argc, char **argv) {
        sane_init(nullptr, nullptr);
        const SANE_Device** device_list;
        sane_get_devices(&device_list, true);
        auto device = device_list[0];
        SANE_Handle handle;
        sane_open(device->name, &handle);
        
        constexpr auto test_picture = 10;
        constexpr auto mode = 2;
    
        constexpr auto grid = 3;
        constexpr auto colours = 2;
    
        auto mode_option =  sane_get_option_descriptor(handle, mode);
        sane_control_option(handle, mode, SANE_ACTION_SET_VALUE, (void*) mode_option->constraint.string_list[1], nullptr);
        
        auto option = sane_get_option_descriptor(handle, test_picture);
        sane_control_option(handle, test_picture, SANE_ACTION_SET_VALUE, (void*) option->constraint.string_list[grid], nullptr);
    
        SANE_Parameters params;
        sane_get_parameters(handle, &params);
    
        auto height = sln::PixelLength{params.lines};
        auto width = sln::PixelLength{params.pixels_per_line};
        short depth = params.depth / 8;
        short channels = params.format==SANE_FRAME_RGB?3:1;
        
        sln::DynImage input_buffer{{width, height, channels, depth}, sln::ImageRowAlignment{0}};
    
        sane_start(handle);
        int total_read = 0;
        int read = 0;
        while(total_read < input_buffer.total_bytes()) {
            sane_read(handle, reinterpret_cast<unsigned char*>(input_buffer.data<sln::PixelRGB_8u>()) + total_read, input_buffer.total_bytes(), &read);
            total_read += read;
        }
        sane_close(handle);
    
    
        // Doesn't work
        auto output_empty_filename_jpg = "empty_test.jpg";
        sln::write_image(input_buffer, sln::ImageFormat::JPEG, sln::FileWriter(output_empty_filename_jpg));
    
        // WORKS
        const sln::Image<sln::PixelRGB_8u> img = sln::to_image<sln::PixelRGB_8u>(std::move(input_buffer));
        const auto img_data_1 = sln::to_dyn_image_view(img);
        
        auto output_filename_jpg = "test.jpg";
        sln::write_image(img_data_1, sln::ImageFormat::JPEG, sln::FileWriter(output_filename_jpg));
    }
    
    opened by dunkyp 3
  • Q: How Selene compares to Boost.GIL

    Q: How Selene compares to Boost.GIL

    Question: would be able to provide brief comparison on how Selene is similar/different to Boost.GIL?

    A similar reference as you make to OpenCV in the Rationale document would be helpful for prospect users considering Selene.

    opened by mloskot 2
  • [Question] Perform interpolation on vector of pixels?

    [Question] Perform interpolation on vector of pixels?

    Hi,

    I'm so sorry if this is not the right place to ask this. If it's not please let me know, I will close this and open the new one in appropriate place.

    I'm looking for a way to perform interpolation to scale the image I get from network and stumbled upon Selene through the Awesome GIS repo. Unfortunately, I cannot get this to work for my use case.

    I'm using SFML library to write a small application that receives a vector of raw pixel from network, a UDP socket, and renders it on screen. The pixels are RGBA pixels. They are stored in a std::vector<unsigned char>. So every four values in the vector makes a pixel. I was able to use that vector to fill a SFML texture and displayed that. Everything worked great.

    However, the problem is that to save the bandwidth, the imaged was sent out with just 256x256 in size. And I want to scale that into a bigger image, I can scale the sprite inside SFML but it makes everything blurry. That led me to find Selene. I was able to convert that std::vector<unsigned char> to std::vector<sln::PixelRGBA_8u> by just looping through the vector and manually push back the pixel. But I'm stuck at how to convert that new vector to an image in Selene and then do the interpolation on that image, or even just do the interpolation right on the vector of pixels itself. If possible, can you point me to the direction where I can find some more instruction on how to do that?

    Thank you so much for your time and help.

    opened by phuongtran7 0
  • Fix tiff deprecation warnings

    Fix tiff deprecation warnings

    This addresses the deprecation warnings coming from the latest tiff releases.

    I saw them with libtiff/4.4.0_1 from homebrew:

    ./projects/selene/selene/img_io/tiff/Write.cpp:41:53: warning: 'uint32' is deprecated [-Wdeprecated-declarations]
      set_field<std::uint32_t>(tif, TIFFTAG_IMAGEDEPTH, uint32{1});
                                                        ^
    /opt/homebrew/include/tiff.h:84:45: note: 'uint32' has been explicitly marked deprecated here
    typedef TIFF_MSC_DEPRECATED uint32_t uint32 TIFF_GCC_DEPRECATED;
                                                ^
    
    opened by springmeyer 0
  • compile error building tests on apple M1 machine

    compile error building tests on apple M1 machine

    Seeing:

    In file included from /Users/sehome/projects/selene/test/selene/Catch.cpp:6:
    /Users/sehome/projects/selene/external/Catch2/single_include/catch2/catch.hpp:7937:13: error: unrecognized instruction mnemonic, did you mean: bit, cnt, hint, ins, not?
                CATCH_BREAK_INTO_DEBUGGER();
                ^
    /Users/sehome/projects/selene/external/Catch2/single_include/catch2/catch.hpp:7651:79: note: expanded from macro 'CATCH_BREAK_INTO_DEBUGGER'
        #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
                                                                                  ^
    ./projects/selene/external/Catch2/single_include/catch2/catch.hpp:7630:34: note: expanded from macro 'CATCH_TRAP'
        #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
                                     ^
    <inline asm>:1:2: note: instantiated into assembly here
            int $3
            ^
    1 error generated.
    

    It looks like this is a bug in Catch2, which can be fixed by upgrading the library submodule: https://github.com/catchorg/Catch2/issues/1127

    opened by springmeyer 0
  • Set cmake policy CMP0110 explicitly to avoid warnings

    Set cmake policy CMP0110 explicitly to avoid warnings

    Using cmake 3.23.3 when building selene from source I see many repeated warnings like:

    CMake Warning (dev) in test/CMakeLists.txt:
      Policy CMP0110 is not set: add_test() supports arbitrary characters in test
      names.  Run "cmake --help-policy CMP0110" for policy details.  Use the
      cmake_policy command to set the policy and suppress this warning.
    
      The following name given to add_test() is invalid if CMP0110 is not set or
      set to OLD:
    
        `"selene_tests:Image view creation"´
    
    This warning is for project developers.  Use -Wno-dev to suppress it.
    

    The warning is repeated so many times its difficult to make sense of the other cmake output. So I thought it would be worth providing a PR fixing this issue. Happy to amend this change to do it differently, but for me this change allowed the warnings to be silenced.

    opened by springmeyer 0
Releases(v0.3.1)
  • v0.3.1(Jan 25, 2019)

    This is a bugfix release. Changes include:

    • Remove (non-working) generation of export header, and export macro usage.
    • Add missing exported target selene::selene.
    • Preprocessor definitions are now set via a configuration header, instead of the CMake PUBLIC interface.
    Source code(tar.gz)
    Source code(zip)
  • v0.3(Jan 19, 2019)

    This release mainly adds image I/O support for the TIFF format, making use of libtiff; but it also contains various other changes and bug fixes.

    Changes include, but are not limited to:

    • Support for I/O of images in TIFF format. (Not all possible TIFF images may be supported, due to the complexity of both the format and the libtiff library.)
    • Add basic 1-D convolution functionality, in x & y-direction, using 1-D kernels.
    • Add functions for view creation on DynImages/DynImageViews.
    • Some header reorganization inside selene/img_io/.
    • Use std::variant for submitting format specific options to write_image(); this is an API breaking change.
    • Each message in an sln::MessageLog instance now carries the type of the message; this is an API breaking change.
    • Add seek_end() function to I/O classes in selene/base/io/.
    • Memory[Reader|Writer] now take a single [Mutable|Constant]MemoryRegion parameter, instead of two arguments. This is an API breaking change.
    • Warning free builds with -Wconversion enabled (GCC & Clang).
    • Use library instead of Boost.Filesystem for tests & examples, where available.
    • Use CMake-generated export macros to enable keeping symbols of public API functions visible.
    • Add CMake options to disable optional external dependencies.
    • Add CMake option to specify symbol visibility.
    • Add easy_build.sh script, to provide a proof-of-concept for building the library on older (Ubuntu) Linux systems.
    • Improvements to the CMake output to the user.
    • Improvements to the documentation on GitHub.
    • Improvements to the documentation built by Doxygen.
    • Fix test failures when building without libjpeg/libpng/libtiff.
    • Fix image view type alias declarations.
    • Fix correct stride adjustment in sln::ImageView constructor.
    Source code(tar.gz)
    Source code(zip)
  • v0.2(Dec 8, 2018)

    This release includes major changes, most prominently a complete redesign of the image classes, as well as a transition to C++17.

    Changes include:

    • Compilation requires a C++17 conformant compiler and standard library, e.g. GCC 8 or Clang 7.
    • Complete reorganization of the header structure.
    • The ImageData class was renamed to DynImage.
    • Owning images and views are now represented by different classes. This applies both to "dynamically typed" images (DynImage & DynImageView), as well as to "statically typed" images (Image & ImageView).
    • All I/O functions have moved from selene/io to selene/base/io.
    • The thread pool implementation has been removed. (Moved to a different repository.)
    • Various bug fixes.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.1(May 26, 2018)

    This is a bugfix release. The most important changes include:

    • Fixed path to selene-config.cmake.in.
    • Don't have selene_img link against OpenCV (but in tests).
    • sln::get performance is now on par with Image<>::operator(), given the same policies.
    Source code(tar.gz)
    Source code(zip)
Owner
Michael Hofmann
Michael Hofmann
A lean, efficient, accurate geohash encoder and decoder library implemented in C

Geohash encoder/decoder in C A lean, efficient, accurate geohash encoder and decoder library implemented in C. It does not depend on the C standard li

Christopher Wellons 18 May 30, 2022
A library of distance and occlusion generation routines

Distance/Occlusion Library + Tool From left to right: original, signed distance with zero at 0.5, red/green SDF, delta vectors to closest boundary poi

Andrew Willmott 98 Jan 3, 2022
C++ library for geographical raster data analysis

Pronto Raster library The Pronto Raster Library is a C++ library to work with raster data. The core idea of the library is to make raster data accessi

Alex Hagen-Zanker 41 Jun 7, 2022
Interactive, thoroughly customizable maps in native Android, iOS, macOS, Node.js, and Qt applications, powered by vector tiles and OpenGL

Mapbox GL Native A C++ library that powers customizable vector maps in native applications on multiple platforms by taking stylesheets that conform to

Mapbox 4.2k Jul 31, 2022
C++ implementation of R*-tree, an MVR-tree and a TPR-tree with C API

libspatialindex Author: Marios Hadjieleftheriou Contact: [email protected] Revision: 1.9.3 Date: 10/23/2019 See http://libspatialindex.org for full doc

null 617 Jul 6, 2022
2D and 3D map renderer using OpenGL ES

Tangram ES Tangram ES is a C++ library for rendering 2D and 3D maps from vector data using OpenGL ES. It is a counterpart to Tangram. This repository

Tangram 735 Jul 28, 2022
Terrain Analysis Using Digital Elevation Models (TauDEM) software for hydrologic terrain analysis and channel network extraction.

TauDEM (Terrain Analysis Using Digital Elevation Models) is a suite of Digital Elevation Model (DEM) tools for the extraction and analysis of hydrolog

David Tarboton 185 Jul 12, 2022
Alternative LAZ implementation for C++ and JavaScript

What is this? Alternative LAZ implementation. It supports compilation and usage in JavaScript, usage in database contexts such as pgpointcloud and Ora

Howard Butler 52 Aug 1, 2022
A command line toolkit to generate maps, point clouds, 3D models and DEMs from drone, balloon or kite images. đź“·

An open source command line toolkit for processing aerial drone imagery. ODM turns simple 2D images into: Classified Point Clouds 3D Textured Models G

OpenDroneMap 3.7k Jul 31, 2022
Computational geometry and spatial indexing on the sphere

S2 Geometry Library Overview This is a package for manipulating geometric shapes. Unlike many geometry libraries, S2 is primarily designed to work wit

Google 1.8k Jul 28, 2022
A fast algorithm for finding the pole of inaccessibility of a polygon (in JavaScript and C++)

A fast algorithm for finding polygon pole of inaccessibility, the most distant internal point from the polygon outline (not to be confused with centroid), implemented as a JavaScript library. Useful for optimal placement of a text label on a polygon.

Mapbox 1.2k Jul 29, 2022
C++ image processing and machine learning library with using of SIMD: SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX-512, VMX(Altivec) and VSX(Power7), NEON for ARM.

Introduction The Simd Library is a free open source image processing and machine learning library, designed for C and C++ programmers. It provides man

Ihar Yermalayeu 1.6k Aug 4, 2022
Video++, a C++14 high performance video and image processing library.

Video++ Video++ is a video and image processing library taking advantage of the C++14 standard to ease the writing of fast video and image processing

Matthieu Garrigues 683 Jul 28, 2022
ppl.cv is a high-performance image processing library of openPPL supporting x86 and cuda platforms.

ppl.cv is a high-performance image processing library of openPPL supporting x86 and cuda platforms.

null 327 Jul 28, 2022
The CImg Library is a small and open-source C++ toolkit for image processing

http://cimg.eu The CImg Library is a small and open-source C++ toolkit for image processing, designed with these properties in mind: CImg defines clas

David Tschumperlé 1.1k Aug 8, 2022
An image processing application & library built in C++20 and the Qt Framework.

Image Processing This is an image processing application & library built using C++ and Qt. It contains set of the most common image processing algorit

Rami Zouari 9 Jun 8, 2022
Second life for famous JPEGView - fast and tiny viewer/editor for JPEG, BMP, PNG, WEBP, TGA, GIF and TIFF images with a minimalist GUI and base image processing.

JPEGView-Image-Viewer-and-Editor Updated Dec 07 2021. Version 1.1.1.0 has been released. Download link1, link2 added. Second life for famous JPEGView

Ann Hatt 25 Aug 5, 2022
A fast image processing library with low memory needs.

libvips : an image processing library Introduction libvips is a demand-driven, horizontally threaded image processing library. Compared to similar lib

libvips 22 Jul 26, 2022
A fast image processing library with low memory needs.

libvips : an image processing library Introduction libvips is a demand-driven, horizontally threaded image processing library. Compared to similar lib

libvips 6.9k Aug 3, 2022
A easy-to-use image processing library accelerated with CUDA on GPU.

gpucv Have you used OpenCV on your CPU, and wanted to run it on GPU. Did you try installing OpenCV and get frustrated with its installation. Fret not

shrikumaran pb 4 Aug 14, 2021
Super Mario Remake using C++, SFML, and Image Processing which was a project for Structure Programming Course, 1st Year

Super Mario Remake We use : C++ in OOP concepts SFML for game animations and sound effects. Image processing (Tensorflow and openCV) to add additional

Omar Elshopky 5 Jun 19, 2022
NVIDIA Texture Tools samples for compression, image processing, and decompression.

NVTT 3 Samples This repository contains a number of samples showing how to use NVTT 3, a GPU-accelerated texture compression and image processing libr

NVIDIA DesignWorks Samples 31 Jun 13, 2022
Insight Toolkit (ITK) is an open-source, cross-platform toolkit for N-dimensional scientific image processing, segmentation, and registration

ITK: The Insight Toolkit C++ Python Linux macOS Windows Linux (Code coverage) Links Homepage Download Discussion Software Guide Help Examples Issue tr

Insight Software Consortium 1.1k Aug 8, 2022
VTK is an open-source software system for image processing, 3D graphics, volume rendering and visualization

Introduction VTK is an open-source software system for image processing, 3D graphics, volume rendering and visualization. VTK includes many advanced a

Kitware, Inc. 1.9k Aug 5, 2022
An open source iOS framework for GPU-based image and video processing

GPUImage Brad Larson http://www.sunsetlakesoftware.com @bradlarson [email protected] Overview The GPUImage framework is a BSD-licensed iO

Brad Larson 20k Aug 1, 2022
GLSL Image Processing System

GIPS: The GLSL Image Processing System An image processing application that applies filters written in the OpenGL Shading Language (GLSL). This means

Martin Fiedler 52 Jun 15, 2022
Isaac ROS image_pipeline package for hardware-accelerated image processing in ROS2.

isaac_ros_image_pipeline Overview This metapackage offers similar functionality as the standard, CPU-based image_pipeline metapackage, but does so by

NVIDIA AI IOT 31 Jul 18, 2022
CXXGraph is a Header-Only C++ Library for Graph Representation and Algorithms

CXXGraph is a small library, header only, that manages the Graph and it's algorithms in C++. In other words a "Comprehensive C++ Graph Library".

ZigRazor 150 Aug 3, 2022