Commit fa2499d8 authored by Davis King's avatar Davis King
Browse files

Added a file that defines a new generic image interface for images in dlib.

This is the dlib/image_processing/generic_image.h file.  Then I changed all the
image processing functions so that they use this interface.  All the changes
are very minor, but there are just a lot of them.

Any user code that was using array2d objects to represent images will still
work.  However, this change makes it so that users can use their own custom
image objects with dlib by simply implementing a few global functions for their
image object.
parent dc0fd24d
// Copyright (C) 2014 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_MATRIX_GENERIC_iMAGE_H__
#define DLIB_MATRIX_GENERIC_iMAGE_H__
#include "matrix.h"
#include "../image_processing/generic_image.h"
namespace dlib
{
template <
typename T,
long NR,
long NC,
typename MM
>
struct image_traits<matrix<T,NR,NC,MM> >
{
typedef T pixel_type;
};
template <
typename T,
long NR,
long NC,
typename MM
>
inline long num_rows( const matrix<T,NR,NC,MM>& img) { return img.nr(); }
template <
typename T,
long NR,
long NC,
typename MM
>
inline long num_columns( const matrix<T,NR,NC,MM>& img) { return img.nc(); }
template <
typename T,
long NR,
long NC,
typename MM
>
inline void set_image_size(
matrix<T,NR,NC,MM>& img,
long rows,
long cols
) { img.set_size(rows,cols); }
template <
typename T,
long NR,
long NC,
typename MM
>
inline void* image_data(
matrix<T,NR,NC,MM>& img
)
{
if (img.size() != 0)
return &img(0,0);
else
return 0;
}
template <
typename T,
long NR,
long NC,
typename MM
>
inline const void* image_data(
const matrix<T,NR,NC,MM>& img
)
{
if (img.size() != 0)
return &img(0,0);
else
return 0;
}
template <
typename T,
long NR,
long NC,
typename MM
>
inline long width_step(
const matrix<T,NR,NC,MM>& img
)
{
return img.nc()*sizeof(T);
}
}
#endif // DLIB_MATRIX_GENERIC_iMAGE_H__
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "matrix_op.h" #include "matrix_op.h"
#include "../array2d.h" #include "../array2d.h"
#include "../array.h" #include "../array.h"
#include "../image_processing/generic_image.h"
namespace dlib namespace dlib
...@@ -28,39 +29,112 @@ namespace dlib ...@@ -28,39 +29,112 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename T> template <typename image_type, typename pixel_type>
struct op_array2d_to_mat : does_not_alias struct op_image_to_mat : does_not_alias
{ {
op_array2d_to_mat( const T& array_) : array(array_){} op_image_to_mat( const image_type& img) : imgview(img){}
const T& array; const_image_view<image_type> imgview;
const static long cost = 1; const static long cost = 1;
const static long NR = 0; const static long NR = 0;
const static long NC = 0; const static long NC = 0;
typedef typename T::type type; typedef pixel_type type;
typedef const typename T::type& const_ret_type; typedef const pixel_type& const_ret_type;
typedef typename T::mem_manager_type mem_manager_type; typedef default_memory_manager mem_manager_type;
typedef row_major_layout layout_type; typedef row_major_layout layout_type;
const_ret_type apply (long r, long c ) const { return array[r][c]; } const_ret_type apply (long r, long c ) const { return imgview[r][c]; }
long nr () const { return array.nr(); } long nr () const { return imgview.nr(); }
long nc () const { return array.nc(); } long nc () const { return imgview.nc(); }
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template < template <
typename T, typename image_type
typename MM > // The reason we disable this if it is a matrix is because this matrix_op claims
> // to not alias any matrix. But obviously that would be a problem if we let it
const matrix_op<op_array2d_to_mat<array2d<T,MM> > > mat ( // take a matrix.
const array2d<T,MM>& array const typename disable_if<is_matrix<image_type>,matrix_op<op_image_to_mat<image_type, typename image_traits<image_type>::pixel_type> > >::type mat (
const image_type& img
) )
{ {
typedef op_array2d_to_mat<array2d<T,MM> > op; typedef op_image_to_mat<image_type, typename image_traits<image_type>::pixel_type> op;
return matrix_op<op>(op(array)); return matrix_op<op>(op(img));
}
// ----------------------------------------------------------------------------------------
template <typename image_type>
struct op_image_view_to_mat : does_not_alias
{
op_image_view_to_mat( const image_view<image_type>& img) : imgview(img){}
typedef typename image_traits<image_type>::pixel_type pixel_type;
const image_view<image_type>& imgview;
const static long cost = 1;
const static long NR = 0;
const static long NC = 0;
typedef pixel_type type;
typedef const pixel_type& const_ret_type;
typedef default_memory_manager mem_manager_type;
typedef row_major_layout layout_type;
const_ret_type apply (long r, long c ) const { return imgview[r][c]; }
long nr () const { return imgview.nr(); }
long nc () const { return imgview.nc(); }
};
template <
typename image_type
>
const matrix_op<op_image_view_to_mat<image_type> > mat (
const image_view<image_type>& img
)
{
typedef op_image_view_to_mat<image_type> op;
return matrix_op<op>(op(img));
}
// ----------------------------------------------------------------------------------------
template <typename image_type>
struct op_const_image_view_to_mat : does_not_alias
{
op_const_image_view_to_mat( const const_image_view<image_type>& img) : imgview(img){}
typedef typename image_traits<image_type>::pixel_type pixel_type;
const const_image_view<image_type>& imgview;
const static long cost = 1;
const static long NR = 0;
const static long NC = 0;
typedef pixel_type type;
typedef const pixel_type& const_ret_type;
typedef default_memory_manager mem_manager_type;
typedef row_major_layout layout_type;
const_ret_type apply (long r, long c ) const { return imgview[r][c]; }
long nr () const { return imgview.nr(); }
long nc () const { return imgview.nc(); }
};
template <
typename image_type
>
const matrix_op<op_const_image_view_to_mat<image_type> > mat (
const const_image_view<image_type>& img
)
{
typedef op_const_image_view_to_mat<image_type> op;
return matrix_op<op>(op(img));
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
...@@ -418,6 +492,42 @@ namespace dlib ...@@ -418,6 +492,42 @@ namespace dlib
return array; return array;
} }
// ----------------------------------------------------------------------------------------
template <typename T>
struct op_array2d_to_mat : does_not_alias
{
op_array2d_to_mat( const T& array_) : array(array_){}
const T& array;
const static long cost = 1;
const static long NR = 0;
const static long NC = 0;
typedef typename T::type type;
typedef const typename T::type& const_ret_type;
typedef typename T::mem_manager_type mem_manager_type;
typedef row_major_layout layout_type;
const_ret_type apply (long r, long c ) const { return array[r][c]; }
long nr () const { return array.nr(); }
long nc () const { return array.nc(); }
};
// Note that we have this version of mat() because it's slightly faster executing
// than the general one that handles any generic image. This is because it avoids
// calling image_data() which for array2d involves a single if statement but this
// version here has no if statement in its construction.
template < typename T, typename MM >
const matrix_op<op_array2d_to_mat<array2d<T,MM> > > mat (
const array2d<T,MM>& array
)
{
typedef op_array2d_to_mat<array2d<T,MM> > op;
return matrix_op<op>(op(array));
}
template < template <
typename array_type typename array_type
> >
......
...@@ -28,14 +28,20 @@ namespace dlib ...@@ -28,14 +28,20 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template < template <
typename T, typename image_type
typename MM
> >
const matrix_exp mat ( const matrix_exp mat (
const array2d<T,MM>& array const image_type& img
); );
/*! /*!
requires
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h or image_type is a image_view or
const_image_view object.
ensures ensures
- This function converts any kind of generic image object into a dlib::matrix
expression. Therefore, it is capable of converting objects like dlib::array2d
of dlib::cv_image.
- returns a matrix R such that: - returns a matrix R such that:
- R.nr() == array.nr() - R.nr() == array.nr()
- R.nc() == array.nc() - R.nc() == array.nc()
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "../algs.h" #include "../algs.h"
#include "../pixel.h" #include "../pixel.h"
#include "../matrix/matrix_mat.h" #include "../matrix/matrix_mat.h"
#include "../image_processing/generic_image.h"
namespace dlib namespace dlib
{ {
...@@ -139,6 +140,51 @@ namespace dlib ...@@ -139,6 +140,51 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// Define the global functions that make cv_image a proper "generic image" according to
// ../image_processing/generic_image.h
template <typename T>
struct image_traits<cv_image<T> >
{
typedef T pixel_type;
};
template <typename T>
inline long num_rows( const cv_image<T>& img) { return img.nr(); }
template <typename T>
inline long num_columns( const cv_image<T>& img) { return img.nc(); }
template <typename T>
inline void* image_data(
cv_image<T>& img
)
{
if (img.size() != 0)
return &img[0][0];
else
return 0;
}
template <typename T>
inline const void* image_data(
const cv_image<T>& img
)
{
if (img.size() != 0)
return &img[0][0];
else
return 0;
}
template <typename T>
inline long width_step(
const cv_image<T>& img
)
{
return img.width_step();
}
// ----------------------------------------------------------------------------------------
} }
#endif // DLIB_CvIMAGE_H_ #endif // DLIB_CvIMAGE_H_
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment