Coder Social home page Coder Social logo

haze's Introduction

haze

haze is a C++ image manipulation library utilizing both CPU- and GPU-side processing to provide high performance image transformations, either through traditional kernel convolution approaches or with specialized implementations using custom data structures.

general

One of the cornerstones of the library is the image class, a class templated on the pixel type and used for storing images.
However, besides acting as an image container, the class also provides some utilities such as constructing a subimage from an existing image.

Making things a bit more useful, the library introduces the pixel field, a slightly smarter (and fatter) image container.
The pixel field, instead of storing a simple buffer of 8 bit pixel values, stores the pixels in two-dimensional prefix arrays. This enables the container to calculate sums of pixel values in any subimage in constant time.
With this approach, it's possible to perform a mean blur with any blur radius on an n x m image in O( n * m ) time, while a naive approach would take O( n * m * blur_radius * blur_radius ) (or O( n * m * blur_radius * 2 ) when using separable convolutions).

examples

converting image formats

#include "include/HAZElib.hpp"

int main ()
{
    haze::image< haze::rgb_pixel > img( "image.jpeg" );
    
    haze::util::write_to_png( img, "image.png" );
    
    
    return 0;
}

scaling images

{
    haze::image< haze::rgb_pixel > img( "image.png" );
    
    auto scaled_up  = haze::scale_image( img, 2.0, 2.0, haze::scaling_options::interpolation_type::bilinear         );
    auto scaled_dwn = haze::scale_image( img, 0.5, 0.5, haze::scaling_options::interpolation_type::nearest_neighbor );
}

getting and setting subimages

{
    haze::image< haze::rgb_pixel > img(   "image.png" );
    haze::image< haze::rgb_pixel > sml( "smaller.png" );
    
    auto sub = img.get_subimage( 0, 0, 400, 300 );
    
    img.set_subimage( sml, 0, 0 );
}

CPU-side mean blur with pixel field

constexpr int blur_radius = 32;

{
    haze::pixel_field< haze::rgb_pixel > field( "image.png" );
    
    haze::image< haze::rgb_pixel > blr = field.get_blurred_image( blur_radius );
}
{
    haze::image< haze::rgb_pixel > img( "image.png" );
    
    haze::pixel_field field( img );
    
    auto blr = field.get_blurred_image( blur_radius );
}

img_transform

The img_transform header provides utilities necessary for traditional kernel convolutions including 2D square and rectangular kernels as well as separable 1D kernels. It also exposes several free functions which implement the image transformations CPU-side, but they're only meant to be used as benchmarks against the GPU implementations.

examples

edge detection with sobel operator

{
    haze::image< haze::bw_pixel > img( "image.png" );
    
    auto v_edge = haze::transform_image( img, haze::sobel_v );
    auto h_edge = haze::transform_image( img, haze::sobel_h );
}

perlin noise

1d 2d 3d perlin noise generator

steganography

basic af, stores a message in the lower 2 bits of a pixel

CPU side

cpu does stuff.

GPU side

gpu goes brrrr.

examples

kernel convolutions

{
    haze::gpu_ops< haze::rgb_pixel > gpu;
    
    haze::image< haze::rgb_pixel > img( "image.png" );
    
    auto gauss_3 = gpu.transform_image(     img, haze::gauss_3 );
    auto v_edge  = gpu.transform_image( gauss_3, haze::sobel_v );
    auto h_edge  = gpu.transform_image( gauss_3, haze::sobel_h );
}

full edge detection

{
    haze::gpu_ops< haze::bw_pixel > gpu;
    
    haze::image< haze::bw_pixel > img( "image.png" );
    
    auto blurred   = gpu.transform_image( img, haze::gauss_3 );
    auto full_edge = gpu.detect_edges( img );
}

haze's People

Contributors

eddieavd avatar

Stargazers

 avatar

Watchers

Luka Markušić avatar  avatar

haze's Issues

Conditionals in GPU code

The GPU-side code has tons of conditional branches checking if we're processing an edge pixel incurring a huge performance drop.
These could be avoided by extending the image being processed with kernel_size pixels on every side and only processing pixels from [ kernel_size, kernel_size ] to [ img_width - kernel_size, img_height - kernel_size ].
This way there is no need to check which pixel we're processing, the kernel will always be fully inside the image.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.