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
......@@ -6,6 +6,7 @@
#include "array2d/array2d_kernel.h"
#include "array2d/serialize_pixel_overloads.h"
#include "array2d/array2d_generic_image.h"
#endif // DLIB_ARRAY2d_
// Copyright (C) 2014 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ARRAY2D_GENERIC_iMAGE_H__
#define DLIB_ARRAY2D_GENERIC_iMAGE_H__
#include "array2d_kernel.h"
#include "../image_processing/generic_image.h"
namespace dlib
{
template <typename T, typename mm>
struct image_traits<array2d<T,mm> >
{
typedef T pixel_type;
};
template <typename T, typename mm>
inline long num_rows( const array2d<T,mm>& img) { return img.nr(); }
template <typename T, typename mm>
inline long num_columns( const array2d<T,mm>& img) { return img.nc(); }
template <typename T, typename mm>
inline void set_image_size(
array2d<T,mm>& img,
long rows,
long cols
) { img.set_size(rows,cols); }
template <typename T, typename mm>
inline void* image_data(
array2d<T,mm>& img
)
{
if (img.size() != 0)
return &img[0][0];
else
return 0;
}
template <typename T, typename mm>
inline const void* image_data(
const array2d<T,mm>& img
)
{
if (img.size() != 0)
return &img[0][0];
else
return 0;
}
template <typename T, typename mm>
inline long width_step(
const array2d<T,mm>& img
)
{
return img.width_step();
}
}
#endif // DLIB_ARRAY2D_GENERIC_iMAGE_H__
......@@ -9,6 +9,7 @@
#include <iostream>
#include "../serialize.h"
#include "vector.h"
#include "../image_processing/generic_image.h"
namespace dlib
{
......@@ -645,7 +646,7 @@ namespace dlib
const T& m
)
{
return rectangle(0, 0, m.nc()-1, m.nr()-1);
return rectangle(0, 0, num_columns(m)-1, num_rows(m)-1);
}
// ----------------------------------------------------------------------------------------
......
......@@ -715,9 +715,12 @@ namespace dlib
);
/*!
requires
- T has nr() and nc() functions that return longs
- It must be possible to determine the number of "rows" and "columns" in m.
Either by calling num_rows(m) and num_columns(m) or by calling m.nr() and
m.nc() to obtain the number of rows and columns respectively. Moreover,
these routines should return longs.
ensures
- returns rectangle(0, 0, m.nc()-1, m.nr()-1)
- returns rectangle(0, 0, num_columns(m)-1, num_rows(m)-1)
(i.e. assuming T represents some kind of rectangular grid, such as
the dlib::matrix or dlib::array2d objects, this function returns the
bounding rectangle for that gridded object.)
......
......@@ -3253,12 +3253,12 @@ namespace dlib
// if the new image has a different size when compared to the previous image
// then we should readjust the total rectangle size.
if (new_img.nr() != img.nr() || new_img.nc() != img.nc())
if (num_rows(new_img) != img.nr() || num_columns(new_img) != img.nc())
{
if (zoom_in_scale != 1)
set_total_rect_size(new_img.nc()*zoom_in_scale, new_img.nr()*zoom_in_scale);
set_total_rect_size(num_columns(new_img)*zoom_in_scale, num_rows(new_img)*zoom_in_scale);
else
set_total_rect_size(new_img.nc()/zoom_out_scale, new_img.nr()/zoom_out_scale);
set_total_rect_size(num_columns(new_img)/zoom_out_scale, num_rows(new_img)/zoom_out_scale);
}
else
{
......
......@@ -66,7 +66,7 @@ namespace dlib
const image_type& img
)
{
COMPILE_TIME_ASSERT( pixel_traits<typename image_type::type>::has_alpha == false );
COMPILE_TIME_ASSERT( pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false );
load_impl(mat(img));
}
......
......@@ -103,7 +103,7 @@ namespace dlib
requires
- image_type is a dlib::matrix or something convertible to a matrix
via mat()
- pixel_traits<typename image_type::type>::has_alpha == false
- pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false
ensures
- if (img.nr() < min_size || img.nc() < min_size) then
- the image is too small so we don't compute anything on it
......
......@@ -309,7 +309,7 @@ namespace dlib
// use the inverse frequency as the scale for each feature. We also scale
// these counts so that they are invariant to the size of the image (we scale
// them so they all look like they come from a 500x400 images).
const double scale = img.size()/(500.0*400.0);
const double scale = image_size(img)/(500.0*400.0);
for (unsigned long i = 0; i < feat_counts.size(); ++i)
{
feat_counts[i] = scale/feat_counts[i];
......
......@@ -82,7 +82,7 @@ namespace dlib
const image_type& img
)
{
COMPILE_TIME_ASSERT( pixel_traits<typename image_type::type>::has_alpha == false );
COMPILE_TIME_ASSERT( pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false );
load_impl(mat(img));
}
......
......@@ -158,8 +158,8 @@ namespace dlib
/*!
requires
- image_type is a dlib::matrix or something convertible to a matrix
via mat()
- pixel_traits<typename image_type::type>::has_alpha == false
via mat().
- pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false
ensures
- if (img.nr() < min_size || img.nc() < min_size) then
- the image is too small so we don't compute anything on it
......
......@@ -138,7 +138,7 @@ namespace dlib
const image_type& img
)
{
COMPILE_TIME_ASSERT( pixel_traits<typename image_type::type>::has_alpha == false );
COMPILE_TIME_ASSERT( pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false );
poly_coef.resize(get_num_dimensions());
des.set_size(get_num_dimensions());
......
......@@ -166,8 +166,9 @@ namespace dlib
);
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- pixel_traits<typename image_type::type>::has_alpha == false
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- pixel_traits<typename image_traits<image_type>::pixel_type>::has_alpha == false
ensures
- Performs the feature extraction described in the WHAT THIS OBJECT REPRESENTS
section above. This means after load() finishes you can call (*this)(row,col)
......
......@@ -248,7 +248,7 @@ namespace dlib
);
// Figure out the proper scalar type we should use to work with these pixels.
typedef typename pixel_traits<typename image_type::type>::basic_pixel_type bp_type;
typedef typename pixel_traits<typename image_traits<image_type>::pixel_type>::basic_pixel_type bp_type;
typedef typename promote<bp_type>::type working_pixel_type;
// make an integral image first
......
......@@ -133,8 +133,10 @@ namespace dlib
requires
- max_points > 0
- detection_threshold >= 0
- image_type == a type that implements the array2d/array2d_kernel_abstract.h interface
- pixel_traits<image_type::type> must be defined
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- Let P denote the type of pixel in img, then we require:
- pixel_traits<P>::has_alpha == false
ensures
- This function runs the complete SURF algorithm on the given input image and
returns the points it found.
......
......@@ -31,10 +31,11 @@ namespace dlib
typename image_type
>
void load_bmp (
image_type& image,
image_type& image_,
std::istream& in_
)
{
image_view<image_type> image(image_);
try
{
unsigned long bytes_read_so_far = 0;
......@@ -550,10 +551,11 @@ namespace dlib
typename image_type
>
void load_dng (
image_type& image,
image_type& image_,
std::istream& in
)
{
image_view<image_type> image(image_);
using namespace dng_helpers_namespace;
try
{
......@@ -788,7 +790,7 @@ namespace dlib
// Only use long double precision if the target image contains long
// doubles because it's slower to use those.
if (!is_same_type<typename image_type::type,long double>::value)
if (!is_same_type<typename image_traits<image_type>::pixel_type,long double>::value)
{
double temp = cur;
assign_pixel(image[r][c],temp);
......
......@@ -29,8 +29,8 @@ namespace dlib
);
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- 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
ensures
- #image == the image of the MS Windows BMP file that was available
in the input stream in.
......@@ -61,8 +61,8 @@ namespace dlib
);
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- 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
ensures
- opens the file indicated by file_name with an input file stream named fin
and performs:
......@@ -87,8 +87,8 @@ namespace dlib
);
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- 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
ensures
- #image == the image of the dlib dng file that was available
in the input stream in.
......@@ -119,8 +119,8 @@ namespace dlib
);
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- 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
ensures
- opens the file indicated by file_name with an input file stream named fin
and performs:
......
......@@ -25,7 +25,7 @@ namespace dlib
bool is_rgb() const;
template<typename T>
void get_image( T& t) const
void get_image( T& t_) const
{
#ifndef DLIB_JPEG_SUPPORT
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
......@@ -36,6 +36,7 @@ namespace dlib
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
COMPILE_TIME_ASSERT(sizeof(T) == 0);
#endif
image_view<T> t(t_);
t.set_size( height_, width_ );
for ( unsigned n = 0; n < height_;n++ )
......
......@@ -99,8 +99,8 @@ namespace dlib
) const;
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- 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
ensures
- loads the JPEG image stored in this object into img
!*/
......@@ -118,8 +118,8 @@ namespace dlib
);
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- 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
ensures
- performs: jpeg_loader(file_name).get_image(image);
!*/
......
......@@ -15,8 +15,8 @@ namespace dlib
);
/*!
requires
- image_type == is an implementation of array2d/array2d_kernel_abstract.h
- 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
ensures
- let EXT == the extension of the file given by file_name converted
to lower case (i.e. the part of the file after the '.')
......
......@@ -30,7 +30,7 @@ namespace dlib
unsigned int bit_depth () const { return bit_depth_; }
template<typename T>
void get_image( T& t) const
void get_image( T& t_) const
{
#ifndef DLIB_PNG_SUPPORT
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
......@@ -42,7 +42,8 @@ namespace dlib
COMPILE_TIME_ASSERT(sizeof(T) == 0);
#endif
typedef typename T::type pixel_type;
typedef typename image_traits<T>::pixel_type pixel_type;
image_view<T> t(t_);
t.set_size( height_, width_ );
......@@ -148,7 +149,7 @@ namespace dlib
}
else if (is_rgba() && bit_depth_ == 8)
{
if (!pixel_traits<typename T::type>::has_alpha)
if (!pixel_traits<pixel_type>::has_alpha)
assign_all_pixels(t,0);
for ( unsigned n = 0; n < height_;n++ )
......@@ -167,7 +168,7 @@ namespace dlib
}
else if (is_rgba() && bit_depth_ == 16)
{
if (!pixel_traits<typename T::type>::has_alpha)
if (!pixel_traits<pixel_type>::has_alpha)
assign_all_pixels(t,0);
for ( unsigned n = 0; n < height_;n++ )
......
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