MRaster examples 22.0.0.0
Image Processing Library
Loading...
Searching...
No Matches
demo_data_image.cpp
Go to the documentation of this file.
1// -*- Mode:C++; Coding:us-ascii-unix; fill-column:158 -*-
2/*******************************************************************************************************************************************************.H.S.**/
3/**
4 @file demo_data_image.cpp
5 @author Mitch Richling <https://www.mitchr.me>
6 @brief Demonstrate "data images" and mjr::ramCanvasPixelFilter.@EOL
7 @std C++20
8 @copyright
9 @parblock
10 Copyright (c) 1988-2015, Mitchell Jay Richling <https://www.mitchr.me> All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
13
14 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
18
19 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software
20 without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 DAMAGE.
28 @endparblock
29 @filedetails
30
31 One of the most powerful abstractions in modern image processing is to think of an image as a sample drawn from a real function of two variables taken on a
32 regular grid. This simple change of perspective opens up an entire world of mathematical techniques which may now be applied to image processing problems.
33 In science and engineering visualization we are presented with the situation in reverse. That is to say we have one or more two dimensional grids of data
34 (frequently thought of as values sampled from some underlying function), and we wish to visualize this data by *synthesizing* a pseudo-color image.
35
36 For example, consider the visualizing temperature variation across Kansas -- which, in the grand tradition of Physics, we will assume to be a 2D rectangle.
37 In this case the data consists of temperatures measured on a regular grid across the state. In these contexts we frequently store the "data" in something
38 like HDF5, and then synthesize the visualization into a "image" manged by something like libPNG. Because MRaster supports such a broad array of data types
39 for colors and color components, we can use MRaster images both for visual images and to house data instead. People doing multi-spectral imaging are one
40 of MRaster's largest user communities.
41
42 Another large MRaster community are people visualizing fractals, ODEs, and chaotic systems. For this community the underlying function is known, and can be
43 computed (sometimes at great cost). For this group, the data image serves as samples of this underlying function. Many of the MRaster example programs
44 follow this paradigm:
45
46 - demo_data_and_filter.cpp: We use an integer image to hold values of the Mandelbrot escape time function.
47 - doublePendulumM.cpp: We use four floating point images to store the state of a differential equation solution
48 - sic.cpp & peterdejong.cpp: We use integer images to store a 2D histogram
49
50*/
51/*******************************************************************************************************************************************************.H.E.**/
52/** @cond exj */
53
54//--------------------------------------------------------------------------------------------------------------------------------------------------------------
55#include "ramCanvas.hpp"
56#include "MRMathIVL.hpp"
57
58//--------------------------------------------------------------------------------------------------------------------------------------------------------------
59int main(void) {
60 std::chrono::time_point<std::chrono::system_clock> startTime = std::chrono::system_clock::now();
61 mjr::ramCanvas1c16b escDatRC(1024, 1024, -2.2, 0.8, -1.5, 1.5);
62
63 // Fill escDatRC with values for the Mandelbrot escape function.
64
65 escDatRC.colorizeFltCanvas([](decltype(escDatRC)::coordFltType x, decltype(escDatRC)::coordFltType y) {
66 std::complex<decltype(escDatRC)::coordFltType> z(0.0, 0.0), c(x, y);
67 decltype(escDatRC)::colorChanType count = 0;
68 while ((std::abs(z)<2) && (count<256)) { z = z * z + c; count++; }
69 return decltype(escDatRC)::colorType((count >= 255 ? 0 : count));
70 });
71
72 // escDatRC contains Mandelbrot escape function data, but visually it appears as nothing but a black image -- the maximum grey value at 255 and a total
73 // dynamic range of 65536. Our task now is to create a pseudo-color image to visualize this data.
74
75 // We use the hpf_t filter type to transform our data into pseudo-color images without modifying the original data.
76 typedef mjr::color3c8b oc_t;
77 typedef mjr::ramCanvasPixelFilter::FuncHomoTransform<decltype(escDatRC), oc_t> hpf_t;
78
79 // For our first attempt, we simply use the values in escDatRC as the three components of a 24-bit RGB image.
80 escDatRC.writeTIFFfile("demo_data_and_filter_01.tiff", hpf_t(escDatRC,[](auto inColor) { return oc_t(static_cast<oc_t::channelType>(inColor.getC0())); }));
81
82 // Next we use the integers stored in escDatRC to index a color scheme (Note csCColdeFireRamp has more 256 colors).
83 escDatRC.writeTIFFfile("demo_data_and_filter_02.tiff", hpf_t(escDatRC,[](auto inColor) { return oc_t::csCColdeFireRamp::c(inColor.getC0()*oc_t::csCColdeFireRamp::numC/255); }));
84
85 // Like the previous line, but with a 30x multiplayer so the colors wrap around. This is a pretty typical way to draw the escape function.
86 escDatRC.writeTIFFfile("demo_data_and_filter_03.tiff", hpf_t(escDatRC,[](auto inColor) { return oc_t::csCColdeFireRamp::c(30*inColor.getC0()); }));
87
88 // We have created three different images, and our original data remains untouched.
89
90 std::chrono::duration<double> runTime = std::chrono::system_clock::now() - startTime;
91 std::cout << "Total Runtime " << runTime.count() << " sec" << std::endl;
92}
93/** @endcond */
int main(int argc, char *argv[])