Skip to content

Commit

Permalink
image_calc: Can make random images
Browse files Browse the repository at this point in the history
  • Loading branch information
oleg-alexandrov committed Oct 17, 2023
1 parent 299c7f2 commit 3e2bd63
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
3 changes: 3 additions & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ sfs (:numref:`sfs`):
* Added an example for Kaguya TC (:numref:`sfs_kaguya`).
* Added the option ``--albedo-robust-threshold``.

image_calc (:numref:`image_calc`):
* Added the ability to create a random image.

misc:
* Fixed a couple of runtime errors when using conda packages on OSX.
* Eliminated a procedure for cleaning the name of an input path that was
Expand Down
12 changes: 12 additions & 0 deletions docs/tools/image_calc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ Create a mask

Positive values will become 1, and the rest will become 0.

Create an image with random values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

::

image_calc -c "rand(var_0)" -d float32 \
input.tif -o output.tif

The produced values will be between 0 and 1. Other operations
can be combined with this one. For example, one could
add a random value multiplied by a constant to the input image.

Add a value to the geoheader metadata
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
36 changes: 23 additions & 13 deletions src/asp/Tools/image_calc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
// limitations under the License.
// __END_LICENSE__


/// \file image_calc.cc
///

// Apply specified arithmetic operations to given input images and save
// the output with desired pixel type.

#include <asp/Core/Common.h>
#include <asp/Core/Macros.h>

#include <vw/Core/FundamentalTypes.h>
#include <vw/Core/Log.h>
#include <vw/Image/Algorithms.h>
Expand All @@ -36,17 +38,15 @@
#include <vw/FileIO/DiskImageView.h>
#include <vw/FileIO/DiskImageUtils.h>

#include <asp/Core/Common.h>
#include <asp/Core/Macros.h>

#include <vector>

#include <boost/program_options.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/math/special_functions/sign.hpp>

#include <vector>
#include <random>

namespace po = boost::program_options;

using namespace vw;
Expand Down Expand Up @@ -74,6 +74,7 @@ enum OperationType {
OP_negate,
OP_abs,
OP_sign,
OP_rand,
// BINARY operations
OP_add,
OP_subtract,
Expand All @@ -90,16 +91,17 @@ enum OperationType {
OP_eq
};

std::string getTagName(const OperationType o) {
std::string getTagName(const OperationType op) {

switch(o) {
switch(op) {

case OP_pass: return "PASS";
case OP_number: return "NUMBER";
case OP_variable: return "VARIABLE";
case OP_negate: return "NEGATE";
case OP_abs: return "ABS";
case OP_sign: return "SIGN";
case OP_rand: return "RAND";
case OP_add: return "ADD";
case OP_subtract: return "SUBTRACT";
case OP_divide: return "DIVIDE";
Expand Down Expand Up @@ -143,6 +145,14 @@ T manual_max(const std::vector<T> &vec) {
return maxVal;
}

// Initialize the random number generator
std::mt19937 mt(0);

// Return a random number in the range [0, 1]
template <typename T>
T custom_rand_0_1(T val) {
return double(mt() - mt.min())/double(mt.max() - mt.min());
}

// This type represents an operation performed on one or more inputs.
struct calc_operation {
Expand Down Expand Up @@ -232,6 +242,7 @@ struct calc_operation {
case OP_negate: return T(-1 * inputResults[0]);
case OP_abs: return T(std::abs(inputResults[0])); // regular abs casts to integer.
case OP_sign: return T(boost::math::sign(inputResults[0]));
case OP_rand: return T(custom_rand_0_1(inputResults[0]));

// Binary
if (numInputs < 2)
Expand Down Expand Up @@ -323,16 +334,15 @@ struct calc_grammar : b_s::qi::grammar<ITER, calc_operation(), b_s::ascii::space
("lte(" > expression [push_back(at_c<IN>(_val), _1), at_c<OP>(_val)=OP_lte] % ',' > ')') |
("gte(" > expression [push_back(at_c<IN>(_val), _1), at_c<OP>(_val)=OP_gte] % ',' > ')') |
("eq(" > expression [push_back(at_c<IN>(_val), _1), at_c<OP>(_val)=OP_eq ] % ',' > ')') |

( ("pow(" > expression > ',' > expression > ')')
[push_back(at_c<IN>(_val), _1), push_back(at_c<IN>(_val), _2), at_c<OP>(_val)=OP_power] ) |
[push_back(at_c<IN>(_val), _1), push_back(at_c<IN>(_val), _2), at_c<OP>(_val)= OP_power
] ) |
("abs(" > expression [push_back(at_c<IN>(_val), _1), at_c<OP>(_val)=OP_abs] > ')') | // Absolute value
("sign(" > expression [push_back(at_c<IN>(_val), _1), at_c<OP>(_val)=OP_sign] > ')') | // Sign function
("rand(" > expression [push_back(at_c<IN>(_val), _1), at_c<OP>(_val)=OP_rand] > ')') | // rand function
('(' > expression [push_back(at_c<IN>(_val), _1), at_c<OP>(_val)=OP_pass] > ')') | // Something in parenthesis
('-' >> factor [push_back(at_c<IN>(_val), _1), at_c<OP>(_val)=OP_negate] ) | // Negative sign
//('+' >> factor [handler] ); // Positive sign
("var_" > int_ [at_c<VAR>(_val)=_1, at_c<OP>(_val)=OP_variable] ) ;
//(b_s::ascii::string [at_c<VAR>(_val)=_1, at_c<OP>(_val)=OP_variable] ) ; // A variable name

/*
Expand Down Expand Up @@ -524,7 +534,7 @@ void handle_arguments(int argc, char *argv[], Options& opt) {
"The operation to be performed on the input images. "
"Input images must all be the same size and type. "
"Currently only single channel images are supported. "
"Recognized operators: +, -, /, *, (), pow(), abs(), sign(), min(), max(), var_0, var_1, ..."
"Recognized operators: +, -, /, *, (), pow(), abs(), sign(), rand(), min(), max(), var_0, var_1, ..."
"Use var_n to refer to the pixel of the n-th input image. "
"Order of operations is parsed with RIGHT priority, use parenthesis "
"to assure the order you want. "
Expand Down

0 comments on commit 3e2bd63

Please sign in to comment.