{"id":13418379,"url":"https://github.com/matt-42/vpp","last_synced_at":"2025-04-04T20:14:41.239Z","repository":{"id":16168737,"uuid":"18914957","full_name":"matt-42/vpp","owner":"matt-42","description":"Video++, a C++14 high performance video and image processing library.","archived":false,"fork":false,"pushed_at":"2019-02-07T13:14:38.000Z","size":603,"stargazers_count":722,"open_issues_count":4,"forks_count":110,"subscribers_count":53,"default_branch":"master","last_synced_at":"2025-03-28T19:11:13.199Z","etag":null,"topics":["c-plus-plus","image-processing","image-processing-library","optical-flow","tracking","video-processing"],"latest_commit_sha":null,"homepage":"http://documentup.com/matt-42/vpp","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matt-42.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-18T14:14:49.000Z","updated_at":"2025-03-09T08:44:57.000Z","dependencies_parsed_at":"2022-07-21T06:47:20.979Z","dependency_job_id":null,"html_url":"https://github.com/matt-42/vpp","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-42%2Fvpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-42%2Fvpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-42%2Fvpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matt-42%2Fvpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matt-42","download_url":"https://codeload.github.com/matt-42/vpp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247242680,"owners_count":20907134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-plus-plus","image-processing","image-processing-library","optical-flow","tracking","video-processing"],"created_at":"2024-07-30T22:01:01.624Z","updated_at":"2025-04-04T20:14:41.211Z","avatar_url":"https://github.com/matt-42.png","language":"C++","readme":"[![Travis build status](https://travis-ci.org/matt-42/vpp.svg?branch=phd_work)](https://travis-ci.org/matt-42/vpp)\n\nVideo++\n=============\n\nVideo++ is a video and image processing library taking advantage of\nthe C++14 standard to ease the writing of fast video and image\nprocessing applications. The idea behind Video++ performance is to\ngenerate via meta-programming code that the compiler can easily \noptimize. Its main features are:\n\n  - Generic N-dimensional image containers.\n  - A growing set of image processing algorithms.\n  - Zero-cost abstractions to easily write image processing algorithms for multicore SIMD processors.\n  - An embedded language to evaluate image expressions.\n\nTested compilers: **G++6, Clang++ 3.8.0**\nDependencies:\n  - C++14\n  - [Eigen 3](http://eigen.tuxfamily.org)\n  - [Boost](http://www.boost.org/)\n  - [the iod library](http://github.com/matt-42/iod) installed by the install.sh script\n\nVideo++ is free of use (BSD). If you you are using Video++ in\nresearch related work, you are welcome to cite us :\n\n```\n@inproceedings{garrigues2014video++,\n  title={Video++, a modern image and video processing C++ framework},\n  author={Garrigues, Matthieu and Manzanera, Antoine},\n  booktitle={Design and Architectures for Signal and Image Processing (DASIP), 2014 Conference on},\n  pages={1--6},\n  year={2014},\n  organization={IEEE}\n}\n```\n\n## Getting Started\n\n### Installation\n\nBefore installing Video++, you need to get Eigen3 and Boost on your\nsystem. Your package managers will probably help you to install these\nlibraries. Then, use the install.sh script to install iod and vpp :\n\n```\ngit clone https://github.com/matt-42/vpp.git\ncd vpp\n./install.sh your_install_prefix # Install iod and vpp in a given prefix\n```\n\nVideo++ is a header-only library, so you just need include the vpp.hh\nheader to access all the basic features of the library:\n\n```c++\n#include \u003cvpp/vpp.hh\u003e\n```\n\nIf you use the parallel constructs of Video++ and need to target multiple cores, activate the OpenMP optimizations:\n```sh\ng++ -I __your_isntall_prefix__ main.cc -fopenmp -lgomp\n```\n\n## Image Containers\n\nThe generic container imageNd\u003cV, N\u003e represents a dense N-dimensional\nrectangle set of pixels with values of type V. For convenience,\nimage1d\u003cV\u003e, image2d\u003cV\u003e, image3d\u003cV\u003e are respectively aliases to\nimageNd\u003cV, 1\u003e, imageNd\u003cV, 2\u003e, and imageNd\u003cV, 3\u003e.\n\n```c++\n// Allocates a 100 rows x 200 columns 2d image of integers.\nimage2d\u003cint\u003e A(100, 200);\n```\n\nThese types provide accesses to the pixel buffer and to other piece of\ninformation useful to process the image. In contrast to std::vector,\nassigning an image to the other does not copy the data, but share them\nso no accidental expensive deep copy happen.\n\n```c++\nimage2d\u003cint\u003e B = A; // B now points to A's data.\n```\n\n### Image options\n\n#### _border and _aligned\n\nImage constructors also take special image options. ```_border``` (default: 0) set\nthe border surrounding the pixels so filter accessing neighborhood\naccess to valid pixels when traversing image borders. ```_aligned``` (default: 16 bytes)\nset the alignment in bytes of the beginning of the first pixel of each row\n(border excluded) to enable aligned SIMD memory instructions.\n\n```c++\n// Allocates a 100x100 image with a border of 3 pixels\n// and rows aligned on 32 bytes (best for 256 bits SIMD\n// units like AVX2).\nimage2d\u003cint\u003e C(100, 100, _border = 3, _aligned = 32);\n```\n\n#### _data and _pitch\n\nTo use image buffers allocated by external libraries, the ```_data``` and\n```_pitch``` options respectively pass the pointer to the first\npixel of the image and the distance in bytes between the first pixels\nof two consecutive rows. When setting these options, video++ is not\nresponsible of freeing the data buffer.\n\n\n```c++\n// Wraps an external images of 100x100 pixels, with a pitch\n// of 1000 bytes.\nimage2d\u003cint\u003e C(100, 100, _data = my_data_ptr, _pitch = 1000);\n```\n\n### OpenCV interoperability\n\nThe header ```vpp/utils/opencv_bridge.hh``` (not included by\n```vpp/vpp.hh```) provides explicit conversions to and from OpenCV image types. It\nallows running video++ algorithms on OpenCV images and to run OpenCV algorithms on\nvideo++ images, without cloning the pixel buffer.  Ownership of the buffer\nwill switch to OpenCV or Video++ depending of the order of the\ndestructor calls.\n\n```c++\n// Load JPG image in a vpp image using OpenCV imread.\nimage2d\u003cvuchar3\u003e img = from_opencv\u003cvuchar3\u003e(cv::imread(\"image.jpg\"));\n\n// Write a vpp image using OpenCV imwrite.\ncv::imwrite(\"in.jpg\", to_opencv(img));\n```\n\nNote: Since it is not possible to opencv to free video++ images, an\nOpenCV image must not be the last one to hold a video++ image.\n\n\n## Vector Types\n\nVideo++ vector types are aliases to eigen3 vectors, providing fast linear algebra. The syntax\nis ```v{T}{N}``` such as\n\n - T is one the following : *char, short, int, float, double, uchar, ushort, uint*.\n - N is an integer in [0, 4].\n\nFor example, the type ```image2d\u003cvuchar4\u003e``` can handle an image of RGBA 8-bit.\n\n\n\n## Pixel Wise Kernels\n\nThe ```pixel_wise``` construct allows to easily and efficiently map\nsimple kernel functions on all the pixels of a set of images. It relies\non OpenMP to spread the processing on all the available cores, and\nSIMD-vectorize the processing of rows when possible. If the kernel\nfunction returns a value, ```pixel_wise``` will return a newly\nallocated image filled with the results of the kernel. Given A and B\ntwo 2d images of integers:\n\n```c++\n// Compute C, the parallel pixel wise sum of A and B.\nauto C = pixel_wise(A, B) | [] (int\u0026 a, int\u0026 b) { return a + b; };\n\n// Compute the average of the c4 neighborhood.\npixel_wise(relative_access(A), B) | [] (auto a, int\u0026 b) {\n  b = (a(-1, 0) + a(1, 0) + a(0, 1) + a(0, -1)) / 4;\n};\n```\n\n### Kernel arguments\n\nGiven ```pixel_wise(I_0, ..., I_N) | my_kernel```, ```pixel_wise``` will\ntraverse the domain of I_0 and for every pixel location P call\n```my_kernel(I_0(P), ..., I_N(P))``` with ```I_N(P)``` a reference to the\npixel of I_N located at location P.\n\n### Parallelism and traversal directions\n\nBy default, ```pixel_wise``` traverses the image from left to right\nand top to bottom and spread the processing of different row on\ndifferent cores. The following options allow to change this defaut behavior:\n\n  - **_no_thread**: disable the parallelism.\n\n  - **_left_to_right**: Traverse each row from left to right.\n\n  - **_right_to_left**: Traverse each row from right to left.\n\n  - **_top_to_bottom**: Traverse the rows from top to bottom.\n\n  - **_bottom_to_top**: Traverse the rows from bottom to top.\n\n### Accessing Neighborhood\n\nVideo++ provides fast access to rectangular pixel neighbors inside\npixel_wise kernels. The speed of access mainly comes from the direct\n2d indexing of the neighborhood, and the ability of the compiler to\nvectorize these accesses using SIMD vector extensions. To stay\nportable, no explicit SIMD optimization is done by video++. On the\nother hand, the generated code was designed to be trivial for the\ncompiler to vectorize if the kernel does not contain conditional\nbranching.\n\nThe accesses are expressed in relative coordinates. For example,\n```nbh(1,1)``` accesses the bottom right neighbor of the current\npixel, and ```nbh(0,0)``` refers to the current pixel.\n\n```c++\n// Define a 3x3 neighborhood accessor on image B.\n// Note that for performance reasons, the boundaries\n// of the neighborhood are static.\n\npixel_wise(S, relative_access(B)) | [\u0026] (auto\u0026 s, auto b) {\n\n  // Average the pixels in the c4 neighborhood.\n  s = (b(-1,0) + b(0, -1) +\n      b(1,0) + b(0,1)) / 4;\n};\n```\n\n## Block Wise Kernels\n\nThe```block_wise``` construct allows to map a function on every cell\nof a given grid. This construct is similar to pixel_wise, but instead\nof processing one pixel, the block_wise kernel processes a given cell.\n\n```c++\n// Given a grid with cell of size 10x10 pixels.\nblock_wise(vint2{10, 10}, A, B, C, A.domain()) |\n  [] (auto a, auto b, auto c, box2d box)\n  {\n  \n    // a, b and c are sub images representing A, B\n    // and C at the current cell.\n    // All the algorithms of the library work on sub images.\n\n    // The box argument is the cell representation of A.domain() and holds\n    // the coordinates of the current cell. box.p1() and box.p2() are\n    // respectively the first and the last pixel of the cell.\n};\n```\n\n### Row Wise and Col Wise Kernels\n\n```row_wise``` and ```col_wise``` are shortcuts to process the image by row or by column.\nFor example, the following compute row wise sums of a given image:\n\n```c++\nstd::vector\u003cint\u003e sums(A.nrows(), 0);\nrow_wise(A, A.domain()) | [] (auto\u0026 a, vint2 coord)\n{\n  sums[coord[0]] += a;\n};\n```\n\n## Contributing\n\nContributions are welcome. Do not hesitate to fill issues, send pull\nrequests, or send me emails at matthieu.garrigues@gmail.com.\n","funding_links":[],"categories":["TODO scan for Android support in followings","Image Processing","C++","HarmonyOS","Media Processing"],"sub_categories":["Windows Manager","Rust"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatt-42%2Fvpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatt-42%2Fvpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatt-42%2Fvpp/lists"}