{"id":18008289,"url":"https://github.com/clemapfel/image_processing","last_synced_at":"2025-04-04T11:46:52.570Z","repository":{"id":122576520,"uuid":"389371472","full_name":"Clemapfel/image_processing","owner":"Clemapfel","description":"real-time, interactive 2d image processing library","archived":false,"fork":false,"pushed_at":"2021-08-29T22:08:45.000Z","size":4198,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T19:51:16.999Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Clemapfel.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-25T14:50:16.000Z","updated_at":"2023-01-10T10:08:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"92097867-b68a-4d53-8e45-8ac919f4ca6c","html_url":"https://github.com/Clemapfel/image_processing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clemapfel%2Fimage_processing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clemapfel%2Fimage_processing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clemapfel%2Fimage_processing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clemapfel%2Fimage_processing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Clemapfel","download_url":"https://codeload.github.com/Clemapfel/image_processing/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247174403,"owners_count":20896074,"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":[],"created_at":"2024-10-30T01:18:13.273Z","updated_at":"2025-04-04T11:46:52.542Z","avatar_url":"https://github.com/Clemapfel.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CRISP: real-time, interactive signal processing\n\nA portable, lightweight, modern C++20 Library implementing most common features of digital image processing as mentioned in \"Digital Image Processing\" (R.C.Gonzales, R.E.Woods, 2017). Intended for educational purposes or personal use only.\n\nSupports video-game-like interactivity, real-time rendering, on- and off-gpu processing on Mac, Windows and Linux. \n\n### Dependencies\n- **fftw** (3.39): for fourier-transform computation\n- **ranges-v3**: for ranges\n- **Eigen** (3.3.3): for cpu-side matrix operations\n- **OpenGL** (3.3+ core): for gpu-side processing\n- **SFML** (2.5.1): for interactivity and interfacing with OpenGL \n- **Lua** (5.4): for code generation\n- **sol** (3.0): for interfacing with lua\n\n### Documentation\nUntil this section is fully formed please consider checking the headers directly. They are intentionally formatted to be very easily referenced back to for questions.\n\n## [Images](include/image.hpp)\nImages are at the heart of crisp and operations in a image processing application are performed on them as objects. In crisp there are two way of representing a picture: An **image**, a rectangular array of values, lives on the ram and operations that interact with them happen on the CPU. A **texture**, in comparison, lives entirely on the graphics cards ram (gram) and most of the operations concerning textures happen on the GPU insted. This can drastically increase performance at the cost of ease of use and flexibility. For this section we will only concern ourself with **images** which are best to think of a simply m\\*n matrices of arbitrary values.\n\n#### [binary_image.hpp](include/binary_image.hpp)\nBinary images are matrices of ``bool``s, each of their elements can only be zero or one. In real-life you can think of them as black-and-white images, think a QR code, a barcode or maybe a really bad scan your teacher had to fax to themself because the printer was out of ink.\nBinary images have the advantage of being fairly light memory-wise and allow for bit-arithmetics making them overall the best-suited cpu-side image to use in real-time processing. A common use-case for binary are as outputs of morphological segmentation, bitplane seperation for the purpose of compression or as elements that represent images as background- xor foreground-pixels.\n\n#### [grayscale_image.hpp](include/grayscale_image.hpp)\nGrayscale images are matrices where each element is a single float in the range [0, 1]. While at first seeming limited for modern applications, grayscale images are at the heart of any image processing pipeline because even if an image is using a completely different color system, it can usually still be represented by one or more grayscale images. For example the problem processing a full-color rgba image can be segmented into processing 4 grayscale images representing each color component respectively.\n\n#### [rgba_image.hpp](include/rgba_image.hpp)\nWhich is essentially what rgba images are in crisp too, just 4 greyscale images stacked on top of each other with the first plane respresenting red, 2nd green, 3rd blue and 4th the transparency value. These are as close to actual image files as you will get, however if you actually want to save them to memory you will have to do so through a fourth image class:\n\n### Image Examples\nThere's no point in processing images if we can't see them so let's do that right now:\n\n```cpp\nint main() {\n  // create a render window for display\n  RenderWindow window;\n  window.create(1280, 740);\n  \n  // load an image\n  auto image = GreyScaleImage();\n  image.create_from_file(\"./test_file.png\");\n  \n  // to display an image we need to bind it to renderable sprite\n  auto sprite = Sprite();\n  sprite.create_from(image);\n  sprite.align_center_with(Vector2f(window.get_resolution().at(0) * 0.5f, window.get_resolution().at(1) * 0.5f));\n  \nwhile (window.is_open())\n{\n  auto time = window.update();\n  \n  window.clear();\n  window.draw(sprite);\n  window.display();\n}\n```\nYou may have noticed that we're loading from a .png which is obviously full-color but the image is only a greyscale image. When loading from a file the image class automatically converts the image into the correct color domain via a pre-defined process so you don't have to worry about file-compatibility issues. Even if those were a case transforming one image type into a another is as simple as casting them (though you might want to be careful as this may quadruple the space taken in ram):\n```cpp\nauto color_img = ColorImage(...\nauto binary_img = BinaryImage(...\n\nauto grey_img = GrayScaleImage(binary_img);\n``` \n\n#### [color.hpp](include/color.hpp)\nSupport for common color representations RGB, HSV, HSL and Grayscale including conversion and mixing between any of them.\n\n```cpp \nauto as_rgb = RGB{123, 140, 129, 255}; // elements are uint8_t\nColor color = rgb;\ncolor = color.invert();\n\nHSV in_hsv = convert_to\u003cHSV\u003e(color);\nHSL in_hsl = convert_to\u003cHSL\u003e(as_hsv);\n\nassert(convert_to\u003cHSL\u003e(color) == color.as_hsl());\n\nfloat in_gray = convert_to\u003cGrayScale\u003e(as_hsl);\nauto mixed = mix\u003cColor\u003e(color, Color(as_gray), 0.5);\n```\n\n#### [render_window.hpp](include/render_window.hpp)\nCreates a window that can be used for rendering in real-time at an arbitrary refresh rate\n\n```cpp\ncrisp::RenderWindow window;\nwindow.create(1920, 1080, true, 60); // create a 1920x1080 fullscreen-only window with a max refresh rate of 60fps\nwindow.set_background_color(Color(255, 255, 0, 1)); // set background to magenta for better contrast\n\ncrisp::Image image = //...\ncrisp::Shader shader = /...\ncrisp::Transform transform = /...\n\nwhile (window.is_open())  // closes when \"x\" is pressed\n{\n  auto time = window.update();  // update things like the keyboard state\n  \n  window.clear();\n  window.draw(image, shader, transform);\n  window.display(); // vsyncs to reach at most target 60fps\n}\n```\n\n### Authors\nClemens Cords (www.clemens-cords.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclemapfel%2Fimage_processing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclemapfel%2Fimage_processing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclemapfel%2Fimage_processing/lists"}