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 @@
#include "matrix_op.h"
#include "../array2d.h"
#include "../array.h"
#include "../image_processing/generic_image.h"
namespace dlib
......@@ -28,39 +29,112 @@ namespace dlib
// ----------------------------------------------------------------------------------------
template <typename T>
struct op_array2d_to_mat : does_not_alias
template <typename image_type, typename pixel_type>
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 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 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 array[r][c]; }
const_ret_type apply (long r, long c ) const { return imgview[r][c]; }
long nr () const { return array.nr(); }
long nc () const { return array.nc(); }
long nr () const { return imgview.nr(); }
long nc () const { return imgview.nc(); }
};
// ----------------------------------------------------------------------------------------
template <
typename T,
typename MM
typename image_type
> // 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
// take a matrix.
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_image_to_mat<image_type, typename image_traits<image_type>::pixel_type> op;
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_array2d_to_mat<array2d<T,MM> > > mat (
const array2d<T,MM>& array
const matrix_op<op_image_view_to_mat<image_type> > mat (
const image_view<image_type>& img
)
{
typedef op_array2d_to_mat<array2d<T,MM> > op;
return matrix_op<op>(op(array));
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
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 <
typename array_type
>
......
......@@ -28,14 +28,20 @@ namespace dlib
// ----------------------------------------------------------------------------------------
template <
typename T,
typename MM
typename image_type
>
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
- 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:
- R.nr() == array.nr()
- R.nc() == array.nc()
......
......@@ -7,6 +7,7 @@
#include "../algs.h"
#include "../pixel.h"
#include "../matrix/matrix_mat.h"
#include "../image_processing/generic_image.h"
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_
......
This diff is collapsed.
......@@ -15,9 +15,10 @@ namespace dlib
);
/*!
requires
- image_type == an implementation of dlib/array2d/array2d_kernel_abstract.h or
a dlib::matrix object which uses a row_major_layout.
- pixel_traits<typename image_type::type> is defined
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h or a dlib::matrix object which uses a
row_major_layout.
- pixel_traits is defined for the contents of img.
ensures
- returns an OpenCV Mat object which represents the same image as img. This
is done by setting up the Mat object to point to the same memory as img.
......
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