Skip to content

Commit

Permalink
comments in headers
Browse files Browse the repository at this point in the history
  • Loading branch information
Subhasis Das committed Jun 10, 2014
1 parent 7245ae4 commit 7e0dbee
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 13 deletions.
38 changes: 36 additions & 2 deletions include/iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@
using namespace cv;
using namespace std;

/**
* This is a wrapper over MatIterator_ to make it consistent with
* range based for loops in C++11.
* The IterableMat<T> class has a begin() and an end() iterator
* that function similarly to MatIterator_<T> class. Also, while
* creating the IterableMat, a warning is issued if the type of
* the matrix is not the same as T
*
* A simple way to get an IterableMat<T> from a Mat is to do
* iterate<T>(mat). Thus, an easy range based for loop would look
* like:
*
* for(T elem : iterate<T>(mat)) {...}
*/

template<class Element> class IterableMat : public Mat {
public:
struct Iterator {
Expand Down Expand Up @@ -43,10 +58,28 @@ template<class Element> class IterableMat : public Mat {

template<class Element>
IterableMat<Element> iterate(Mat &x) {
CHECKER_ASSERT(DataType<Element>::type == x.type(), "WARNING: Data type mismatch in iterable, may lead to wrong results\n");
CHECKER_ASSERT(DataType<Element>::type == x.type(),
"WARNING: Data type mismatch in iterable, may lead to wrong results\n");
return IterableMat<Element>(x);
}

/**
* This is another wrapper over MatIterator_ but it also gives the
* (x,y) coordinates of the current loop instance.
* The EnumerableMat<T> class has an EnumerationIterator
* that gives back an Enumeration object upon dereference. The
* Enumeration object has three fields: x, y, T& val, which are
* set according to the current iteration.
*
* A simple way to get an EnumerableMat<T> from a Mat is to do
* enumerate<T>(mat). Thus, an easy range based for loop would look
* like:
*
* for(auto en : enumerate<float>(mat)) {
* printf("%d %d %f", en.x, en.y, en.val);
* }
*/

template<class Element> class EnumerableMat : public Mat {
public:
struct Enumeration {
Expand Down Expand Up @@ -104,7 +137,8 @@ template<class Element> class EnumerableMat : public Mat {

template<class Element>
EnumerableMat<Element> enumerate(Mat &x) {
CHECKER_ASSERT(DataType<Element>::type == x.type(), "WARNING: Data type mismatch in enumerable, may lead to wrong results\n");
CHECKER_ASSERT(DataType<Element>::type == x.type(),
"WARNING: Data type mismatch in enumerable, may lead to wrong results\n");
return EnumerableMat<Element>(x);
}

Expand Down
62 changes: 51 additions & 11 deletions include/transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
using namespace std;
using namespace cv;

/**
* a simple function_traits class to get argument and result types of functions
*/

template <typename T>
struct function_traits
: public function_traits<decltype(&T::operator())>
Expand All @@ -18,21 +22,57 @@ template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
enum { arity = sizeof...(Args) };
// arity is the number of arguments.

typedef ReturnType result_type;
typedef typename std::tuple_element<0, std::tuple<Args...>>::type argument_type;

template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
// the i-th argument is equivalent to the i-th tuple element of a tuple
// composed of those arguments.
};
};


/**
* This is the workhorse of per-pixel transforms and the like
* An IntermediateValue stores the current intermediate Mat in its val
* and can be freely cast to or from a Mat instance
*
* It provides two methods:
* pp_transform(func), which is equivalent to
*
* Mat output = Mat(val.size(), <return type of func>)
* for(each pixel in val) {
* output[pixel] = func(input[pixel]);
* }
* return IntermediateValue(output);
*
* pp_transform can also be called with an explicit output
* type, such as:
* pp_transform(CV_32FC3, func);
*
* One can directly obtain an IntermediateValue by calling
* pp_transform(image, func)
*
* Since a pp_transform returns a IntermediateValue, one can create a chain
* of pp_transforms such as
* pp_transform(image, func).
* pp_transform(func2).
* pp_transform(func3);
*
* Also, another similar method is total_transform, which simply calls
* func on the Mat itself, like:
*
* Mat output = func(val);
* return IntermediateValue(output);
*
* This method is meant to be used for OpenCV implemented transforms such
* as edge detection etc. An example of edge detection on the R-channel of a
* normalized color image is below
*
* Mat output = pp_transform(image, [](Vec3b pixel) { // get normalized R channel
* float sum = pixel[0] + pixel[1] + pixel[2];
* return saturate_cast<uint8_t>(pixel[2]/sum*255);
* }).total_transform([](Mat input) {
* Mat output;
* Canny(input, output, 20, 60);
* return output;
* });
*/
struct IntermediateValue {
Mat val;

Expand Down

0 comments on commit 7e0dbee

Please sign in to comment.