/usr/include/gamera/region.hpp is in python-gamera-dev 1:3.4.2+git20160808.1725654-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | /*
*
* Copyright (C) 2001-2005 Ichiro Fujinaga, Michael Droettboom, and Karl MacMillan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef kwm01262002_region
#define kwm01262002_region
#include "dimensions.hpp"
#include "gamera_limits.hpp"
#include <list>
#include <map>
#include <algorithm>
#include <exception>
#include <string>
#include <iostream>
/*
REGIONS
Regions are designed to be a generic mapping between a region on an image
(as represented by a rectangle) and some values (represented as a key
value pair (string/double)). By convention regions should contain a key
called "scaling" that returns the default value for that region. This is
used in feature functions that are dependant on some relative value (i.e.
the height of glyphs in music recognition is scaled by the size of the
staff space + the size of the staff line).
REGIONMAP
A regionmap is a list of regions with a function to add regions and a
function to lookup regions based on position.
*/
namespace Gamera {
template<class V>
class RegionTemplate : public Rect {
public:
typedef std::map<std::string, V> map_type;
RegionTemplate() :
Rect() { }
RegionTemplate(const Point& ul, const Point& lr) :
Rect(ul, lr) { }
RegionTemplate(const Rect& r) :
Rect(r) { }
RegionTemplate(const Point& ul, const Size& size)
: Rect(ul, size) {}
RegionTemplate(const Point& ul, const Dim& dim)
: Rect(ul, dim) {}
V get(const std::string& key) const {
typename map_type::const_iterator i = m_value_map.find(key);
if (i != m_value_map.end())
return i->second;
else
throw std::invalid_argument("Key does not exist");
}
void add(const std::string& key, V x) {
m_value_map[key] = x;
}
private:
map_type m_value_map;
};
namespace region_detail {
template<class T> struct intersect {
intersect(const T& v) : m_rect(v) {}
inline bool operator()(const T& other) {
return other.contains_rect(m_rect);
}
T m_rect;
};
// check to see if b is aligned vertically with a
template<class T, class U>
inline bool vertically_intersected(const T& a, const U& b) {
if ((b.ul_x() >= a.ul_x() && b.ul_x() <= a.lr_x())
|| (b.lr_x() >= a.ul_x() && b.lr_x() <= a.lr_x()))
return true;
else
return false;
}
// distance from the top of a to the bottom of b
template<class T, class U>
inline int distance_above(const T& a, const U& b) {
// check that b really is above a
if (b.lr_y() >= a.ul_y())
return b.lr_y() - a.ul_y();
else
return -int(a.ul_y() - b.lr_y());
}
// distance from the bottom of a to the top of b
template<class T, class U>
inline int distance_below(const T& a, const U& b) {
// check that b really is below a
if (b.ul_y() <= a.lr_y())
return a.lr_y() - b.ul_y();
else
return -(int)(b.ul_y() - a.lr_y());
}
}
template<class T>
class RegionMapTemplate : public std::list<RegionTemplate<T> > {
public:
using std::list<RegionTemplate<T> >::begin;
using std::list<RegionTemplate<T> >::end;
typedef RegionMapTemplate self;
typedef RegionTemplate<T> region_type;
typedef Rect rect_t;
RegionMapTemplate() : std::list<region_type>(0) { }
virtual ~RegionMapTemplate() { }
void add_region(const region_type& x) {
this->push_back(x);
}
virtual region_type lookup(const rect_t& r) {
typename self::iterator answer =
std::find_if(begin(), end(), region_detail::intersect<rect_t>(r));
if (answer != end())
return *answer;
else {
// if we weren't contained in the rectangle we need to find the closest
// by going straight up and down
typename self::iterator closest = begin();
typename self::iterator i = begin();
int closest_distance = std::numeric_limits<int>::max();
for (; i != end(); ++i) {
if (region_detail::vertically_intersected(r, *i)) {
// get the distance above
int current_distance = region_detail::distance_above(r, *i);
// if we aren't really above, get the distance below. Because we
// know that the rectangles don't intersect, these cases really
// are exclusive
if (current_distance < 0) {
current_distance = region_detail::distance_below(r, *i);
}
if (current_distance < closest_distance)
closest = i;
}
}
return *closest;
}
}
};
}
#endif
|