Skip to main content

1D array transpose/conversion

Project description

IndexMapping

This library contains tools that helps indexing arrays from 1d array (C buffer data type) to 3d array and reciprocally. The functions to1d and to3d are complementary and can be resume with the following statment :

If we know the index value of a buffer (index), find the 
equivalent position in a 3d array (x, y, z) and reciprocally; 
such as :
  • to3d buffer[index] --> 3d array[x, y, z]
  • to1d 3d array[x, y, z] --> buffer[index]

to1d & to3d can also be used to convert 1d array -> 3d array and vice versa. The library also includes functions to transpose C buffer data type like the numpy transpose function used for multi-dimensional arrays.

How can we transpose row and columns in a 1d array since a buffer is a contiguous or non-contiguous adjacent set of data?

  1. reshape the 1d array to a 3d equivalent format
  2. swap row and column of the equivalent 3d array (transposed)
  3. Convert the 3d array back to 1d array type (flatten)

This library provide functions such as vfb_rgb & vfb_rgba (for transparency) to transpose the array directly.

Below a good example with 9 pixels buffer:
// Original 9 pixels buffer (length = 27), pixel format RGB 
(contiguous values)
buffer = [RGB1, RGB2, *RGB3, RGB4, RGB5, RGB6, RGB7, RGB8, 
RGB9]

Equivalent reshape model (w, h, depth) would be (3x3x3):
3d model = [RGB1 RGB2 *RGB3*]
           [RGB4 RGB5  RGB6 ]
           [RGB7 RGB8  RGB9 ]

// Same 1d buffer after transposing the values (swapped 
row and column)
buffer = [RGB1, RGB4, *RGB7*, RGB2, RGB5, RGB8, RGB3, RGB6, 
RGB9]

Equivalent reshape model (w, h, depth) after transposing the
original buffer
3D model = [RGB1, RGB4, RGB7]
           [RGB2, RGB5, RGB8]
           [RGB3, RGB6, RGB9]

After transposing the buffer we can observed that the 3d equivalent model is an array with row & columns swapped. This operation would be identical to a numpy transpose function such as : 3darray transpose(1, 0, 2)

Installation

pip install Mapping

Methods

# MAP BUFFER INDEX VALUE INTO 3D INDEXING
cpdef tuple to3d(unsigned int index, unsigned int width, unsigned short int depth):
   
    use_pygments=false
    """
    Index mapping (buffer indexing --> 3d array)
    
    :param index : python int; buffer index    
    :param width : python int; width (3d array columns number) 
    :param depth : python int; depth (RGB = 3) | (RGBA = 4) 
    :return      : Return a python tuple containing x, y, z index values 
    """
    
    cdef xyz v = to3d_c(index, width, depth)
    return v.x, v.y, v.z
# MAP 3D INDEX VALUE INTO BUFFER INDEXING
cpdef unsigned int to1d(unsigned int x, unsigned int y, unsigned int z, unsigned int width, unsigned short int depth):
    
    use_pygments=false
    """
    Index mapping (3d array indexing --> buffer)
    
    :param x     : python int; index x of the array 
    :param y     : python int; index y of the array 
    :param z     : python int; index z of the array 
    :param width : python int; width of the 3d array (number of columns)
    :param depth : python int; depth, either RGB (depth = 3) or RGBA (depth = 4)
    :return      : python int; return the index value (1d array)
     corresponding to a 3d array with index position  (x, y, z) 
    """
    return to1d_c(x, y, z, width, depth)
# VERTICALLY FLIP A SINGLE BUFFER VALUE
cpdef vmap_buffer(unsigned int index, unsigned int width, unsigned int height, unsigned short int depth):
                  
    use_pygments=false
    """
    Vertically flipped a single buffer value.

    Flip a C-buffer value vertically
    Re-sample a buffer value in order to swap rows and columns of
    its equivalent 3d model

    :param index  : integer; index value to convert  
    :param width  : integer; Original image width 
    :param height : integer; Original image height   
    :param depth  : integer; Original image depth=3 for RGB or 4 for RGBA
    :return       : integer value pointing to the pixel in
     the buffer (traversed vertically). 
    """
    return vmap_buffer_c(index, width, height, depth)
# FLIP VERTICALLY A BUFFER (TYPE RGB)
cpdef np.ndarray[np.uint8_t, ndim=1] vfb_rgb(unsigned char [:] source, unsigned char [:] target,
        int width, int height):
     
    use_pygments=false
    """
    Vertically flipped buffer containing any format of RGB colors
    
    :param source   : 1d buffer to flip vertically (unsigned char 
    values). The array length is known with (width * height *
    depth). The buffer represent  image 's pixels RGB.      
    :param target   : Target buffer must have same length than source  buffer)
    :param width    : integer; Source array's width (image width). 
    :param height   : integer; source array's height (image width). 
    :return         : Return a vertically flipped 1D RGB buffer 
    (swapped rows and columns of the 2d model) 
    
    """
    return numpy.asarray(vfb_rgb_c(source, target, width, height))
# FLIP VERTICALLY A BUFFER (TYPE RGBA)
cpdef np.ndarray[np.uint8_t, ndim=1] vfb_rgba(unsigned char [:] source, unsigned char [:] target,
        int width, int height):
        
    use_pygments=false
    """
    Vertically flipped buffer containing any format of RGBA colors
        
    :param source   : 1d buffer to flip vertically (unsigned 
    char values). The array length is known with (width * height
     * depth). The buffer represent image 's pixels RGBA.     
    :param target   : Target buffer must have same length than source buffer)
    :param width    : integer; Source array's width (image width)
    :param height   : integer; source array's height (image height)
    :return         : Return a vertically flipped 1D RGBA buffer 
    (swapped rows and columns of the 2d model) 
    """
    return numpy.asarray(vfb_rgba_c(source, target, width, height))
#  FLIP VERTICALLY A BUFFER (TYPE ALPHA, (WIDTH, HEIGHT))
cpdef unsigned char [::1] vfb(unsigned char [:] source, unsigned char [::1] target, int width,
    int height):
    
    use_pygments=false
    """
    Flip vertically the content (e.g alpha values) of an 1d buffer
    structure. buffer representing an array type (w, h) 

    :param source : 1d buffer created from array type(w, h) 
    :param target : 1d buffer numpy.empty(ax_ * ay_, dtype=numpy.uint8) 
    that will be the equivalentof the source array but flipped vertically 
    :param width  : source width. 
    :param height : source height. 
    :return       : return 1d buffer (source array flipped)
    """
    return vfb_c(source, target, width, height)
EXAMPLE :

import IndexMapping
from IndexMapping.mapping import to1d
import pygame
import numpy
import os

PROJECT_PATH = IndexMapping.__path__
os.chdir(PROJECT_PATH[0] + "\\test")

width, height = 800, 1024
screen = pygame.display.set_mode((width, height))
background = pygame.image.load('../Assets/A1.png').convert()
w, h = background.get_size()
rgb_array = pygame.surfarray.pixels3d(background)
c_buffer = numpy.empty(w * h * 3, dtype=numpy.uint8)

# Convert 3d array (rgb_array) into a C buffer (1d)
for i in range(w):
    for j in range(h):
        for k in range(3):
            index = to1d(i, j, k, w, 3)
            c_buffer[index] = rgb_array[i, j, k]       
import IndexMapping
from IndexMapping.mapping import to3d
import pygame
from pygame.surfarray import pixels3d
import numpy
import os

PROJECT_PATH = IndexMapping.__path__
os.chdir(PROJECT_PATH[0] + "\\test")

width, height = 800, 1024
screen = pygame.display.set_mode((width, height))
background = pygame.image.load('../Assets/A1.png').convert()
w, h = background.get_size()

rgb_array = pixels3d(background).transpose(1, 0, 2)
c_buffer = rgb_array.flatten()

length = c_buffer.size
assert length == w * h * 3, \
    "C buffer has an incorrect length, got %s instead of %s " \ 
% (length, w * h * 3)

rgb_array = numpy.zeros((w, h, 3), numpy.uint8)
        
# Build a 3d array using the function to3d
for i in range(length):
    x, y, z = to3d(i, w, 3)
    rgb_array[x, y, z] = c_buffer[i]
import IndexMapping
import numpy
from IndexMapping.mapping import vfb_rgb
import pygame
from pygame.surfarray import pixels3d
import os

PROJECT_PATH = IndexMapping.__path__
os.chdir(PROJECT_PATH[0] + "\\test")

width, height = 800, 1024
screen = pygame.display.set_mode((width, height))
background = pygame.image.load('../Assets/A1.png').convert()
background = pygame.transform.smoothscale(background, (640, 480))
w, h = background.get_size()
rgb_array = pixels3d(background)

rgb_buffer = rgb_array.flatten()
target_buffer = numpy.empty(w * h * 3, numpy.uint8)
rgb_buffer_transpose = vfb_rgb(rgb_buffer, target_buffer, w, h)

Building cython code

If you need to compile the Cython code after any changes in the 
file Mapping.pyx:

1) open a terminal window
2) Go in the main project directory where (mapping.pyx & 
   mapping.pxd files are located)
3) run : python setup_Mapping.py build_ext --inplace

If you have to compile the code with a specific python 
version, make sure to reference the right python version 
in (python38 setup_mapping.py build_ext --inplace)

If the compilation fail, refers to the requirement section and 
make sure cython and a C-compiler are correctly install on your
 system.
- A compiler such visual studio, MSVC, CGYWIN setup correctly on 
  your system.
  - a C compiler for windows (Visual Studio, MinGW etc) install 
  on your system and linked to your windows environment.
  Note that some adjustment might be needed once a compiler is 
  install on your system, refer to external documentation or 
  tutorial in order to setup this process.e.g https://devblogs.
  microsoft.com/python/unable-to-find-vcvarsall-bat/

Credit

Yoann Berenguer

Dependencies :

python >= 3.0
cython >= 0.28

License :

MIT License

Copyright (c) 2019 Yoann Berenguer

Permission is hereby granted, free of charge, to any person 
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without 
restriction, including without limitation the rights to use, 
copy, modify, merge, publish, distribute, sublicense, and/or 
sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following 
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

Testing:

>>>from IndexMapping.test.test_mapping import run_test
>>>run_test()

Timing :

C:\>python profiling.py

Testing to1d        per call 2.627551e-07 overall time 0.2627551 for 1000000
Testing to3d        per call 1.217256e-07 overall time 0.1217255 for 1000000
Testing vfb_rgb     per call 0.0015129453 overall time 1.5129453 for 1000 --> image 800x800x3
Testing vmap_buffer per call 1.189032e-07 overall time 0.1189032 for 1000000
Testing vfb_rgba    per call 0.001878 overall time 1.8783595 for 1000     --> image 800x800x4

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

IndexMapping-1.0.2.tar.gz (1.3 MB view details)

Uploaded Source

Built Distributions

IndexMapping-1.0.2-cp310-cp310-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.10 Windows x86-64

IndexMapping-1.0.2-cp39-cp39-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.9 Windows x86-64

IndexMapping-1.0.2-cp38-cp38-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.8 Windows x86-64

IndexMapping-1.0.2-cp37-cp37m-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.7m Windows x86-64

IndexMapping-1.0.2-cp36-cp36m-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.6m Windows x86-64

File details

Details for the file IndexMapping-1.0.2.tar.gz.

File metadata

  • Download URL: IndexMapping-1.0.2.tar.gz
  • Upload date:
  • Size: 1.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/51.0.0 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for IndexMapping-1.0.2.tar.gz
Algorithm Hash digest
SHA256 fdff2963e84d6f8d19c337b0182f6cfca90f4092df531bb530c35f805ab4f482
MD5 12bca605a3eaefe63aaa55e46aaab633
BLAKE2b-256 0d4fe88c1b2373cfde3020fb6b6e3a535c73ddf5d7597fa8b1b0574bba0ee882

See more details on using hashes here.

File details

Details for the file IndexMapping-1.0.2-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: IndexMapping-1.0.2-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/51.0.0 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for IndexMapping-1.0.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 c6ef6eff81b417d0814a4b380c06310ab4fc8d787d073af85748e75e7f41d11f
MD5 b6afc0c0afac281cf7c0350be94ae65f
BLAKE2b-256 a6922b8bc1d6a2204d375c441ea41ab827b3b33666581e76e299ca9205c57d82

See more details on using hashes here.

File details

Details for the file IndexMapping-1.0.2-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: IndexMapping-1.0.2-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/51.0.0 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for IndexMapping-1.0.2-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 791c8acfd272e0bcd79892feb6d6f5e0e10b316c92762471841b1a7e7086bb37
MD5 86b2d38b906577cd82c3b679c3e9581f
BLAKE2b-256 34e0a0e854fbc102633981a0c4f7ccb18d513fbe15ae8d4b72db776327fed25e

See more details on using hashes here.

File details

Details for the file IndexMapping-1.0.2-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: IndexMapping-1.0.2-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/51.0.0 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for IndexMapping-1.0.2-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 8e66fe9092373645a408d715b6f2b12bc15ad7f54be9d0cff57015805892ec80
MD5 699f3625aa36e33dff4990d585fb62cf
BLAKE2b-256 a61027e996cefe0d44ed451beea52f21092f5ab1c046e13889a728c146b42676

See more details on using hashes here.

File details

Details for the file IndexMapping-1.0.2-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: IndexMapping-1.0.2-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/51.0.0 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for IndexMapping-1.0.2-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 e8a3238796e3456431c77a67584d315ccb009a4f7abf2bcde7c6a9821610f0ce
MD5 77be20bc889fbd3af4837ef32982df8f
BLAKE2b-256 681ac7db611d5b0c1c037c0de387092c14006949b50e9080d753ae54dd39d4d6

See more details on using hashes here.

File details

Details for the file IndexMapping-1.0.2-cp36-cp36m-win_amd64.whl.

File metadata

  • Download URL: IndexMapping-1.0.2-cp36-cp36m-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.6m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/51.0.0 requests-toolbelt/0.9.1 tqdm/4.54.1 CPython/3.8.6

File hashes

Hashes for IndexMapping-1.0.2-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 f3b3182ab12268f074bebe17443ceb805625d6810bdb982c98bcef3c63760a3a
MD5 e09076043d8d26c6982098a8ce4398b2
BLAKE2b-256 b04d0a39d922dc26a85eb5342f2e31d91814db59efb13d3cb5b7aa5e98cf5145

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page