iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tests/test-Image.C
/*! @file
@author Randolph Voorhies
@copyright GNU Public License (GPL v3)
@section License
@verbatim
// ////////////////////////////////////////////////////////////////////////
// The iLab Neuromorphic Robotics Toolkit (NRT) //
// Copyright 2010-2012 by the University of Southern California (USC) //
// and the iLab at USC. //
// //
// iLab - University of Southern California //
// Hedco Neurociences Building, Room HNB-10 //
// Los Angeles, Ca 90089-2520 - USA //
// //
// See http://ilab.usc.edu for information about this project. //
// ////////////////////////////////////////////////////////////////////////
// This file is part of The iLab Neuromorphic Robotics Toolkit. //
// //
// The iLab Neuromorphic Robotics Toolkit is free software: you can //
// redistribute it and/or modify it under the terms of the GNU General //
// Public License as published by the Free Software Foundation, either //
// version 3 of the License, or (at your option) any later version. //
// //
// The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
// that it will be useful, but WITHOUT ANY WARRANTY; without even the //
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
// PURPOSE. See the GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with The iLab Neuromorphic Robotics Toolkit. If not, see //
// <http://www.gnu.org/licenses/>. //
// ////////////////////////////////////////////////////////////////////////
@endverbatim */
#include <type_traits>
using namespace nrt;
template <class T>
void printImage(Image<T> const img)
{
NRT_INFO("Image(" << img.width() << ", " << img.height() <<") = { ");
for (int y = 0; y < img.height(); ++y)
{
std::stringstream str; str << " {";
for (int x = 0; x < img.width(); ++x) str << " " << img.at(x, y) << " ";
NRT_INFO(str.str() << "}");
}
NRT_INFO("}");
}
int main(int argc, char const* argv[])
{
if (argc != 2) NRT_FATAL("Give me the pixel value (format \"PixRGB(255,255,255)\" (quotes needed)");
nrt::PixRGB<nrt::byte> x; std::stringstream stream; stream << argv[1]; stream >> x;
NRT_INFO("-----------------------RGB:");
NRT_INFO("Pixel: " << x);
NRT_INFO("first channel: " << x.channels[0]);
NRT_INFO("-----------------------HSV:");
NRT_INFO("-----------------------RGB:");
NRT_INFO("-----------------------Image tests:");
Image<PixGray<nrt::byte>> im1 { { 1, 2, 3 } }; // construction from initializer list
printImage(im1);
// test range-based for loop
for (auto const & pix : im1) NRT_INFO("pix = " << pix);
Image<PixGray<nrt::byte>> im2 { { 1, 2, 3 }, { 4, 5, 6} };
printImage(im2);
Image<PixGray<nrt::byte>> im3 { { 1 }, { 2 }, { 3 } };
printImage(im3);
// Some ImageSet testing:
is.push_back(im1);
is.push_back(im2);
is.push_back(im3);
NRT_INFO("This should be 2: " << is.at(1).at(1, 0));
NRT_INFO("Interpolated should be 3: " << is.at(1).interpolate(0, 0.55));
Image<PixRGB<byte> > colim { { PixRGB<nrt::byte>(2,12,52) },
{ PixRGB<nrt::byte>(4,22,62) },
{ PixRGB<nrt::byte>(6,32,72) } };
NRT_INFO("RGB interp should be(3,17,57) " << colim.interpolate(0,0.5));
// Some Layout testing:
NRT_INFO("Layout dims, should be (7,3): " << la.dims());
Image<PixGray<byte>> r = la.render();
NRT_INFO("Rendered dims, should be (7,2): " << r.dims());
NRT_INFO("Rendered pixel, should be 5: " << r.at(4, 1));
//testing iterators
Image<PixGray<float>> imiter = { { 1, 2, 3 }, { 4, 5, 6} };
Image<PixGray<float>>::const_iterator i = imiter.const_begin();
NRT_INFO("Test read iterators: result should display Values: 1-6.");
while (i != imiter.const_end())
NRT_INFO("Value: " << *i++);
NRT_INFO("Test read row iterator: result should display Values: 4-6.");
Image<PixGray<float>>::const_row_iterator irow = imiter.const_row_begin(1);
while(irow != imiter.const_row_end(1))
NRT_INFO("Value: " << *irow++);
NRT_INFO("Test read column iterator: result should display Values: 2,5.");
Image<PixGray<float>>::const_col_iterator icol = imiter.const_col_begin(1);
while(icol != imiter.const_col_end(1))
NRT_INFO("Value: " << *icol++);
NRT_INFO("Test read rectangle iterator: result should display Values: 1,2,4,5.");
Image<PixGray<float>>::const_rect_iterator irect = imiter.const_rect_begin(rect);
while(irect != imiter.const_rect_end(rect))
NRT_INFO("Value: " << *irect++);
Image<PixGray<float>>::rect_iterator jrect = imiter.rect_begin(rect);
NRT_INFO("Test write rectangle iterator: result should be 0,0,3;0,0,6.");
while(jrect != imiter.rect_end(rect))
*jrect++ = PixGray<float>(0.0F);
printImage(imiter);
NRT_INFO("Test write iterator: result should be all 1s.");
Image<PixGray<float>>::iterator j = imiter.begin();
while (j != imiter.end())
*j++ = PixGray<float>(1.0F);
printImage(imiter);
// Some math operator testing
Image<PixGray<float>> imo1 = { { 1, 1, 1 }, { 1, 1, 1} };
Image<PixGray<float>> imo2 = { { 2, 2, 2 }, { 2, 2, 2} };
// Image operators with images, pixels, or pod types, the underyling pod type
// can be different, but the pixel type must be the same
imo1 += imo2;
imo1 -= PixGray<int>(2);
imo1 *= 2.0F;
//imo1 /= PixRGB<float>(); //can't operate on different pixels
imo3 = (imo1 + imo2 - PixGray<float>(0.0F))/2.0;
NRT_INFO("Operator result should be all 2's");
printImage(imo3);
//test accumulate
Image<PixGray<float>> ima = { { 1, 2, 3 }, { 4, 5, 6} };
PixGray<float> val = nrt::accumulate(ima);//sum all elements
PixGray<float> vale = nrt::accumulate(ima, PixGray<float>(4.0F));//sum starting at a value
NRT_INFO("Accumulate result should be 21 and 25: " << val << "," << vale );
//these tests are the same as above, but we pass in our own function, or
//lambda or function object
[](PixGray<float> const & val1, PixGray<float> const & val2){ return val1 + val2; });
PixGray<float> vale1 = nrt::accumulate(ima, PixGray<float>(4.0F), std::plus<PixGray<float>>());
NRT_INFO("Accumulate result should be 21 and 25: " << val1 << "," << vale1 );
Image<PixGray<float>> imt1 = { { 1, 2, 3 }, { 4, 5, 6} };
//create a new image from a single image by applying our lambda at every pixel
imt2 = nrt::transform(imt1, [](PixGray<float> const & v){ return v*v; });
//create a new image from two images by applying our function at every pixel,
//return is promoted type so inputs can be of different types. Computations
//performed as input types of functor.
imt2 = nrt::transform(imt1, imt1, std::multiplies<PixGray<float>>());
NRT_INFO("Transform result should be { { 1 4 9 }, { 16 25 36 } }: ");
printImage(imt2);
//in place version of single input transform
nrt::transformInPlace(imt1, [](PixGray<float> const & v){ return v*v; });
NRT_INFO("Transform result should be { { 1 4 9 }, { 16 25 36 } }: ");
printImage(imt1);
//in place version of two input transform
nrt::transformInPlace(imt2, imt2, std::divides<PixGray<float>>());
NRT_INFO("Transform result should be { { 1 1 1 }, { 1 1 1 } }: ");
printImage(imt2);
//for_each test
struct print { void operator()(PixGray<float> const & val)
{NRT_INFO("for_each test using a print functor: " << val); }};
nrt::for_each(imt1, print());
// Test rescaling:
NRT_INFO("testing rescale...");
for (auto & pix : ii) pix = PixRGB<float>(10.0F, 11.0F, 12.0F);
for (int32 w = 1; w < 121; ++w)
for (int32 h = 1; h < 55; ++h) {
Image<PixRGB<float> > rii = rescaleBilinear<void>(ii, Dims<int32>(w, h));
for (auto const & val : rii) for (auto const & c : val.channels) if (isnan(c)) NRT_FATAL("found a NaN");
}
NRT_INFO("No NaN's found after rescale. Good.");
return 0;
}