// test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include using namespace std; using namespace boost; using namespace gil; // // The algorithm maps each channel with all its possible values // onto a std::vector . Each index in the vector represents // one value inside the channel's value range [min...max]. Once all // values are counted the algorithm is looking for a smallest index which // satisfies the bottom N% value constrain. // // A weakness of such this algorithm is its assumption of a // continuous value range. // // template< class PIXEL , class VIEW > inline PIXEL min_channel_values_( const VIEW& view , const size_t percent = 1 ) { //only for homogeneous pixel types typedef channel_type::type channel_t; vector channels[ num_channels::type::value ]; for( int i = 0; i < num_channels::type::value; ++i ) { channels[ i ].resize( channel_traits::max_value() ); } vector c_0( channel_traits::max_value() ); for( typename VIEW::iterator it = view.begin(); it != view.end(); ++it ) { PIXEL::const_reference p = *it; for( int i = 0; i < num_channels::type::value; ++i ) { ++channels[ i ][ dynamic_at_c( p, i ) ]; } } // channel vectors are sorted. // bottom N% value size_t N = ( view.width() * view.height() ) / ( 100 * percent ); PIXEL min; for( int i = 0; i < num_channels::type::value; ++i ) { vector::const_iterator it = find_if( channels[i].begin() , channels[i].end() , bind( greater() , _1 , N )); if( it == channels[0].end() ) { throw runtime_error( "no min value found" ); } else { ptrdiff_t dist = distance( static_cast< vector::const_iterator>( channels[i].begin() ) , it ); // get the index of the value dynamic_at_c( min, i ) = static_cast( dist ); } } return min; } int main(int argc, char* argv[]) { { rgb8_image_t dst( 10, 10 ); typedef channel_type::type channel_t; fill_pixels( view( dst ), rgb8_pixel_t( 0,0,0 ) ); min_channel_values_( view( dst )); } return 0; }