pyramid_down<6>

1.frontal_face_detector detector = get_frontal_face_detector();
2.typedef object_detector<scan_fhog_pyramid<pyramid_down<6> > > frontal_face_detector;
3.

class pyramid_down : noncopyable
    {
    public:

        COMPILE_TIME_ASSERT(N > 0);

        template <typename T>
        vector<double,2> point_down (
            const vector<T,2>& p
        ) const
        {
            const double ratio = (N-1.0)/N;
            return (p - 0.3)*ratio;
        }

        template <typename T>
        vector<double,2> point_up (
            const vector<T,2>& p
        ) const
        {
            const double ratio = N/(N-1.0);
            return p*ratio + 0.3;
        }

    // -----------------------------

        template <typename T>
        vector<double,2> point_down (
            const vector<T,2>& p,
            unsigned int levels
        ) const
        {
            vector<double,2> temp = p;
            for (unsigned int i = 0; i < levels; ++i)
                temp = point_down(temp);
            return temp;
        }

        template <typename T>
        vector<double,2> point_up (
            const vector<T,2>& p,
            unsigned int levels
        ) const
        {
            vector<double,2> temp = p;
            for (unsigned int i = 0; i < levels; ++i)
                temp = point_up(temp);
            return temp;
        }

    // -----------------------------

        drectangle rect_up (
            const drectangle& rect
        ) const
        {
            return drectangle(point_up(rect.tl_corner()), point_up(rect.br_corner()));
        }

        drectangle rect_up (
            const drectangle& rect,
            unsigned int levels
        ) const
        {
            return drectangle(point_up(rect.tl_corner(),levels), point_up(rect.br_corner(),levels));
        }

    // -----------------------------

        drectangle rect_down (
            const drectangle& rect
        ) const
        {
            return drectangle(point_down(rect.tl_corner()), point_down(rect.br_corner()));
        }

        drectangle rect_down (
            const drectangle& rect,
            unsigned int levels
        ) const
        {
            return drectangle(point_down(rect.tl_corner(),levels), point_down(rect.br_corner(),levels));
        }

        template <
            typename in_image_type,
            typename out_image_type
            >
        void operator() (
            const in_image_type& original,
            out_image_type& down
        ) const
        {
            // make sure requires clause is not broken
            DLIB_ASSERT(is_same_object(original, down) == false, 
                        "\t void pyramid_down::operator()"
                        << "\n\t is_same_object(original, down): " << is_same_object(original, down) 
                        << "\n\t this:                           " << this
                        );

            typedef typename image_traits<in_image_type>::pixel_type in_pixel_type;
            typedef typename image_traits<out_image_type>::pixel_type out_pixel_type;
            COMPILE_TIME_ASSERT( pixel_traits<in_pixel_type>::has_alpha == false );
            COMPILE_TIME_ASSERT( pixel_traits<out_pixel_type>::has_alpha == false );


            set_image_size(down, ((N-1)*num_rows(original))/N+0.5, ((N-1)*num_columns(original))/N+0.5);
            resize_image(original, down);
        }

        template <
            typename image_type
            >
        void operator() (
            image_type& img
        ) const
        {
            image_type temp;
            (*this)(img, temp);
            swap(temp, img);
        }
    };

    template <>
    class pyramid_down<1> : public pyramid_disable {};

    template <>
    class pyramid_down<2> : public dlib::impl::pyramid_down_2_1 {};

    template <>
    class pyramid_down<3> : public dlib::impl::pyramid_down_3_2 {};

// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------

    template <unsigned int N>
    double pyramid_rate(const pyramid_down<N>&)
    {
        return (N-1.0)/N;
    }

// ----------------------------------------------------------------------------------------

    template <
        typename pyramid_type,
        typename image_type1,
        typename image_type2
        >
    void create_tiled_pyramid (
        const image_type1& img,
        image_type2& out_img,
        std::vector<rectangle>& rects,
        const unsigned long padding = 10,
        const unsigned long outer_padding = 0
    )
    {
        DLIB_ASSERT(!is_same_object(img, out_img));

        rects.clear();
        if (num_rows(img)*num_columns(img) == 0)
        {
            set_image_size(out_img,0,0);
            return;
        }

        const long min_height = 5;
        pyramid_type pyr;
        std::vector<matrix<rgb_pixel>> pyramid;
        matrix<rgb_pixel> temp;
        assign_image(temp, img);
        pyramid.push_back(std::move(temp));
        // build the whole pyramid
        while(true)
        {
            matrix<rgb_pixel> temp;
            pyr(pyramid.back(), temp);
            if (temp.size() == 0 || temp.nr() < min_height)
                break;
            pyramid.push_back(std::move(temp));
        }

        // figure out output image size
        long total_height = 0;
        for (auto&& i : pyramid)
            total_height += i.nr()+padding;
        total_height -= padding*2; // don't add unnecessary padding to the very right side.
        long height = 0;
        long prev_width = 0;
        for (auto&& i : pyramid)
        {
            // Figure out how far we go on the first column.  We go until the next image can
            // fit next to the previous one, which means we can double back for the second
            // column of images.
            if (i.nc() <= img.nc()-prev_width-(long)padding && 
                (height-img.nr())*2 >= (total_height-img.nr()))
            {
                break;
            }
            height += i.nr() + padding;
            prev_width = i.nc();
        }
        height -= padding; // don't add unnecessary padding to the very right side.

        const long width = img.nc();
        set_image_size(out_img,height+outer_padding*2,width+outer_padding*2);
        assign_all_pixels(out_img, 0);

        long y = outer_padding;
        size_t i = 0;
        while(y < height+(long)outer_padding)
        {
            rectangle rect = translate_rect(get_rect(pyramid[i]),point(outer_padding,y));
            DLIB_ASSERT(get_rect(out_img).contains(rect));
            rects.push_back(rect);
            auto si = sub_image(out_img, rect);
            assign_image(si, pyramid[i]);
            y += pyramid[i].nr()+padding;
            ++i;
        }
        y -= padding;
        while (i < pyramid.size())
        {
            point p1(outer_padding+width-1,y-1);
            point p2 = p1 - get_rect(pyramid[i]).br_corner();
            rectangle rect(p1,p2);
            DLIB_ASSERT(get_rect(out_img).contains(rect));
            // don't keep going on the last row if it would intersect the original image.
            if (!get_rect(img).intersect(rect).is_empty())
                break;
            rects.push_back(rect);
            auto si = sub_image(out_img, rect);
            assign_image(si, pyramid[i]);
            y -= pyramid[i].nr()+padding;
            ++i;
        }

    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值