From 97a7e68f234cc09807d2d55f550e2516be0e9093 Mon Sep 17 00:00:00 2001 From: Francois Fleuret Date: Fri, 28 Sep 2007 08:52:27 +0200 Subject: [PATCH] --- Makefile | 52 + README.txt | 141 +++ array.h | 137 +++ global.cc | 30 + global.h | 54 + gpl-3.0.txt | 674 ++++++++++ integral_array.h | 65 + integral_proba_view.h | 75 ++ misc.cc | 89 ++ misc.h | 39 + normal_law.cc | 37 + normal_law.h | 34 + pom.cc | 317 +++++ pom_solver.cc | 143 +++ pom_solver.h | 75 ++ proba_view.cc | 33 + proba_view.h | 52 + rectangle.cc | 24 + rectangle.h | 25 + rgb_image.cc | 340 ++++++ rgb_image.h | 67 + room.cc | 83 ++ room.h | 57 + test.pom | 2700 +++++++++++++++++++++++++++++++++++++++++ vector.h | 139 +++ 25 files changed, 5482 insertions(+) create mode 100644 Makefile create mode 100644 README.txt create mode 100644 array.h create mode 100644 global.cc create mode 100644 global.h create mode 100644 gpl-3.0.txt create mode 100644 integral_array.h create mode 100644 integral_proba_view.h create mode 100644 misc.cc create mode 100644 misc.h create mode 100644 normal_law.cc create mode 100644 normal_law.h create mode 100644 pom.cc create mode 100644 pom_solver.cc create mode 100644 pom_solver.h create mode 100644 proba_view.cc create mode 100644 proba_view.h create mode 100644 rectangle.cc create mode 100644 rectangle.h create mode 100644 rgb_image.cc create mode 100644 rgb_image.h create mode 100644 room.cc create mode 100644 room.h create mode 100644 test.pom create mode 100644 vector.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4ae6fd4 --- /dev/null +++ b/Makefile @@ -0,0 +1,52 @@ + +#==============================================================================# +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the version 3 of the GNU General Public License # +# as published by the Free Software Foundation. # +# # +# 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, see . # +# # +# Written by Francois Fleuret # +# (C) Ecole Polytechnique Federale de Lausanne # +# Contact for comments & bug reports # +#==============================================================================# + +ifeq ($(STATIC),yes) + LDFLAGS=-static -lm -lpng -lz +else + LDFLAGS=-lm -lpng +endif + +ifeq ($(DEBUG),yes) + OPTIMIZE_FLAG = -g -DDEBUG +else + OPTIMIZE_FLAG = -g -O3 +endif + +ifeq ($(PROFILE),yes) + PROFILE_FLAG = -pg +endif + +CXXFLAGS = -Wall $(OPTIMIZE_FLAG) $(PROFILE_FLAG) + +all: pom + +pom.tgz: + cd .. ; tar zcvf pom/pom.tgz pom/*.cc pom/*.h pom/Makefile pom/images/*.png pom/test.pom pom/*.txt + +pom: pom.o global.o pom_solver.o proba_view.o normal_law.o rectangle.o room.o misc.o rgb_image.o + $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) + +Makefile.depend: *.h *.cc Makefile + $(CC) -M *.cc > Makefile.depend + +clean: + \rm -f pom *.o Makefile.depend + +-include Makefile.depend diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..f8d973f --- /dev/null +++ b/README.txt @@ -0,0 +1,141 @@ + +INTRODUCTION +------------ + + The Probabilistic Occupancy Map is a procedure which estimates the + marginal probabilities of presence of individuals at every location + in an area of interest under a simple appearance model, given binary + images corresponding to the result of a background-subtraction from + different viewpoints. + + The appearance model is parametrized by a family of rectangles which + approximate the silhouettes of individuals standing at every + location of interest, from every point of view. + +INSTALLATION AND TEST +--------------------- + + This program should compile by typing `make' on any standard + GNU/Linux system, as long as the libpng is installed with its header + files. + + To run a simple test on the images provided in the archive just type + + ./pom test.pom + + It will generate several result files in the /tmp directory. + + If the program is not provided with a filename, it will process the + standard input, but will not make any output. + +CONFIGURATION FILE +------------------ + + The configuration file contains the following keywords + + ROOM + + Defines the input image size, the number of cameras and the number + of locations in the area of interest. + + RECTANGLE notvisible| + + Defines the parameters of a certain rectangle, standing for an + individual at a certain location viewed from a certain camera. All + non-specified rectangles are "not visible" by default. + + INPUT_VIEW_FORMAT + + Specifies the filenames of the input images produced by the + background subtraction. The immobile parts should be black (0, 0, + 0) and the moving ones white (255, 255, 255). See FILENAME FORMAT + below. + + RESULT_VIEW_FORMAT + + Specifies the filenames of the result images. See FILENAME FORMAT + below. + + RESULT_FORMAT + + Specifies the filenames of the result probability files, which + contains one marginal probability per line, hence as many lines as + there are locations of interest. See FILENAME FORMAT below. + + CONVERGENCE_VIEW_FORMAT + + Specifies the filenames of the images for individual iteration + during the convergence of the algorithm. Use with care, since tens + of images will be produced for every single frame. See FILENAME + FORMAT below. + + PRIOR + + Sets the prior probability of presence (common to all + locations). Default is 0.01. + + SIGMA_IMAGE_DENSITY + + Sets the variance of the distance between the image produced by + the background subtraction and the ideal synthetic image. Default + is 0.01. + + MAX_NB_SOLVER_ITERATIONS + + Sets a bound on the number of iterations. Default is 100. + + PROBA_IGNORED + + Sets the probability of absence ignored by the solver to speed up + the convergence (use with care, it can produce false + positive). Default is 1.0 + + The file test.pom provided in the archive gives an example. Lines + starting with "#" are ignored. + +FILENAME FORMAT +--------------- + + Every filename format in the configuration file is a string with the + following three "conversion specifications": + + %c camera number + + %f frame number + + %i iteration number + + Some of these fields may be meaningless, depending with the + context. For instance the iteration number is defined only for + CONVERGENCE_VIEW_FORMAT. + +REFERENCES +---------- + + For more information about the POM algorithm, please check the + section V and appendix A of: + + François Fleuret, Jérôme Berclaz, Richard Lengagne and Pascal Fua, + "Multi-Camera People Tracking with a Probabilistic Occupancy Map", + IEEE Transactions on Pattern Analysis and Machine Intelligence + (TPAMI), 2007, to be published. + + This distributed version of the software is slightly slower than the + one described in the article, for which many values such as the + image size were hard-coded in the source to let the compiler + optimize the code. + +LICENSE +------- + + This source code is available under the terms of the version 3 of + the GNU General Public License as published by the Free Software + Foundation. In short: If you distribute a software that uses POM, + you have to distribute it under GPL version 3, hence with the source + code. Another option is to contact us to purchase a commercial + license. + +CONTACT +------- + + Please mail pom@epfl.ch for bug reports, comments and questions. diff --git a/array.h b/array.h new file mode 100644 index 0000000..f921516 --- /dev/null +++ b/array.h @@ -0,0 +1,137 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include +#include + +using namespace std; + +#include "misc.h" + +template +class Array { +public: + int width, height; + // [i][j] is faster on i386 CPU than [i + j * width] + T *content; + T **heads; + + inline void resize(int w, int h) { + delete[] content; + delete[] heads; + width = w; height = h; + content = new T[width * height]; + heads = new T *[width]; + for(int i = 0; i < width; i++) heads[i] = content + i * height; + } + + inline int get_width() const { return width; } + inline int get_height() const { return height; } + + inline Array() : width(0), height(0), content(0), heads(0) { } + + inline Array(int w, int h) : width(w), height(h) { + content = new T[width * height]; + heads = new T *[width]; + for(int i = 0; i < width; i++) heads[i] = content + i * height; + } + + inline Array(const Array &a) : width(a.width), height(a.height) { + content = new T[width * height]; + heads = new T *[width]; + for(int i = 0; i < width; i++) heads[i] = content + i * height; + memcpy(content, a.content, height * width * sizeof(T)); + } + + inline ~Array() { delete[] content; delete[] heads; } + + inline Array &operator = (const Array &a) { + if(this != &a) { + if(a.width != width || a.height != height) resize(a.width, a.height); + if(width > 0 && height > 0) memcpy(content, a.content, height * width * sizeof(T)); + } + return *this; + } + + inline Array& clear() { + memset(content, 0, height * width * sizeof(T)); + return *this; + } + + inline T dot(const Array &a) { + ASSERT(width == a.width && height == a.height, "Size mismatch in Array::dot"); + T *u1 = content, *u2 = a.content; + T s = 0; + for(int i = 0; i < width * height; i++) s += *(u1++) * *(u2++); + return s; + } + + inline T sum_square() { + T *u = content; + T s = 0; + for(int i = 0; i < width * height; i++) { s += *u * *u; u++; } + return s; + } + + inline T sum() { + T *u = content; + T s = 0; + for(int i = 0; i < width * height; i++) s += *(u++); + return s; + } + + inline T &operator () (int i, int j) { + ASSERT(i >= 0 && i < width && j >= 0 && j < height, "Index out of bounds in Array::operator ()"); + return heads[i][j]; + } + + inline T operator () (int i, int j) const { + ASSERT(i >= 0 && i < width && j >= 0 && j < height, "Index out of bounds in Array::operator () const"); + return heads[i][j]; + } + + inline void print(std::ostream &os) const { + for(int i = 0; i < width; i++) for(int j = 0; j < height; j++) + os << heads[i][j] << ((i < width-1) ? ' ' : '\n'); + } + + inline void print_for_gnuplot(std::ostream &os) const { + for(int i = 0; i < width; i++) { + for(int j = 0; j < height; j++) + os << i << " " << j << " " << heads[i][j] << "\n"; + os << "\n"; + } + } + + inline T l2distance(const Array &m) { + ASSERT(m.width == width && m.height == height, "Array size mismatch"); + T r = 0; + for(int i = 0; i < width * height; i++) r += (m.content[i] - content[i]) * (m.content[i] - content[i]); + return r; + } +}; + +template +std::ostream &operator << (std::ostream &os, const Array &v) { v.print(os); return os; } + +#endif diff --git a/global.cc b/global.cc new file mode 100644 index 0000000..db2866e --- /dev/null +++ b/global.cc @@ -0,0 +1,30 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include "global.h" + +scalar_t global_prior = 0.01; +scalar_t global_mu_image_density = 0.0; +scalar_t global_sigma_image_density = 0.01; +scalar_t global_smoothing_coefficient = 0.8; +int global_max_nb_solver_iterations = 100; +scalar_t global_error_max = 1e-4; +int global_nb_stable_error_for_convergence = 5; +scalar_t global_proba_ignored = 1.00; + diff --git a/global.h b/global.h new file mode 100644 index 0000000..342380b --- /dev/null +++ b/global.h @@ -0,0 +1,54 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef GLOBAL_H +#define GLOBAL_H + +#include "misc.h" + +// We used the same prior at every location, but POMSolver::solve +// takes as parameter a vector of priors if you want +extern scalar_t global_prior; + +// The parameters of the Normal law for the conditional image density, +// given the true state. Mu does not appear in the paper, sigma does. +extern scalar_t global_mu_image_density; +extern scalar_t global_sigma_image_density; + +// When we iterate the solver, we smooth the estimate to prevent from +// oscillating effects that tend to appear naturally +extern scalar_t global_smoothing_coefficient; + +// Ugly parameters for defining the convergence of the solver. I guess +// there are far better ways to do + +// Hard bound on the number of iterations +extern int global_max_nb_solver_iterations; + +// What error is considered acceptable +extern scalar_t global_error_max; + +// How many steps under the global_error_max defines convergence +extern int global_nb_stable_error_for_convergence; + +// If the probability of absence is greated than that, ignore the +// avatar in the computation of the average image to save computation +extern scalar_t global_proba_ignored; + +#endif diff --git a/gpl-3.0.txt b/gpl-3.0.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/gpl-3.0.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/integral_array.h b/integral_array.h new file mode 100644 index 0000000..e84141b --- /dev/null +++ b/integral_array.h @@ -0,0 +1,65 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef INTEGRAL_ARRAY_H +#define INTEGRAL_ARRAY_H + +#include + +using namespace std; + +#include "array.h" + +template +class IntegralArray: public Array { +public: + + void compute(const Array *m) { + T *v = Array::content, *w = m->Array::content; + for(int x = 0; x < Array::height; x++) *(v++) = 0; + + register T sl; + for(int y = 1; y < Array::width; y++) { + sl = 0; *(v++) = 0; + for(int x = 0; x < Array::height - 1; x++) { + sl += *(w++); + *(v++) = sl + *(v - Array::height); + } + } + } + + IntegralArray(int w, int h) : Array(w+1, h+1) { } + + IntegralArray(const Array &m) : Array(m->get_width() + 1, m->get_height() + 1) { + compute(m); + } + + // Integral on xmin <= x < xmax, ymin <= y < ymax + // Thus, xmax and ymax can go up to m->width+1 and m->height+1 respectively + + inline T integral(int xmin, int ymin, int xmax, int ymax) const { + ASSERT(xmin <= xmax && ymin <= ymax, "Inconsistent bounds for integral"); + ASSERT(xmin >= 0 && xmax < Array::width && + ymin >= 0 && ymax < Array::height, "Index out of bounds in Array::operator () const"); + return Array::heads[xmax][ymax] + Array::heads[xmin][ymin] + - Array::heads[xmax][ymin] - Array::heads[xmin][ymax]; + } +}; + +#endif diff --git a/integral_proba_view.h b/integral_proba_view.h new file mode 100644 index 0000000..ff164b0 --- /dev/null +++ b/integral_proba_view.h @@ -0,0 +1,75 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef INTEGRAL_PROBA_VIEW_H +#define INTEGRAL_PROBA_VIEW_H + +#include "proba_view.h" +#include "integral_array.h" + +class IntegralProbaView : public IntegralArray { +public: + IntegralProbaView(int view_width, int view_height) : IntegralArray(view_width, view_height) {}; + + // Computes the integral image and returns the sum of all the + // original image pixels + + inline scalar_t compute_sum(const ProbaView *m) { + scalar_t *p = content, *pm = m->content; + for(int x = 0; x < height; x++) *(p++) = 0; + + register scalar_t st = 0; + register scalar_t sl; + for(register int y = 1; y < width; y++) { + sl = 0; *(p++) = sl; + for(register int x = 0; x < height - 1; x++) { + sl += *(pm++); + *p = sl + *(p - height); + p++; + } + st += sl; + } + + return st; + } + + // Computes the integral image and returns the sum of (2m-1)*b + + inline scalar_t compute_sum(const ProbaView *m, const ProbaView *b) { + scalar_t *p = content, *pm = m->content, *pb = b->content; + + for(int x = 0; x < height; x++) *(p++) = 0; + + scalar_t st = 0; + register scalar_t sl; + for(int y = 1; y < width; y++) { + sl = 0; *(p++) = 0; + for(int x = 0; x < height - 1; x++) { + st -= *pb; + sl += *(pm++) * *(pb++); + *p = sl + *(p - height); + p++; + } + st += 2 * sl; + } + + return st; + } +}; +#endif diff --git a/misc.cc b/misc.cc new file mode 100644 index 0000000..adaf6ed --- /dev/null +++ b/misc.cc @@ -0,0 +1,89 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +using namespace std; + +#include "misc.h" + +char *next_word(char *buffer, char *r, int buffer_size) { + char *s; + s = buffer; + if(r != 0) { + while((*r == ' ') || (*r == '\t') || (*r == ',')) r++; + if(*r == '"') { + r++; + while((*r != '"') && (*r != '\0') && + (s. // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef MISC_H +#define MISC_H + +#ifdef DEBUG +#define ASSERT(x, s) if(!(x)) { std::cerr << "ASSERT FAILED IN " << __FILE__ << ":" << __LINE__ << " [" << (s) << "]\n"; abort(); } +#else +#define ASSERT(x, s) +#endif + +typedef double scalar_t; + +template T sq(T x) { return x*x; } + +const int buffer_size = 1024; + +char *next_word(char *buffer, char *r, int buffer_size); + +int pomsprintf(char *buffer, int buffer_length, char *format, int n_camera, int n_frame, int n_iteration); + +#endif diff --git a/normal_law.cc b/normal_law.cc new file mode 100644 index 0000000..02278d8 --- /dev/null +++ b/normal_law.cc @@ -0,0 +1,37 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include "normal_law.h" +#include + +NormalLaw::~NormalLaw() { } + +scalar_t NormalLaw::log_proba(scalar_t x) { + return normalizer - sq(x - expectation)/(2*variance); +} + +scalar_t NormalLaw::proba(scalar_t x) { + return exp(normalizer - sq(x - expectation)/(2*variance)); +} + +void NormalLaw::set(scalar_t e, scalar_t v) { + expectation = e; + variance = v; + normalizer = - 0.5 * log(variance * 2 * M_PI); +} diff --git a/normal_law.h b/normal_law.h new file mode 100644 index 0000000..6f36965 --- /dev/null +++ b/normal_law.h @@ -0,0 +1,34 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef NORMAL_LAW_H +#define NORMAL_LAW_H + +#include "misc.h" + +class NormalLaw { +public: + ~NormalLaw(); + scalar_t expectation, variance, normalizer; + scalar_t log_proba(scalar_t x); + scalar_t proba(scalar_t x); + void set(scalar_t e, scalar_t v); +}; + +#endif diff --git a/pom.cc b/pom.cc new file mode 100644 index 0000000..20498fe --- /dev/null +++ b/pom.cc @@ -0,0 +1,317 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +using namespace std; + +#include "misc.h" +#include "global.h" +#include "vector.h" +#include "room.h" +#include "pom_solver.h" + +void check_parameter(char *s, int line_number, char *buffer) { + if(!s) { + cerr << "Missing parameter line " << line_number << ":" << endl; + cerr << buffer << endl; + exit(1); + } +} + +int main(int argc, char **argv) { + + if(argc > 2) { + cerr << argv[0] << " [-h | --help | ]" << endl; + exit(1); + } + + ifstream *configuration_file = 0; + istream *input_stream; + + if(argc > 1) { + if(strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { + cout << argv[0] << " [-h | --help | ]" << endl + << endl + << " If a configuration file name is provided, the programs processes it" << endl + << " and prints information about the files it generates. Otherwise, it" << endl + << " reads the standard input and does not produce any output unless an" << endl + << " error occurs." << endl + << endl; + exit(0); + } + configuration_file = new ifstream(argv[1]); + if(configuration_file->fail()) { + cerr << "Can not open " << argv[1] << " for reading." << endl; + exit(1); + } + input_stream = configuration_file; + } else input_stream = &cin; + + char input_view_format[buffer_size] = ""; + char result_format[buffer_size] = ""; + char result_view_format[buffer_size] = ""; + char convergence_view_format[buffer_size] = ""; + + char buffer[buffer_size], token[buffer_size]; + + int line_number = 0; + Vector *proba_views = 0; + + Room *room = 0; + + while(!input_stream->eof()) { + + input_stream->getline(buffer, buffer_size); + line_number++; + + char *s = buffer; + s = next_word(token, s, buffer_size); + + if(strcmp(token, "ROOM") == 0) { + int view_width = -1, view_height = -1; + int nb_positions = -1; + int nb_cameras = -1; + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + view_width = atoi(token); + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + view_height = atoi(token); + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + nb_cameras = atoi(token); + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + nb_positions = atoi(token); + + if(room) { + cerr << "Room already defined, line" << line_number << "." << endl; + exit(1); + } + + room = new Room(view_width, view_height, nb_cameras, nb_positions); + proba_views = new Vector(nb_cameras); + for(int c = 0; c < proba_views->length(); c++) + (*proba_views)[c] = new ProbaView(view_width, view_height); + } + + else if(strcmp(token, "CONVERGENCE_VIEW_FORMAT") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(convergence_view_format, s, buffer_size); + } + + else if(strcmp(token, "INPUT_VIEW_FORMAT") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(input_view_format, s, buffer_size); + } + + else if(strcmp(token, "RESULT_VIEW_FORMAT") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(result_view_format, s, buffer_size); + } + + else if(strcmp(token, "RESULT_FORMAT") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(result_format, s, buffer_size); + } + + else if(strcmp(token, "PROCESS") == 0) { + RGBImage tmp; + int first_frame, nb_frames; + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + first_frame = atoi(token); + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + nb_frames = atoi(token); + + POMSolver solver(room); + + Vector prior(room->nb_positions()); + Vector proba_presence(room->nb_positions()); + for(int i = 0; i < room->nb_positions(); i++) prior[i] = global_prior; + + if(strcmp(input_view_format, "") == 0) { + cerr << "You must specify the input view format." << endl; + exit(1); + } + + for(int f = first_frame; f < first_frame + nb_frames; f++) { + + if(configuration_file) + cout << "Processing frame " << f << endl; + + for(int c = 0; c < room->nb_cameras(); c++) { + pomsprintf(buffer, buffer_size, input_view_format, c, f, 0); + tmp.read_png(buffer); + (*proba_views)[c]->from_image(&tmp); + } + + if(strcmp(convergence_view_format, "") != 0) + solver.solve(room, &prior, proba_views, &proba_presence, f, convergence_view_format); + else + solver.solve(room, &prior, proba_views, &proba_presence, f, 0); + + if(strcmp(result_view_format, "") != 0) + for(int c = 0; c < room->nb_cameras(); c++) { + pomsprintf(buffer, buffer_size, result_view_format, c, f, 0); + if(configuration_file) + cout << "Saving " << buffer << endl; + room->save_stochastic_view(buffer, c, (*proba_views)[c], &proba_presence); + } + + if(strcmp(result_format, "") != 0) { + pomsprintf(buffer, buffer_size, result_format, 0, f, 0); + ofstream result(buffer); + if(result.fail()) { + cerr << "Can not open " << token << " for writing." << endl; + exit(1); + } + if(configuration_file) + cout << "Saving " << buffer << endl; + for(int i = 0; i < room->nb_positions(); i++) + result << i << " " << proba_presence[i] << endl; + result.flush(); + } + } + } + + else if(strcmp(token, "RECTANGLE") == 0) { + int n_camera, n_position; + + if(!room) { + cerr << "You must define a room before adding rectangles, line" << line_number << "." << endl; + exit(1); + } + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + n_camera = atoi(token); + + if(n_camera < 0 || n_camera >= room->nb_cameras()) { + cerr << "Out of range camera number line " << line_number << "." << endl; + exit(1); + } + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + n_position = atoi(token); + + if(n_position < 0 || n_camera >= room->nb_positions()) { + cerr << "Out of range position number line " << line_number << "." << endl; + exit(1); + } + + Rectangle *current = room->avatar(n_camera, n_position); + + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + if(strcmp(token, "notvisible") == 0) { + current->visible = false; + current->xmin = -1; + current->ymin = -1; + current->xmax = -1; + current->ymax = -1; + } else { + current->visible = true; + current->xmin = atoi(token); + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + current->ymin = atoi(token); + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + current->xmax = atoi(token); + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + current->ymax = atoi(token); + + if(current->xmin < 0 || current->xmax >= room->view_width() || + current->ymin < 0 || current->ymax >= room->view_height()) { + cerr << "Rectangle out of bounds, line " << line_number << endl; + exit(1); + } + } + } + + else if(strcmp(token, "PRIOR") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + global_prior = atof(token); + } + + else if(strcmp(token, "SIGMA_IMAGE_DENSITY") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + global_sigma_image_density = atof(token); + } + + else if(strcmp(token, "SMOOTHING_COEFFICIENT") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + global_smoothing_coefficient = atof(token); + } + + else if(strcmp(token, "MAX_NB_SOLVER_ITERATIONS") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + global_max_nb_solver_iterations = atoi(token); + } + + else if(strcmp(token, "ERROR_MAX") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + global_error_max = atof(token); + } + + else if(strcmp(token, "NB_STABLE_ERROR_FOR_CONVERGENCE") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + global_nb_stable_error_for_convergence = atoi(token); + } + + else if(strcmp(token, "PROBA_IGNORED") == 0) { + check_parameter(s, line_number, buffer); + s = next_word(token, s, buffer_size); + global_proba_ignored = atof(token); + } + + else if(strcmp(buffer, "") == 0 || buffer[0] == '#') { } + + else { + cerr << "Unknown token " << token << "."; + exit(1); + } + } + + if(proba_views) + for(int c = 0; c < proba_views->length(); c++) delete (*proba_views)[c]; + + delete proba_views; + delete room; + + delete configuration_file; +} diff --git a/pom_solver.cc b/pom_solver.cc new file mode 100644 index 0000000..76cc9a5 --- /dev/null +++ b/pom_solver.cc @@ -0,0 +1,143 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +using namespace std; + +#include "pom_solver.h" +#include "global.h" + +////////////////////////////////////////////////////////////////////// + +POMSolver::POMSolver(Room *room) : neg(room->view_width(), room->view_height()), + neg_view(room->view_width(), room->view_height()), + ii_neg(room->view_width(), room->view_height()), + ii_neg_view(room->view_width(), room->view_height()) { + global_difference.set(global_mu_image_density, global_sigma_image_density); +} + +////////////////////////////////////////////////////////////////////// + +void POMSolver::compute_average_images(int camera, + Room *room, + Vector *proba_absence) { + neg.fill(1.0); + + for(int n = 0; n < room->nb_positions(); n++) if((*proba_absence)[n] <= global_proba_ignored) { + Rectangle *r = room->avatar(camera, n); + if(r->visible) + neg.multiply_subarray(r->xmin, r->ymin, r->xmax + 1, r->ymax + 1, (*proba_absence)[n]); + } +} + +////////////////////////////////////////////////////////////////////// + +void POMSolver::add_log_ratio(int camera, + Room *room, + ProbaView *view, + Vector *proba_absence, + Vector *sum) { + + // Computes the average on the complete picture + + compute_average_images(camera, room, proba_absence); + + double s = ii_neg.compute_sum(&neg); + double sv = ii_neg_view.compute_sum(&neg, view); + + scalar_t noise_proba = 0.01; // 1% of the scene can remain unexplained + scalar_t average_surface = room->view_width() * room->view_height() * (1 + noise_proba) - s; + scalar_t average_diff = average_surface + sv; + + // Cycles throw all positions and adds the log likelihood ratio to + // the total sum for each + + for(int i = 0; i < room->nb_positions(); i++) { + Rectangle *r = room->avatar(camera, i); + if(r->visible) { + scalar_t lambda = 1 - 1/(*proba_absence)[i]; + + scalar_t integral_neg = ii_neg.integral(r->xmin, r->ymin, r->xmax + 1, r->ymax + 1); + scalar_t average_surface_givpre = average_surface + integral_neg; + scalar_t average_surface_givabs = average_surface + lambda * integral_neg; + + scalar_t integral_neg_view = ii_neg_view.integral(r->xmin, r->ymin, r->xmax + 1, r->ymax + 1); + scalar_t average_diff_givpre = average_diff + integral_neg - 2 * integral_neg_view; + scalar_t average_diff_givabs = average_diff + lambda * (integral_neg - 2 * integral_neg_view); + + scalar_t log_mu0 = global_difference.log_proba(average_diff_givabs / average_surface_givabs); + scalar_t log_mu1 = global_difference.log_proba(average_diff_givpre / average_surface_givpre); + + (*sum)[i] += log_mu1 - log_mu0; + + } + } +} + +void POMSolver::solve(Room *room, + Vector *prior, + Vector *views, + Vector *proba_presence, + int nb_frame, + char *convergence_file_format) { + + Vector log_prior_ratio(prior->length()); + + Vector sum(room->nb_positions()); + Vector proba_absence(room->nb_positions()); + + for(int i = 0; i < room->nb_positions(); i++) { + log_prior_ratio[i] = log((*prior)[i]/(1 - (*prior)[i])); + proba_absence[i] = 1 - (*prior)[i]; + } + + int nb_stab = 0; + + for(int it = 0; (nb_stab < global_nb_stable_error_for_convergence) && (it < global_max_nb_solver_iterations); it++) { + + sum.clear(); + for(int c = 0; c < room->nb_cameras(); c++) + add_log_ratio(c, room, (*views)[c], &proba_absence, &sum); + + scalar_t e = 0; + for(int i = 0; i < room->nb_positions(); i++) { + scalar_t np = global_smoothing_coefficient * proba_absence[i] + (1 - global_smoothing_coefficient) / (1 + exp(log_prior_ratio[i] + sum[i])); + if(abs(proba_absence[i] - np) > e) e = abs(proba_absence[i] - np); + proba_absence[i] = np; + } + + if(e < global_error_max) nb_stab++; else nb_stab = 0; + + if(convergence_file_format) { + char buffer[buffer_size]; + for(int p = 0; p < room->nb_positions(); p++) (*proba_presence)[p] = 1 - proba_absence[p]; + for(int c = 0; c < room->nb_cameras(); c++) { + pomsprintf(buffer, buffer_size, convergence_file_format, c, nb_frame, it); + cout << "Saving " << buffer << "\n"; cout.flush(); + room->save_stochastic_view(buffer, c, (*views)[c], proba_presence); + } + } + + } + + for(int p = 0; p < room->nb_positions(); p++) (*proba_presence)[p] = 1 - proba_absence[p]; +} diff --git a/pom_solver.h b/pom_solver.h new file mode 100644 index 0000000..b0624b4 --- /dev/null +++ b/pom_solver.h @@ -0,0 +1,75 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef POM_SOLVER_H +#define POM_SOLVER_H + +#include "misc.h" +#include "integral_proba_view.h" +#include "normal_law.h" +#include "room.h" + +class POMSolver { + + // At each pixel the proba for the pixel to be off + + ProbaView neg; + + // At each pixel, 0 if the view is 0, and the proba for the pixel to + // be off if the view is 1 (or, more mathematically: neg * view) + + ProbaView neg_view; + + // Integral images to speed-up computation + + IntegralProbaView ii_neg, ii_neg_view; + + // Distribution of surface_difference / surface_synthetic + + NormalLaw global_difference; + + void compute_average_images(int camera, + Room *room, + Vector *proba_absence); + + // Adds to every sum[i] the value log(P(X_i = 1 | V_camera) / P(X_i + // = 0 | V_camera)), given the other P(X_j = 1 | V) + + void add_log_ratio(int camera, + Room *room, + ProbaView *view, + Vector *proba_absence, + Vector *sum); + +public: + + POMSolver(Room *room); + + // Uses the computation above for the various cameras and the prior + // to refresh proba_absence. Iterates as many times as specified. + + void solve(Room *room, + Vector *prior, + Vector *views, + Vector *proba_presence, + int nb_frame, + char *convergence_file_format); +}; + +#endif diff --git a/proba_view.cc b/proba_view.cc new file mode 100644 index 0000000..3bf3faf --- /dev/null +++ b/proba_view.cc @@ -0,0 +1,33 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include "proba_view.h" + +ProbaView::ProbaView(int view_width, int view_height) : Array(view_width, view_height) { } + +void ProbaView::from_image(const RGBImage *image) { + ASSERT(image->width() == width && image->height() == height, + "Image size missmatch"); + int k = 0; + for(int x = 0; x < width; x++) for(int y = 0; y < height; y++) { + content[k++] = scalar_t(image->pixel(x, y, 0) + + image->pixel(x, y, 1) + + image->pixel(x, y, 2))/(3 * 255); + } +} diff --git a/proba_view.h b/proba_view.h new file mode 100644 index 0000000..1433043 --- /dev/null +++ b/proba_view.h @@ -0,0 +1,52 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef PROBA_VIEW_H +#define PROBA_VIEW_H + +#include "misc.h" +#include "array.h" +#include "rgb_image.h" + +class ProbaView : public Array { +public: + ProbaView(int view_width, int view_height); + + void from_image(const RGBImage *picture); + + inline void fill(const scalar_t &t) { + register scalar_t *s = content; + register int i = 0; + for(i = 0; i < width * height - 7; i += 8) { + *(s++) = t; *(s++) = t; *(s++) = t; *(s++) = t; + *(s++) = t; *(s++) = t; *(s++) = t; *(s++) = t; + } + for(; i < width * height; i++) *(s++) = t; + } + + inline void multiply_subarray(int xmin, int ymin, int xmax, int ymax, scalar_t k) { + register scalar_t *s = content + xmin * height + ymin; + for(register int x = 0; x < xmax - xmin; x++) { + for(register int y = 0; y < ymax - ymin; y++) *(s++) *= k; + s += height - ymax + ymin; + } + } +}; + +#endif diff --git a/rectangle.cc b/rectangle.cc new file mode 100644 index 0000000..82739b3 --- /dev/null +++ b/rectangle.cc @@ -0,0 +1,24 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include "rectangle.h" + +Rectangle::Rectangle() { + visible = false; +} diff --git a/rectangle.h b/rectangle.h new file mode 100644 index 0000000..6ac5f0c --- /dev/null +++ b/rectangle.h @@ -0,0 +1,25 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +class Rectangle { +public: + bool visible; + int xmin, ymin, xmax, ymax; + Rectangle(); +}; diff --git a/rgb_image.cc b/rgb_image.cc new file mode 100644 index 0000000..26d4e3c --- /dev/null +++ b/rgb_image.cc @@ -0,0 +1,340 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +using namespace std; + +#include + +#include "rgb_image.h" + +void RGBImage::allocate() { + _bit_plans = new unsigned char **[RGB_DEPTH]; + _bit_lines = new unsigned char *[RGB_DEPTH * _height]; + _bit_map = new unsigned char [_width * _height * RGB_DEPTH]; + for(int k = 0; k < RGB_DEPTH; k++) _bit_plans[k] = _bit_lines + k * _height; + for(int k = 0; k < RGB_DEPTH * _height; k++) _bit_lines[k] = _bit_map + k * _width; +} + +void RGBImage::deallocate() { + delete[] _bit_plans; + delete[] _bit_lines; + delete[] _bit_map; +} + +RGBImage::RGBImage() : _bit_plans(0), _bit_lines(0), _bit_map(0) { } + +RGBImage::RGBImage(int width, int height) : _width(width), _height(height) { + allocate(); + memset(_bit_map, 0, _width * _height * RGB_DEPTH * sizeof(unsigned char)); +} + +RGBImage::~RGBImage() { + deallocate(); +} + +void RGBImage::write_ppm(const char *filename) { + FILE *outfile; + + if ((outfile = fopen (filename, "wb")) == 0) { + fprintf (stderr, "Can't open %s for reading\n", filename); + exit(1); + } + + fprintf(outfile, "P6\n%d %d\n255\n", _width, _height); + + char *raw = new char[_width * _height * 3]; + + int k = 0; + for(int y = 0; y < _height; y++) for(int x = 0; x < _width; x++) { + raw[k++] = _bit_map[x + _width * (y + _height * RED)]; + raw[k++] = _bit_map[x + _width * (y + _height * GREEN)]; + raw[k++] = _bit_map[x + _width * (y + _height * BLUE)]; + } + + fwrite((void *) raw, sizeof(unsigned char), _width * _height * 3, outfile); + fclose(outfile); + + delete[] raw; +} + +void RGBImage::read_ppm(const char *filename) { + const int buffer_size = 1024; + FILE *infile; + char buffer[buffer_size]; + int max; + + deallocate(); + + if((infile = fopen (filename, "r")) == 0) { + fprintf (stderr, "Can't open %s for reading\n", filename); + exit(1); + } + + fgets(buffer, buffer_size, infile); + + if(strncmp(buffer, "P6", 2) == 0) { + + do { + fgets(buffer, buffer_size, infile); + } while((buffer[0] < '0') || (buffer[0] > '9')); + sscanf(buffer, "%d %d", &_width, &_height); + fgets(buffer, buffer_size, infile); + sscanf(buffer, "%d", &max); + + allocate(); + + unsigned char *raw = new unsigned char[_width * _height * RGB_DEPTH]; + fread(raw, sizeof(unsigned char), _width * _height * RGB_DEPTH, infile); + + int k = 0; + for(int y = 0; y < _height; y++) for(int x = 0; x < _width; x++) { + _bit_plans[RED][y][x] = raw[k++]; + _bit_plans[GREEN][y][x] = raw[k++]; + _bit_plans[BLUE][y][x] = raw[k++]; + } + + delete[] raw; + + } else if(strncmp(buffer, "P5", 2) == 0) { + + do { + fgets(buffer, buffer_size, infile); + } while((buffer[0] < '0') || (buffer[0] > '9')); + sscanf(buffer, "%d %d", &_width, &_height); + fgets(buffer, buffer_size, infile); + sscanf(buffer, "%d", &max); + + allocate(); + + unsigned char *pixbuf = new unsigned char[_width * _height]; + fread(buffer, sizeof(unsigned char), _width * _height, infile); + + int k = 0, l = 0; + for(int y = 0; y < _height; y++) for(int x = 0; x < _width; x++) { + unsigned char c = pixbuf[k++]; + _bit_map[l++] = c; + _bit_map[l++] = c; + _bit_map[l++] = c; + } + + delete[] pixbuf; + + } else { + cerr << "Can not read ppm of type [" << buffer << "] from " << filename << ".\n"; + exit(1); + } +} + +void RGBImage::read_png(const char* filename) { + // This is the number of bytes the read_png routine will read to + // decide if the file is a PNG or not. According to the png + // documentation, it can be 1 to 8 bytes, 8 being the max and the + // best. + + const int header_size = 8; + + png_byte header[header_size]; + png_bytep *row_pointers; + + deallocate(); + + // open file + FILE *fp = fopen(filename, "rb"); + if (!fp) { + cerr << "Unable to open file " << filename << " for reading.\n"; + exit(1); + } + + // read header + fread(header, 1, header_size, fp); + if (png_sig_cmp(header, 0, header_size)) { + cerr << "File " << filename << " does not look like PNG.\n"; + fclose(fp); + exit(1); + } + + // create png pointer + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png_ptr) { + cerr << "png_create_read_struct failed\n"; + fclose(fp); + exit(1); + } + + // create png info struct + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, (png_infopp) 0, (png_infopp) 0); + cerr << "png_create_info_struct failed\n"; + fclose(fp); + exit(1); + } + + // get image info + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, header_size); + png_read_info(png_ptr, info_ptr); + + _width = info_ptr->width; + _height = info_ptr->height; + + png_byte bit_depth, color_type, channels; + color_type = info_ptr->color_type; + bit_depth = info_ptr->bit_depth; + channels = info_ptr->channels; + + if(bit_depth != 8) { + cerr << "Can only read 8-bits PNG images." << endl; + exit(1); + } + + // allocate image pointer + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * _height); + for (int y = 0; y < _height; y++) + row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes); + + allocate(); + + // read image + png_read_image(png_ptr, row_pointers); + + // send image to red, green and blue buffers + switch (color_type) { + case PNG_COLOR_TYPE_GRAY: + { + unsigned char pixel = 0; + for (int y = 0; y < _height; y++) for (int x = 0; x < _width; x++) { + pixel = row_pointers[y][x]; + _bit_plans[RED][y][x] = pixel; + _bit_plans[GREEN][y][x] = pixel; + _bit_plans[BLUE][y][x] = pixel; + } + } + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + cerr << "PNG type GRAY_ALPHA not supported.\n"; + exit(1); + break; + + case PNG_COLOR_TYPE_PALETTE: + cerr << "PNG type PALETTE not supported.\n"; + exit(1); + break; + + case PNG_COLOR_TYPE_RGB: + { + if(channels != RGB_DEPTH) { + cerr << "Unsupported number of channels for RGB type\n"; + break; + } + int k; + for (int y = 0; y < _height; y++) { + k = 0; + for (int x = 0; x < _width; x++) { + _bit_plans[RED][y][x] = row_pointers[y][k++]; + _bit_plans[GREEN][y][x] = row_pointers[y][k++]; + _bit_plans[BLUE][y][x] = row_pointers[y][k++]; + } + } + } + break; + + case PNG_COLOR_TYPE_RGB_ALPHA: + cerr << "PNG type RGB_ALPHA not supported.\n"; + exit(1); + break; + + default: + cerr << "Unknown PNG type\n"; + exit(1); + } + + // release memory + png_destroy_read_struct(&png_ptr, &info_ptr, 0); + + for (int y = 0; y < _height; y++) free(row_pointers[y]); + free(row_pointers); + + fclose(fp); +} + +void RGBImage::write_png(const char *filename) { + png_bytep *row_pointers; + + // create file + FILE *fp = fopen(filename, "wb"); + + if (!fp) { + cerr << "Unable to create image '" << filename << "'\n"; + exit(1); + } + + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + + if (!png_ptr) { + cerr << "png_create_write_struct failed\n"; + fclose(fp); + exit(1); + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + cerr << "png_create_info_struct failed\n"; + fclose(fp); + exit(1); + } + + png_init_io(png_ptr, fp); + + png_set_IHDR(png_ptr, info_ptr, _width, _height, + 8, 2, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + // allocate memory + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * _height); + for (int y = 0; y < _height; y++) + row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes); + + int k; + for (int y = 0; y < _height; y++) { + k = 0; + for (int x = 0; x < _width; x++) { + row_pointers[y][k++] = _bit_map[x + _width * (y + _height * RED)]; + row_pointers[y][k++] = _bit_map[x + _width * (y + _height * GREEN)]; + row_pointers[y][k++] = _bit_map[x + _width * (y + _height * BLUE)]; + } + } + + png_write_image(png_ptr, row_pointers); + png_write_end(png_ptr, 0); + + png_destroy_write_struct(&png_ptr, &info_ptr); + + // cleanup heap allocation + for (int y = 0; y < _height; y++) free(row_pointers[y]); + free(row_pointers); + + fclose(fp); +} diff --git a/rgb_image.h b/rgb_image.h new file mode 100644 index 0000000..c0e0c43 --- /dev/null +++ b/rgb_image.h @@ -0,0 +1,67 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef RGB_IMAGE_H +#define RGB_IMAGE_H + +#include "misc.h" + +using namespace std; + +class RGBImage { +protected: + int _width, _height; + unsigned char ***_bit_plans, **_bit_lines, *_bit_map; + static const int RED = 0; + static const int GREEN = 1; + static const int BLUE = 2; + static const int RGB_DEPTH = 3; + + void allocate(); + void deallocate(); + +public: + + RGBImage(); + RGBImage(int width, int height); + virtual ~RGBImage(); + + inline int width() const { return _width; } + inline int height() const { return _height; } + + inline void set_pixel(int x, int y, unsigned char r, unsigned char g, unsigned char b) { + ASSERT(x >= 0 && x < _width && y >= 0 && y < _height, "Out of bounds."); + _bit_plans[RED][y][x] = r; + _bit_plans[GREEN][y][x] = g; + _bit_plans[BLUE][y][x] = b; + } + + inline unsigned char pixel(int x, int y, int d) const { + ASSERT(x >= 0 && x < _width && y >= 0 && y < _height && d >= 0 && d < RGB_DEPTH, "Out of bounds."); + return _bit_plans[d][y][x]; + } + + virtual void read_ppm(const char *filename); + virtual void write_ppm(const char *filename); + + virtual void read_png(const char *filename); + virtual void write_png(const char *filename); +}; + +#endif diff --git a/room.cc b/room.cc new file mode 100644 index 0000000..ad03036 --- /dev/null +++ b/room.cc @@ -0,0 +1,83 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "room.h" +#include "misc.h" + +Room::Room(int view_width, int view_height, int nb_cameras, int nb_positions) { + _view_width = view_width; + _view_height = view_height; + _nb_cameras = nb_cameras; + _nb_positions = nb_positions; + _rectangles = new Rectangle[_nb_cameras * _nb_positions]; +} + +Room::~Room() { + delete[] _rectangles; +} + +void Room::save_stochastic_view(char *name, + int n_camera, + const ProbaView *view, + const Vector *proba_presence) const { + + RGBImage image(view->get_width(), view->get_height()); + + Array proba_pixel_off(_view_width, _view_height); + + for(int px = 0; px < _view_width; px++) for(int py = 0; py < _view_height; py++) + proba_pixel_off(px, py) = 1.0; + + Array dots(_view_width, _view_height); + dots.clear(); + + for(int n = 0; n < nb_positions(); n++) { + Rectangle *r = avatar(n_camera, n); + if(r->visible) { + for(int py = r->ymin; py < r->ymax; py++) + for(int px = r->xmin; px < r->xmax; px++) + proba_pixel_off(px, py) *= (1 - (*proba_presence)[n]); + if(r->xmin > 0 && r->xmax < _view_width-1 && r->ymax < _view_height-1) + dots((r->xmax + r->xmin)/2, r->ymax) = true; + } + } + + for(int py = 0; py < _view_height; py++) for(int px = 0; px < _view_width; px++) { + scalar_t r, g, b; + scalar_t a = proba_pixel_off(px, py); + + if(dots(px, py)) { r = 0.0; g = 0.0; b = 0.0; } + else { + if(a < 0.5) { r = 0; g = 0; b = 2*a; } + else { r = (a - 0.5) * 2; g = (a - 0.5) * 2; b = 1.0; } + } + + scalar_t c = (*view)(px, py); + + r = c * 0.0 + (1 - c) * r; + g = c * 0.8 + (1 - c) * g; + b = c * 0.6 + (1 - c) * b; + + image.set_pixel(px, py, (unsigned char) (255 * r), (unsigned char) (255 * g), (unsigned char) (255 * b)); + } + + image.write_png(name); +} diff --git a/room.h b/room.h new file mode 100644 index 0000000..f8c4c90 --- /dev/null +++ b/room.h @@ -0,0 +1,57 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef ROOM_H +#define ROOM_H + +#include "rectangle.h" +#include "proba_view.h" +#include "vector.h" + +using namespace std; + +class Room { + + int _nb_cameras, _nb_positions; + int _view_width, _view_height; + + Rectangle *_rectangles; + +public: + + Room(int view_width, int view_height, int nb_cameras, int nb_positions); + ~Room(); + + inline int nb_positions() const { return _nb_positions; } + inline int nb_cameras() const { return _nb_cameras; } + inline int view_width() const { return _view_width; } + inline int view_height() const { return _view_height; } + + inline Rectangle *avatar(int n_camera, int n_position) const { + ASSERT(n_camera >= 0 && n_camera < _nb_cameras && + n_position >= 0 && n_position < _nb_positions, + "Index out of bounds"); + return _rectangles + n_camera * _nb_positions + n_position; + } + + void save_stochastic_view(char *name, int ncam, const ProbaView *view, + const Vector *proba_presence) const; +}; + +#endif diff --git a/test.pom b/test.pom new file mode 100644 index 0000000..a785bb1 --- /dev/null +++ b/test.pom @@ -0,0 +1,2700 @@ + +# Simple file for the Probabilistic Occupancy Map + +# The images are of resolution 160x120, there are two cameras and 1332 +# locations of interest + +ROOM 160 120 2 1332 + +# The rectangles modeling silhouettes for every camera and location + +RECTANGLE 0 0 notvisible +RECTANGLE 0 1 notvisible +RECTANGLE 0 2 notvisible +RECTANGLE 0 3 notvisible +RECTANGLE 0 4 notvisible +RECTANGLE 0 5 notvisible +RECTANGLE 0 6 notvisible +RECTANGLE 0 7 notvisible +RECTANGLE 0 8 notvisible +RECTANGLE 0 9 notvisible +RECTANGLE 0 10 notvisible +RECTANGLE 0 11 notvisible +RECTANGLE 0 12 notvisible +RECTANGLE 0 13 notvisible +RECTANGLE 0 14 notvisible +RECTANGLE 0 15 notvisible +RECTANGLE 0 16 notvisible +RECTANGLE 0 17 notvisible +RECTANGLE 0 18 notvisible +RECTANGLE 0 19 notvisible +RECTANGLE 0 20 notvisible +RECTANGLE 0 21 notvisible +RECTANGLE 0 22 notvisible +RECTANGLE 0 23 notvisible +RECTANGLE 0 24 notvisible +RECTANGLE 0 25 notvisible +RECTANGLE 0 26 notvisible +RECTANGLE 0 27 notvisible +RECTANGLE 0 28 notvisible +RECTANGLE 0 29 notvisible +RECTANGLE 0 30 notvisible +RECTANGLE 0 31 notvisible +RECTANGLE 0 32 notvisible +RECTANGLE 0 33 notvisible +RECTANGLE 0 34 notvisible +RECTANGLE 0 35 notvisible +RECTANGLE 0 36 notvisible +RECTANGLE 0 37 notvisible +RECTANGLE 0 38 notvisible +RECTANGLE 0 39 notvisible +RECTANGLE 0 40 notvisible +RECTANGLE 0 41 notvisible +RECTANGLE 0 42 notvisible +RECTANGLE 0 43 notvisible +RECTANGLE 0 44 notvisible +RECTANGLE 0 45 notvisible +RECTANGLE 0 46 notvisible +RECTANGLE 0 47 notvisible +RECTANGLE 0 48 notvisible +RECTANGLE 0 49 notvisible +RECTANGLE 0 50 notvisible +RECTANGLE 0 51 notvisible +RECTANGLE 0 52 notvisible +RECTANGLE 0 53 notvisible +RECTANGLE 0 54 notvisible +RECTANGLE 0 55 notvisible +RECTANGLE 0 56 notvisible +RECTANGLE 0 57 notvisible +RECTANGLE 0 58 notvisible +RECTANGLE 0 59 notvisible +RECTANGLE 0 60 notvisible +RECTANGLE 0 61 notvisible +RECTANGLE 0 62 notvisible +RECTANGLE 0 63 notvisible +RECTANGLE 0 64 notvisible +RECTANGLE 0 65 notvisible +RECTANGLE 0 66 notvisible +RECTANGLE 0 67 notvisible +RECTANGLE 0 68 notvisible +RECTANGLE 0 69 notvisible +RECTANGLE 0 70 notvisible +RECTANGLE 0 71 notvisible +RECTANGLE 0 72 notvisible +RECTANGLE 0 73 notvisible +RECTANGLE 0 74 notvisible +RECTANGLE 0 75 notvisible +RECTANGLE 0 76 notvisible +RECTANGLE 0 77 notvisible +RECTANGLE 0 78 notvisible +RECTANGLE 0 79 notvisible +RECTANGLE 0 80 notvisible +RECTANGLE 0 81 notvisible +RECTANGLE 0 82 notvisible +RECTANGLE 0 83 notvisible +RECTANGLE 0 84 notvisible +RECTANGLE 0 85 notvisible +RECTANGLE 0 86 notvisible +RECTANGLE 0 87 notvisible +RECTANGLE 0 88 notvisible +RECTANGLE 0 89 notvisible +RECTANGLE 0 90 notvisible +RECTANGLE 0 91 notvisible +RECTANGLE 0 92 notvisible +RECTANGLE 0 93 notvisible +RECTANGLE 0 94 notvisible +RECTANGLE 0 95 notvisible +RECTANGLE 0 96 notvisible +RECTANGLE 0 97 notvisible +RECTANGLE 0 98 notvisible +RECTANGLE 0 99 notvisible +RECTANGLE 0 100 notvisible +RECTANGLE 0 101 notvisible +RECTANGLE 0 102 notvisible +RECTANGLE 0 103 notvisible +RECTANGLE 0 104 notvisible +RECTANGLE 0 105 notvisible +RECTANGLE 0 106 notvisible +RECTANGLE 0 107 notvisible +RECTANGLE 0 108 notvisible +RECTANGLE 0 109 notvisible +RECTANGLE 0 110 notvisible +RECTANGLE 0 111 notvisible +RECTANGLE 0 112 notvisible +RECTANGLE 0 113 notvisible +RECTANGLE 0 114 notvisible +RECTANGLE 0 115 notvisible +RECTANGLE 0 116 notvisible +RECTANGLE 0 117 notvisible +RECTANGLE 0 118 notvisible +RECTANGLE 0 119 notvisible +RECTANGLE 0 120 notvisible +RECTANGLE 0 121 notvisible +RECTANGLE 0 122 notvisible +RECTANGLE 0 123 notvisible +RECTANGLE 0 124 notvisible +RECTANGLE 0 125 notvisible +RECTANGLE 0 126 notvisible +RECTANGLE 0 127 notvisible +RECTANGLE 0 128 notvisible +RECTANGLE 0 129 notvisible +RECTANGLE 0 130 notvisible +RECTANGLE 0 131 notvisible +RECTANGLE 0 132 notvisible +RECTANGLE 0 133 notvisible +RECTANGLE 0 134 notvisible +RECTANGLE 0 135 notvisible +RECTANGLE 0 136 notvisible +RECTANGLE 0 137 notvisible +RECTANGLE 0 138 notvisible +RECTANGLE 0 139 notvisible +RECTANGLE 0 140 notvisible +RECTANGLE 0 141 notvisible +RECTANGLE 0 142 notvisible +RECTANGLE 0 143 notvisible +RECTANGLE 0 144 notvisible +RECTANGLE 0 145 notvisible +RECTANGLE 0 146 notvisible +RECTANGLE 0 147 notvisible +RECTANGLE 0 148 notvisible +RECTANGLE 0 149 notvisible +RECTANGLE 0 150 notvisible +RECTANGLE 0 151 notvisible +RECTANGLE 0 152 notvisible +RECTANGLE 0 153 notvisible +RECTANGLE 0 154 notvisible +RECTANGLE 0 155 notvisible +RECTANGLE 0 156 notvisible +RECTANGLE 0 157 notvisible +RECTANGLE 0 158 notvisible +RECTANGLE 0 159 notvisible +RECTANGLE 0 160 notvisible +RECTANGLE 0 161 notvisible +RECTANGLE 0 162 notvisible +RECTANGLE 0 163 notvisible +RECTANGLE 0 164 notvisible +RECTANGLE 0 165 notvisible +RECTANGLE 0 166 notvisible +RECTANGLE 0 167 notvisible +RECTANGLE 0 168 notvisible +RECTANGLE 0 169 notvisible +RECTANGLE 0 170 notvisible +RECTANGLE 0 171 notvisible +RECTANGLE 0 172 notvisible +RECTANGLE 0 173 notvisible +RECTANGLE 0 174 notvisible +RECTANGLE 0 175 notvisible +RECTANGLE 0 176 notvisible +RECTANGLE 0 177 notvisible +RECTANGLE 0 178 notvisible +RECTANGLE 0 179 notvisible +RECTANGLE 0 180 notvisible +RECTANGLE 0 181 notvisible +RECTANGLE 0 182 notvisible +RECTANGLE 0 183 notvisible +RECTANGLE 0 184 notvisible +RECTANGLE 0 185 notvisible +RECTANGLE 0 186 notvisible +RECTANGLE 0 187 notvisible +RECTANGLE 0 188 notvisible +RECTANGLE 0 189 notvisible +RECTANGLE 0 190 notvisible +RECTANGLE 0 191 notvisible +RECTANGLE 0 192 notvisible +RECTANGLE 0 193 notvisible +RECTANGLE 0 194 notvisible +RECTANGLE 0 195 notvisible +RECTANGLE 0 196 notvisible +RECTANGLE 0 197 notvisible +RECTANGLE 0 198 notvisible +RECTANGLE 0 199 notvisible +RECTANGLE 0 200 notvisible +RECTANGLE 0 201 notvisible +RECTANGLE 0 202 notvisible +RECTANGLE 0 203 notvisible +RECTANGLE 0 204 notvisible +RECTANGLE 0 205 notvisible +RECTANGLE 0 206 notvisible +RECTANGLE 0 207 notvisible +RECTANGLE 0 208 notvisible +RECTANGLE 0 209 notvisible +RECTANGLE 0 210 notvisible +RECTANGLE 0 211 notvisible +RECTANGLE 0 212 notvisible +RECTANGLE 0 213 notvisible +RECTANGLE 0 214 notvisible +RECTANGLE 0 215 notvisible +RECTANGLE 0 216 notvisible +RECTANGLE 0 217 notvisible +RECTANGLE 0 218 notvisible +RECTANGLE 0 219 notvisible +RECTANGLE 0 220 notvisible +RECTANGLE 0 221 notvisible +RECTANGLE 0 222 notvisible +RECTANGLE 0 223 notvisible +RECTANGLE 0 224 notvisible +RECTANGLE 0 225 notvisible +RECTANGLE 0 226 notvisible +RECTANGLE 0 227 notvisible +RECTANGLE 0 228 notvisible +RECTANGLE 0 229 notvisible +RECTANGLE 0 230 notvisible +RECTANGLE 0 231 notvisible +RECTANGLE 0 232 notvisible +RECTANGLE 0 233 notvisible +RECTANGLE 0 234 notvisible +RECTANGLE 0 235 notvisible +RECTANGLE 0 236 notvisible +RECTANGLE 0 237 notvisible +RECTANGLE 0 238 notvisible +RECTANGLE 0 239 notvisible +RECTANGLE 0 240 notvisible +RECTANGLE 0 241 notvisible +RECTANGLE 0 242 notvisible +RECTANGLE 0 243 notvisible +RECTANGLE 0 244 notvisible +RECTANGLE 0 245 notvisible +RECTANGLE 0 246 notvisible +RECTANGLE 0 247 notvisible +RECTANGLE 0 248 notvisible +RECTANGLE 0 249 notvisible +RECTANGLE 0 250 notvisible +RECTANGLE 0 251 notvisible +RECTANGLE 0 252 notvisible +RECTANGLE 0 253 notvisible +RECTANGLE 0 254 notvisible +RECTANGLE 0 255 notvisible +RECTANGLE 0 256 notvisible +RECTANGLE 0 257 notvisible +RECTANGLE 0 258 notvisible +RECTANGLE 0 259 notvisible +RECTANGLE 0 260 notvisible +RECTANGLE 0 261 notvisible +RECTANGLE 0 262 notvisible +RECTANGLE 0 263 notvisible +RECTANGLE 0 264 notvisible +RECTANGLE 0 265 notvisible +RECTANGLE 0 266 notvisible +RECTANGLE 0 267 notvisible +RECTANGLE 0 268 notvisible +RECTANGLE 0 269 notvisible +RECTANGLE 0 270 notvisible +RECTANGLE 0 271 notvisible +RECTANGLE 0 272 notvisible +RECTANGLE 0 273 notvisible +RECTANGLE 0 274 notvisible +RECTANGLE 0 275 112 0 159 119 +RECTANGLE 0 276 0 0 159 119 +RECTANGLE 0 277 notvisible +RECTANGLE 0 278 notvisible +RECTANGLE 0 279 notvisible +RECTANGLE 0 280 notvisible +RECTANGLE 0 281 notvisible +RECTANGLE 0 282 notvisible +RECTANGLE 0 283 notvisible +RECTANGLE 0 284 notvisible +RECTANGLE 0 285 notvisible +RECTANGLE 0 286 notvisible +RECTANGLE 0 287 notvisible +RECTANGLE 0 288 notvisible +RECTANGLE 0 289 notvisible +RECTANGLE 0 290 notvisible +RECTANGLE 0 291 notvisible +RECTANGLE 0 292 notvisible +RECTANGLE 0 293 notvisible +RECTANGLE 0 294 notvisible +RECTANGLE 0 295 notvisible +RECTANGLE 0 296 notvisible +RECTANGLE 0 297 notvisible +RECTANGLE 0 298 notvisible +RECTANGLE 0 299 notvisible +RECTANGLE 0 300 notvisible +RECTANGLE 0 301 notvisible +RECTANGLE 0 302 notvisible +RECTANGLE 0 303 notvisible +RECTANGLE 0 304 notvisible +RECTANGLE 0 305 notvisible +RECTANGLE 0 306 notvisible +RECTANGLE 0 307 notvisible +RECTANGLE 0 308 notvisible +RECTANGLE 0 309 notvisible +RECTANGLE 0 310 143 0 159 119 +RECTANGLE 0 311 117 0 159 119 +RECTANGLE 0 312 82 0 159 119 +RECTANGLE 0 313 28 0 159 119 +RECTANGLE 0 314 0 0 159 119 +RECTANGLE 0 315 notvisible +RECTANGLE 0 316 notvisible +RECTANGLE 0 317 notvisible +RECTANGLE 0 318 notvisible +RECTANGLE 0 319 notvisible +RECTANGLE 0 320 notvisible +RECTANGLE 0 321 notvisible +RECTANGLE 0 322 notvisible +RECTANGLE 0 323 notvisible +RECTANGLE 0 324 notvisible +RECTANGLE 0 325 notvisible +RECTANGLE 0 326 notvisible +RECTANGLE 0 327 notvisible +RECTANGLE 0 328 notvisible +RECTANGLE 0 329 notvisible +RECTANGLE 0 330 notvisible +RECTANGLE 0 331 notvisible +RECTANGLE 0 332 notvisible +RECTANGLE 0 333 notvisible +RECTANGLE 0 334 notvisible +RECTANGLE 0 335 notvisible +RECTANGLE 0 336 notvisible +RECTANGLE 0 337 notvisible +RECTANGLE 0 338 notvisible +RECTANGLE 0 339 notvisible +RECTANGLE 0 340 notvisible +RECTANGLE 0 341 notvisible +RECTANGLE 0 342 notvisible +RECTANGLE 0 343 notvisible +RECTANGLE 0 344 158 0 159 119 +RECTANGLE 0 345 143 0 159 119 +RECTANGLE 0 346 125 0 159 119 +RECTANGLE 0 347 104 0 159 119 +RECTANGLE 0 348 78 0 159 119 +RECTANGLE 0 349 46 0 159 119 +RECTANGLE 0 350 5 0 158 119 +RECTANGLE 0 351 0 0 147 119 +RECTANGLE 0 352 0 0 159 119 +RECTANGLE 0 353 notvisible +RECTANGLE 0 354 notvisible +RECTANGLE 0 355 notvisible +RECTANGLE 0 356 notvisible +RECTANGLE 0 357 notvisible +RECTANGLE 0 358 notvisible +RECTANGLE 0 359 notvisible +RECTANGLE 0 360 notvisible +RECTANGLE 0 361 notvisible +RECTANGLE 0 362 notvisible +RECTANGLE 0 363 notvisible +RECTANGLE 0 364 notvisible +RECTANGLE 0 365 notvisible +RECTANGLE 0 366 notvisible +RECTANGLE 0 367 notvisible +RECTANGLE 0 368 notvisible +RECTANGLE 0 369 notvisible +RECTANGLE 0 370 notvisible +RECTANGLE 0 371 notvisible +RECTANGLE 0 372 notvisible +RECTANGLE 0 373 notvisible +RECTANGLE 0 374 notvisible +RECTANGLE 0 375 notvisible +RECTANGLE 0 376 notvisible +RECTANGLE 0 377 notvisible +RECTANGLE 0 378 notvisible +RECTANGLE 0 379 154 0 159 119 +RECTANGLE 0 380 141 0 159 119 +RECTANGLE 0 381 127 0 159 119 +RECTANGLE 0 382 110 0 159 119 +RECTANGLE 0 383 92 0 159 119 +RECTANGLE 0 384 70 0 155 119 +RECTANGLE 0 385 45 0 139 119 +RECTANGLE 0 386 14 0 121 119 +RECTANGLE 0 387 0 0 101 119 +RECTANGLE 0 388 0 0 77 119 +RECTANGLE 0 389 0 0 55 119 +RECTANGLE 0 390 0 0 55 119 +RECTANGLE 0 391 notvisible +RECTANGLE 0 392 notvisible +RECTANGLE 0 393 notvisible +RECTANGLE 0 394 notvisible +RECTANGLE 0 395 notvisible +RECTANGLE 0 396 notvisible +RECTANGLE 0 397 notvisible +RECTANGLE 0 398 notvisible +RECTANGLE 0 399 notvisible +RECTANGLE 0 400 notvisible +RECTANGLE 0 401 notvisible +RECTANGLE 0 402 notvisible +RECTANGLE 0 403 notvisible +RECTANGLE 0 404 notvisible +RECTANGLE 0 405 notvisible +RECTANGLE 0 406 notvisible +RECTANGLE 0 407 notvisible +RECTANGLE 0 408 notvisible +RECTANGLE 0 409 notvisible +RECTANGLE 0 410 notvisible +RECTANGLE 0 411 notvisible +RECTANGLE 0 412 notvisible +RECTANGLE 0 413 notvisible +RECTANGLE 0 414 150 0 159 119 +RECTANGLE 0 415 139 0 159 119 +RECTANGLE 0 416 127 0 159 119 +RECTANGLE 0 417 114 0 159 119 +RECTANGLE 0 418 99 0 159 119 +RECTANGLE 0 419 82 0 147 119 +RECTANGLE 0 420 64 0 134 119 +RECTANGLE 0 421 42 0 118 119 +RECTANGLE 0 422 17 0 101 119 +RECTANGLE 0 423 0 0 80 119 +RECTANGLE 0 424 0 0 57 119 +RECTANGLE 0 425 0 0 30 119 +RECTANGLE 0 426 0 0 0 119 +RECTANGLE 0 427 notvisible +RECTANGLE 0 428 notvisible +RECTANGLE 0 429 notvisible +RECTANGLE 0 430 notvisible +RECTANGLE 0 431 notvisible +RECTANGLE 0 432 notvisible +RECTANGLE 0 433 notvisible +RECTANGLE 0 434 notvisible +RECTANGLE 0 435 notvisible +RECTANGLE 0 436 notvisible +RECTANGLE 0 437 notvisible +RECTANGLE 0 438 notvisible +RECTANGLE 0 439 notvisible +RECTANGLE 0 440 notvisible +RECTANGLE 0 441 notvisible +RECTANGLE 0 442 notvisible +RECTANGLE 0 443 notvisible +RECTANGLE 0 444 notvisible +RECTANGLE 0 445 notvisible +RECTANGLE 0 446 notvisible +RECTANGLE 0 447 notvisible +RECTANGLE 0 448 156 0 159 110 +RECTANGLE 0 449 147 0 159 114 +RECTANGLE 0 450 138 0 159 119 +RECTANGLE 0 451 127 0 159 119 +RECTANGLE 0 452 116 0 159 119 +RECTANGLE 0 453 104 0 154 119 +RECTANGLE 0 454 90 0 143 119 +RECTANGLE 0 455 75 0 131 119 +RECTANGLE 0 456 58 0 118 119 +RECTANGLE 0 457 39 0 104 119 +RECTANGLE 0 458 17 0 87 119 +RECTANGLE 0 459 0 0 68 119 +RECTANGLE 0 460 0 0 47 119 +RECTANGLE 0 461 0 0 23 119 +RECTANGLE 0 462 notvisible +RECTANGLE 0 463 notvisible +RECTANGLE 0 464 notvisible +RECTANGLE 0 465 notvisible +RECTANGLE 0 466 notvisible +RECTANGLE 0 467 notvisible +RECTANGLE 0 468 notvisible +RECTANGLE 0 469 notvisible +RECTANGLE 0 470 notvisible +RECTANGLE 0 471 notvisible +RECTANGLE 0 472 notvisible +RECTANGLE 0 473 notvisible +RECTANGLE 0 474 notvisible +RECTANGLE 0 475 notvisible +RECTANGLE 0 476 notvisible +RECTANGLE 0 477 notvisible +RECTANGLE 0 478 notvisible +RECTANGLE 0 479 notvisible +RECTANGLE 0 480 notvisible +RECTANGLE 0 481 notvisible +RECTANGLE 0 482 notvisible +RECTANGLE 0 483 152 0 159 101 +RECTANGLE 0 484 145 0 159 104 +RECTANGLE 0 485 136 0 159 107 +RECTANGLE 0 486 127 0 159 111 +RECTANGLE 0 487 118 0 158 115 +RECTANGLE 0 488 107 0 149 119 +RECTANGLE 0 489 95 0 140 119 +RECTANGLE 0 490 83 0 130 119 +RECTANGLE 0 491 68 0 118 119 +RECTANGLE 0 492 53 0 106 119 +RECTANGLE 0 493 36 0 92 119 +RECTANGLE 0 494 17 0 77 119 +RECTANGLE 0 495 0 0 60 119 +RECTANGLE 0 496 0 0 41 119 +RECTANGLE 0 497 0 0 19 119 +RECTANGLE 0 498 notvisible +RECTANGLE 0 499 notvisible +RECTANGLE 0 500 notvisible +RECTANGLE 0 501 notvisible +RECTANGLE 0 502 notvisible +RECTANGLE 0 503 notvisible +RECTANGLE 0 504 notvisible +RECTANGLE 0 505 notvisible +RECTANGLE 0 506 notvisible +RECTANGLE 0 507 notvisible +RECTANGLE 0 508 notvisible +RECTANGLE 0 509 notvisible +RECTANGLE 0 510 notvisible +RECTANGLE 0 511 notvisible +RECTANGLE 0 512 notvisible +RECTANGLE 0 513 notvisible +RECTANGLE 0 514 notvisible +RECTANGLE 0 515 notvisible +RECTANGLE 0 516 notvisible +RECTANGLE 0 517 156 2 159 91 +RECTANGLE 0 518 150 1 159 93 +RECTANGLE 0 519 143 0 159 96 +RECTANGLE 0 520 135 0 159 98 +RECTANGLE 0 521 127 0 159 101 +RECTANGLE 0 522 119 0 154 104 +RECTANGLE 0 523 109 0 146 108 +RECTANGLE 0 524 99 0 137 111 +RECTANGLE 0 525 88 0 128 115 +RECTANGLE 0 526 76 0 118 119 +RECTANGLE 0 527 64 0 108 119 +RECTANGLE 0 528 49 0 96 119 +RECTANGLE 0 529 34 0 84 119 +RECTANGLE 0 530 17 0 70 119 +RECTANGLE 0 531 0 0 54 119 +RECTANGLE 0 532 0 0 37 119 +RECTANGLE 0 533 0 0 17 119 +RECTANGLE 0 534 notvisible +RECTANGLE 0 535 notvisible +RECTANGLE 0 536 notvisible +RECTANGLE 0 537 notvisible +RECTANGLE 0 538 notvisible +RECTANGLE 0 539 notvisible +RECTANGLE 0 540 notvisible +RECTANGLE 0 541 notvisible +RECTANGLE 0 542 notvisible +RECTANGLE 0 543 notvisible +RECTANGLE 0 544 notvisible +RECTANGLE 0 545 notvisible +RECTANGLE 0 546 notvisible +RECTANGLE 0 547 notvisible +RECTANGLE 0 548 notvisible +RECTANGLE 0 549 notvisible +RECTANGLE 0 550 notvisible +RECTANGLE 0 551 notvisible +RECTANGLE 0 552 154 4 159 85 +RECTANGLE 0 553 148 4 159 87 +RECTANGLE 0 554 141 3 159 89 +RECTANGLE 0 555 134 2 159 91 +RECTANGLE 0 556 127 1 157 94 +RECTANGLE 0 557 119 0 151 96 +RECTANGLE 0 558 111 0 144 99 +RECTANGLE 0 559 102 0 136 102 +RECTANGLE 0 560 93 0 128 105 +RECTANGLE 0 561 82 0 119 108 +RECTANGLE 0 562 71 0 110 112 +RECTANGLE 0 563 59 0 99 116 +RECTANGLE 0 564 46 0 88 119 +RECTANGLE 0 565 32 0 76 119 +RECTANGLE 0 566 16 0 63 119 +RECTANGLE 0 567 0 0 49 119 +RECTANGLE 0 568 0 0 33 119 +RECTANGLE 0 569 0 0 16 119 +RECTANGLE 0 570 notvisible +RECTANGLE 0 571 notvisible +RECTANGLE 0 572 notvisible +RECTANGLE 0 573 notvisible +RECTANGLE 0 574 notvisible +RECTANGLE 0 575 notvisible +RECTANGLE 0 576 notvisible +RECTANGLE 0 577 notvisible +RECTANGLE 0 578 notvisible +RECTANGLE 0 579 notvisible +RECTANGLE 0 580 notvisible +RECTANGLE 0 581 notvisible +RECTANGLE 0 582 notvisible +RECTANGLE 0 583 notvisible +RECTANGLE 0 584 notvisible +RECTANGLE 0 585 notvisible +RECTANGLE 0 586 157 7 159 78 +RECTANGLE 0 587 151 6 159 80 +RECTANGLE 0 588 146 6 159 82 +RECTANGLE 0 589 140 5 159 83 +RECTANGLE 0 590 134 5 159 85 +RECTANGLE 0 591 127 4 154 87 +RECTANGLE 0 592 120 3 148 89 +RECTANGLE 0 593 112 2 141 92 +RECTANGLE 0 594 104 1 134 94 +RECTANGLE 0 595 96 1 127 96 +RECTANGLE 0 596 87 0 120 99 +RECTANGLE 0 597 77 0 111 102 +RECTANGLE 0 598 67 0 102 105 +RECTANGLE 0 599 55 0 92 109 +RECTANGLE 0 600 43 0 82 112 +RECTANGLE 0 601 31 0 71 116 +RECTANGLE 0 602 16 0 58 119 +RECTANGLE 0 603 1 0 45 119 +RECTANGLE 0 604 0 0 31 119 +RECTANGLE 0 605 0 0 15 119 +RECTANGLE 0 606 notvisible +RECTANGLE 0 607 notvisible +RECTANGLE 0 608 notvisible +RECTANGLE 0 609 notvisible +RECTANGLE 0 610 notvisible +RECTANGLE 0 611 notvisible +RECTANGLE 0 612 notvisible +RECTANGLE 0 613 notvisible +RECTANGLE 0 614 notvisible +RECTANGLE 0 615 notvisible +RECTANGLE 0 616 notvisible +RECTANGLE 0 617 notvisible +RECTANGLE 0 618 notvisible +RECTANGLE 0 619 notvisible +RECTANGLE 0 620 159 9 159 73 +RECTANGLE 0 621 154 8 159 74 +RECTANGLE 0 622 150 8 159 76 +RECTANGLE 0 623 144 7 159 77 +RECTANGLE 0 624 138 7 159 79 +RECTANGLE 0 625 133 6 157 80 +RECTANGLE 0 626 127 6 152 82 +RECTANGLE 0 627 120 5 146 84 +RECTANGLE 0 628 113 5 140 86 +RECTANGLE 0 629 106 4 134 88 +RECTANGLE 0 630 99 3 127 90 +RECTANGLE 0 631 91 2 120 92 +RECTANGLE 0 632 82 2 112 94 +RECTANGLE 0 633 72 1 104 97 +RECTANGLE 0 634 63 0 96 100 +RECTANGLE 0 635 52 0 86 102 +RECTANGLE 0 636 41 0 76 106 +RECTANGLE 0 637 29 0 66 109 +RECTANGLE 0 638 16 0 55 113 +RECTANGLE 0 639 2 0 42 116 +RECTANGLE 0 640 0 0 29 119 +RECTANGLE 0 641 0 0 15 119 +RECTANGLE 0 642 notvisible +RECTANGLE 0 643 notvisible +RECTANGLE 0 644 notvisible +RECTANGLE 0 645 notvisible +RECTANGLE 0 646 notvisible +RECTANGLE 0 647 notvisible +RECTANGLE 0 648 notvisible +RECTANGLE 0 649 notvisible +RECTANGLE 0 650 notvisible +RECTANGLE 0 651 notvisible +RECTANGLE 0 652 notvisible +RECTANGLE 0 653 notvisible +RECTANGLE 0 654 notvisible +RECTANGLE 0 655 157 10 159 70 +RECTANGLE 0 656 152 10 159 71 +RECTANGLE 0 657 148 9 159 72 +RECTANGLE 0 658 143 9 159 73 +RECTANGLE 0 659 137 8 159 75 +RECTANGLE 0 660 132 8 154 76 +RECTANGLE 0 661 127 8 150 77 +RECTANGLE 0 662 121 7 144 79 +RECTANGLE 0 663 114 7 138 81 +RECTANGLE 0 664 108 6 133 82 +RECTANGLE 0 665 101 5 127 84 +RECTANGLE 0 666 93 5 120 86 +RECTANGLE 0 667 86 4 113 88 +RECTANGLE 0 668 77 3 106 90 +RECTANGLE 0 669 69 3 98 92 +RECTANGLE 0 670 59 2 90 95 +RECTANGLE 0 671 49 1 81 97 +RECTANGLE 0 672 39 0 72 100 +RECTANGLE 0 673 28 0 62 103 +RECTANGLE 0 674 15 0 51 106 +RECTANGLE 0 675 3 0 40 109 +RECTANGLE 0 676 0 0 27 113 +RECTANGLE 0 677 0 0 14 117 +RECTANGLE 0 678 0 0 0 119 +RECTANGLE 0 679 notvisible +RECTANGLE 0 680 notvisible +RECTANGLE 0 681 notvisible +RECTANGLE 0 682 notvisible +RECTANGLE 0 683 notvisible +RECTANGLE 0 684 notvisible +RECTANGLE 0 685 notvisible +RECTANGLE 0 686 notvisible +RECTANGLE 0 687 notvisible +RECTANGLE 0 688 notvisible +RECTANGLE 0 689 159 11 159 66 +RECTANGLE 0 690 155 11 159 67 +RECTANGLE 0 691 151 11 159 68 +RECTANGLE 0 692 146 10 159 69 +RECTANGLE 0 693 141 10 159 70 +RECTANGLE 0 694 137 10 157 71 +RECTANGLE 0 695 132 9 153 72 +RECTANGLE 0 696 127 9 148 74 +RECTANGLE 0 697 121 8 143 75 +RECTANGLE 0 698 115 8 137 76 +RECTANGLE 0 699 109 8 132 78 +RECTANGLE 0 700 102 7 126 79 +RECTANGLE 0 701 96 7 120 81 +RECTANGLE 0 702 89 6 114 83 +RECTANGLE 0 703 81 5 107 84 +RECTANGLE 0 704 73 5 100 86 +RECTANGLE 0 705 65 4 93 88 +RECTANGLE 0 706 57 4 85 90 +RECTANGLE 0 707 47 3 77 93 +RECTANGLE 0 708 37 2 68 95 +RECTANGLE 0 709 26 1 58 98 +RECTANGLE 0 710 15 0 48 100 +RECTANGLE 0 711 3 0 37 103 +RECTANGLE 0 712 0 0 26 106 +RECTANGLE 0 713 0 0 14 110 +RECTANGLE 0 714 0 0 0 113 +RECTANGLE 0 715 notvisible +RECTANGLE 0 716 notvisible +RECTANGLE 0 717 notvisible +RECTANGLE 0 718 notvisible +RECTANGLE 0 719 notvisible +RECTANGLE 0 720 notvisible +RECTANGLE 0 721 notvisible +RECTANGLE 0 722 notvisible +RECTANGLE 0 723 notvisible +RECTANGLE 0 724 157 12 159 63 +RECTANGLE 0 725 153 12 159 64 +RECTANGLE 0 726 149 12 159 65 +RECTANGLE 0 727 145 11 159 66 +RECTANGLE 0 728 141 11 159 67 +RECTANGLE 0 729 136 11 155 68 +RECTANGLE 0 730 131 10 150 69 +RECTANGLE 0 731 126 10 146 70 +RECTANGLE 0 732 121 10 141 71 +RECTANGLE 0 733 116 9 137 73 +RECTANGLE 0 734 110 9 131 74 +RECTANGLE 0 735 104 9 126 75 +RECTANGLE 0 736 98 8 120 77 +RECTANGLE 0 737 92 8 115 78 +RECTANGLE 0 738 85 7 109 80 +RECTANGLE 0 739 78 7 102 81 +RECTANGLE 0 740 70 6 95 83 +RECTANGLE 0 741 62 6 88 85 +RECTANGLE 0 742 54 5 81 87 +RECTANGLE 0 743 45 4 73 89 +RECTANGLE 0 744 35 4 64 91 +RECTANGLE 0 745 25 3 55 93 +RECTANGLE 0 746 15 2 46 96 +RECTANGLE 0 747 4 1 36 98 +RECTANGLE 0 748 0 0 25 101 +RECTANGLE 0 749 0 0 13 104 +RECTANGLE 0 750 0 0 1 107 +RECTANGLE 0 751 notvisible +RECTANGLE 0 752 notvisible +RECTANGLE 0 753 notvisible +RECTANGLE 0 754 notvisible +RECTANGLE 0 755 notvisible +RECTANGLE 0 756 notvisible +RECTANGLE 0 757 notvisible +RECTANGLE 0 758 159 13 159 60 +RECTANGLE 0 759 155 13 159 61 +RECTANGLE 0 760 152 13 159 62 +RECTANGLE 0 761 148 12 159 63 +RECTANGLE 0 762 144 12 159 63 +RECTANGLE 0 763 140 12 157 64 +RECTANGLE 0 764 136 12 153 65 +RECTANGLE 0 765 131 11 149 66 +RECTANGLE 0 766 126 11 144 67 +RECTANGLE 0 767 121 11 140 68 +RECTANGLE 0 768 117 10 136 69 +RECTANGLE 0 769 111 10 131 71 +RECTANGLE 0 770 106 10 126 72 +RECTANGLE 0 771 100 9 121 73 +RECTANGLE 0 772 94 9 115 74 +RECTANGLE 0 773 88 9 110 76 +RECTANGLE 0 774 81 8 103 77 +RECTANGLE 0 775 74 8 97 78 +RECTANGLE 0 776 67 7 91 80 +RECTANGLE 0 777 59 7 84 82 +RECTANGLE 0 778 52 6 77 83 +RECTANGLE 0 779 43 6 69 85 +RECTANGLE 0 780 34 5 61 87 +RECTANGLE 0 781 25 4 53 89 +RECTANGLE 0 782 15 4 44 91 +RECTANGLE 0 783 4 3 34 93 +RECTANGLE 0 784 0 2 24 96 +RECTANGLE 0 785 0 1 13 98 +RECTANGLE 0 786 0 0 2 101 +RECTANGLE 0 787 notvisible +RECTANGLE 0 788 notvisible +RECTANGLE 0 789 notvisible +RECTANGLE 0 790 notvisible +RECTANGLE 0 791 notvisible +RECTANGLE 0 792 notvisible +RECTANGLE 0 793 158 14 159 58 +RECTANGLE 0 794 154 13 159 59 +RECTANGLE 0 795 150 13 159 60 +RECTANGLE 0 796 147 13 159 60 +RECTANGLE 0 797 143 13 159 61 +RECTANGLE 0 798 139 13 155 62 +RECTANGLE 0 799 135 12 151 63 +RECTANGLE 0 800 130 12 147 64 +RECTANGLE 0 801 126 12 143 65 +RECTANGLE 0 802 121 12 139 66 +RECTANGLE 0 803 117 11 135 67 +RECTANGLE 0 804 112 11 130 68 +RECTANGLE 0 805 107 11 126 69 +RECTANGLE 0 806 102 10 121 70 +RECTANGLE 0 807 96 10 116 71 +RECTANGLE 0 808 90 10 110 72 +RECTANGLE 0 809 84 9 105 73 +RECTANGLE 0 810 78 9 99 75 +RECTANGLE 0 811 71 9 93 76 +RECTANGLE 0 812 64 8 87 77 +RECTANGLE 0 813 57 8 80 79 +RECTANGLE 0 814 49 7 73 80 +RECTANGLE 0 815 41 7 66 82 +RECTANGLE 0 816 33 6 58 84 +RECTANGLE 0 817 24 6 50 86 +RECTANGLE 0 818 15 5 42 87 +RECTANGLE 0 819 5 5 33 89 +RECTANGLE 0 820 0 4 23 92 +RECTANGLE 0 821 0 3 13 94 +RECTANGLE 0 822 0 2 2 96 +RECTANGLE 0 823 notvisible +RECTANGLE 0 824 notvisible +RECTANGLE 0 825 notvisible +RECTANGLE 0 826 notvisible +RECTANGLE 0 827 notvisible +RECTANGLE 0 828 156 14 159 57 +RECTANGLE 0 829 152 14 159 57 +RECTANGLE 0 830 149 14 159 58 +RECTANGLE 0 831 145 14 159 59 +RECTANGLE 0 832 142 14 157 59 +RECTANGLE 0 833 138 13 153 60 +RECTANGLE 0 834 135 13 150 61 +RECTANGLE 0 835 130 13 146 62 +RECTANGLE 0 836 126 13 142 62 +RECTANGLE 0 837 122 12 139 63 +RECTANGLE 0 838 117 12 134 64 +RECTANGLE 0 839 113 12 130 65 +RECTANGLE 0 840 108 12 126 66 +RECTANGLE 0 841 103 11 121 67 +RECTANGLE 0 842 98 11 116 68 +RECTANGLE 0 843 92 11 111 69 +RECTANGLE 0 844 87 11 106 70 +RECTANGLE 0 845 81 10 101 71 +RECTANGLE 0 846 75 10 95 72 +RECTANGLE 0 847 68 10 89 74 +RECTANGLE 0 848 62 9 83 75 +RECTANGLE 0 849 55 9 77 76 +RECTANGLE 0 850 47 8 70 78 +RECTANGLE 0 851 40 8 63 79 +RECTANGLE 0 852 32 7 56 81 +RECTANGLE 0 853 23 7 48 82 +RECTANGLE 0 854 14 6 40 84 +RECTANGLE 0 855 5 6 31 86 +RECTANGLE 0 856 0 5 22 88 +RECTANGLE 0 857 0 5 13 90 +RECTANGLE 0 858 0 4 3 92 +RECTANGLE 0 859 notvisible +RECTANGLE 0 860 notvisible +RECTANGLE 0 861 notvisible +RECTANGLE 0 862 notvisible +RECTANGLE 0 863 notvisible +RECTANGLE 0 864 151 15 159 56 +RECTANGLE 0 865 148 14 159 56 +RECTANGLE 0 866 144 14 158 57 +RECTANGLE 0 867 141 14 155 57 +RECTANGLE 0 868 138 14 152 58 +RECTANGLE 0 869 134 14 149 59 +RECTANGLE 0 870 130 14 145 60 +RECTANGLE 0 871 126 13 141 60 +RECTANGLE 0 872 122 13 138 61 +RECTANGLE 0 873 118 13 134 62 +RECTANGLE 0 874 114 13 130 63 +RECTANGLE 0 875 109 12 126 63 +RECTANGLE 0 876 104 12 121 64 +RECTANGLE 0 877 99 12 116 65 +RECTANGLE 0 878 94 12 112 66 +RECTANGLE 0 879 89 11 107 67 +RECTANGLE 0 880 83 11 102 68 +RECTANGLE 0 881 78 11 97 69 +RECTANGLE 0 882 72 11 91 70 +RECTANGLE 0 883 66 10 86 71 +RECTANGLE 0 884 59 10 80 73 +RECTANGLE 0 885 53 10 74 74 +RECTANGLE 0 886 45 9 67 75 +RECTANGLE 0 887 38 9 60 77 +RECTANGLE 0 888 31 8 54 78 +RECTANGLE 0 889 23 8 46 79 +RECTANGLE 0 890 14 8 38 81 +RECTANGLE 0 891 5 7 30 83 +RECTANGLE 0 892 0 7 21 84 +RECTANGLE 0 893 0 6 12 86 +RECTANGLE 0 894 0 5 3 88 +RECTANGLE 0 895 notvisible +RECTANGLE 0 896 notvisible +RECTANGLE 0 897 notvisible +RECTANGLE 0 898 notvisible +RECTANGLE 0 899 notvisible +RECTANGLE 0 900 147 15 159 55 +RECTANGLE 0 901 144 15 157 55 +RECTANGLE 0 902 140 15 153 56 +RECTANGLE 0 903 137 14 151 56 +RECTANGLE 0 904 133 14 147 57 +RECTANGLE 0 905 130 14 144 58 +RECTANGLE 0 906 126 14 140 58 +RECTANGLE 0 907 122 14 137 59 +RECTANGLE 0 908 118 14 133 60 +RECTANGLE 0 909 114 13 129 61 +RECTANGLE 0 910 110 13 126 61 +RECTANGLE 0 911 105 13 121 62 +RECTANGLE 0 912 101 13 117 63 +RECTANGLE 0 913 96 13 113 64 +RECTANGLE 0 914 91 12 108 65 +RECTANGLE 0 915 86 12 103 66 +RECTANGLE 0 916 81 12 99 66 +RECTANGLE 0 917 75 12 93 67 +RECTANGLE 0 918 69 11 88 68 +RECTANGLE 0 919 64 11 83 70 +RECTANGLE 0 920 57 11 77 71 +RECTANGLE 0 921 51 10 71 72 +RECTANGLE 0 922 44 10 64 73 +RECTANGLE 0 923 37 10 58 74 +RECTANGLE 0 924 30 9 52 76 +RECTANGLE 0 925 22 9 44 77 +RECTANGLE 0 926 14 9 37 78 +RECTANGLE 0 927 6 8 29 80 +RECTANGLE 0 928 0 8 21 81 +RECTANGLE 0 929 0 7 13 83 +RECTANGLE 0 930 0 7 4 85 +RECTANGLE 0 931 notvisible +RECTANGLE 0 932 notvisible +RECTANGLE 0 933 notvisible +RECTANGLE 0 934 notvisible +RECTANGLE 0 935 notvisible +RECTANGLE 0 936 143 15 155 54 +RECTANGLE 0 937 139 15 152 54 +RECTANGLE 0 938 136 15 149 55 +RECTANGLE 0 939 133 15 146 56 +RECTANGLE 0 940 130 15 143 56 +RECTANGLE 0 941 126 14 140 57 +RECTANGLE 0 942 122 14 136 57 +RECTANGLE 0 943 119 14 133 58 +RECTANGLE 0 944 114 14 129 59 +RECTANGLE 0 945 110 14 125 59 +RECTANGLE 0 946 106 14 121 60 +RECTANGLE 0 947 102 13 117 61 +RECTANGLE 0 948 97 13 113 62 +RECTANGLE 0 949 93 13 109 62 +RECTANGLE 0 950 88 13 104 63 +RECTANGLE 0 951 83 13 100 64 +RECTANGLE 0 952 78 12 95 65 +RECTANGLE 0 953 73 12 90 66 +RECTANGLE 0 954 67 12 85 67 +RECTANGLE 0 955 62 12 80 68 +RECTANGLE 0 956 55 11 74 69 +RECTANGLE 0 957 49 11 68 70 +RECTANGLE 0 958 43 11 63 71 +RECTANGLE 0 959 36 10 56 72 +RECTANGLE 0 960 29 10 50 73 +RECTANGLE 0 961 22 10 43 75 +RECTANGLE 0 962 14 9 36 76 +RECTANGLE 0 963 6 9 28 77 +RECTANGLE 0 964 0 9 21 79 +RECTANGLE 0 965 0 8 13 80 +RECTANGLE 0 966 0 8 4 82 +RECTANGLE 0 967 notvisible +RECTANGLE 0 968 notvisible +RECTANGLE 0 969 notvisible +RECTANGLE 0 970 notvisible +RECTANGLE 0 971 notvisible +RECTANGLE 0 972 139 16 151 53 +RECTANGLE 0 973 136 15 148 54 +RECTANGLE 0 974 132 15 145 54 +RECTANGLE 0 975 129 15 142 55 +RECTANGLE 0 976 126 15 139 55 +RECTANGLE 0 977 122 15 135 56 +RECTANGLE 0 978 119 15 132 56 +RECTANGLE 0 979 115 15 129 57 +RECTANGLE 0 980 111 14 125 58 +RECTANGLE 0 981 107 14 121 58 +RECTANGLE 0 982 103 14 117 59 +RECTANGLE 0 983 99 14 114 60 +RECTANGLE 0 984 95 14 110 60 +RECTANGLE 0 985 90 13 106 61 +RECTANGLE 0 986 85 13 101 62 +RECTANGLE 0 987 81 13 97 63 +RECTANGLE 0 988 76 13 92 63 +RECTANGLE 0 989 70 13 87 64 +RECTANGLE 0 990 65 12 82 65 +RECTANGLE 0 991 59 12 77 66 +RECTANGLE 0 992 54 12 72 67 +RECTANGLE 0 993 48 12 66 68 +RECTANGLE 0 994 41 11 60 69 +RECTANGLE 0 995 35 11 54 70 +RECTANGLE 0 996 28 11 48 71 +RECTANGLE 0 997 21 10 41 72 +RECTANGLE 0 998 14 10 35 74 +RECTANGLE 0 999 6 10 27 75 +RECTANGLE 0 1000 0 9 20 76 +RECTANGLE 0 1001 0 9 12 78 +RECTANGLE 0 1002 0 9 4 79 +RECTANGLE 0 1003 notvisible +RECTANGLE 0 1004 notvisible +RECTANGLE 0 1005 notvisible +RECTANGLE 0 1006 notvisible +RECTANGLE 0 1007 notvisible +RECTANGLE 0 1008 135 16 147 52 +RECTANGLE 0 1009 132 16 144 53 +RECTANGLE 0 1010 129 16 141 53 +RECTANGLE 0 1011 126 15 138 54 +RECTANGLE 0 1012 122 15 135 54 +RECTANGLE 0 1013 119 15 132 55 +RECTANGLE 0 1014 115 15 128 55 +RECTANGLE 0 1015 112 15 125 56 +RECTANGLE 0 1016 108 15 122 57 +RECTANGLE 0 1017 104 15 118 57 +RECTANGLE 0 1018 100 14 114 58 +RECTANGLE 0 1019 96 14 110 59 +RECTANGLE 0 1020 92 14 107 59 +RECTANGLE 0 1021 87 14 102 60 +RECTANGLE 0 1022 83 14 98 61 +RECTANGLE 0 1023 78 14 93 61 +RECTANGLE 0 1024 73 13 89 62 +RECTANGLE 0 1025 68 13 84 63 +RECTANGLE 0 1026 63 13 80 64 +RECTANGLE 0 1027 58 13 75 65 +RECTANGLE 0 1028 52 12 69 65 +RECTANGLE 0 1029 46 12 64 66 +RECTANGLE 0 1030 40 12 58 67 +RECTANGLE 0 1031 34 12 52 68 +RECTANGLE 0 1032 27 11 46 69 +RECTANGLE 0 1033 21 11 40 70 +RECTANGLE 0 1034 14 11 34 72 +RECTANGLE 0 1035 7 11 27 73 +RECTANGLE 0 1036 0 10 20 74 +RECTANGLE 0 1037 0 10 12 75 +RECTANGLE 0 1038 0 9 4 77 +RECTANGLE 0 1039 notvisible +RECTANGLE 0 1040 notvisible +RECTANGLE 0 1041 notvisible +RECTANGLE 0 1042 notvisible +RECTANGLE 0 1043 notvisible +RECTANGLE 0 1044 132 16 143 52 +RECTANGLE 0 1045 129 16 141 52 +RECTANGLE 0 1046 126 16 138 52 +RECTANGLE 0 1047 123 16 135 53 +RECTANGLE 0 1048 119 16 131 53 +RECTANGLE 0 1049 116 15 129 54 +RECTANGLE 0 1050 112 15 125 55 +RECTANGLE 0 1051 109 15 122 55 +RECTANGLE 0 1052 105 15 118 56 +RECTANGLE 0 1053 101 15 114 56 +RECTANGLE 0 1054 97 15 111 57 +RECTANGLE 0 1055 93 15 107 57 +RECTANGLE 0 1056 89 14 103 58 +RECTANGLE 0 1057 85 14 99 59 +RECTANGLE 0 1058 80 14 95 59 +RECTANGLE 0 1059 76 14 91 60 +RECTANGLE 0 1060 71 14 86 61 +RECTANGLE 0 1061 66 14 82 62 +RECTANGLE 0 1062 61 13 77 62 +RECTANGLE 0 1063 56 13 72 63 +RECTANGLE 0 1064 50 13 67 64 +RECTANGLE 0 1065 45 13 62 65 +RECTANGLE 0 1066 39 12 56 66 +RECTANGLE 0 1067 33 12 51 67 +RECTANGLE 0 1068 27 12 45 68 +RECTANGLE 0 1069 20 12 39 69 +RECTANGLE 0 1070 14 11 33 70 +RECTANGLE 0 1071 7 11 26 71 +RECTANGLE 0 1072 0 11 19 72 +RECTANGLE 0 1073 0 11 12 73 +RECTANGLE 0 1074 0 10 5 74 +RECTANGLE 0 1075 notvisible +RECTANGLE 0 1076 notvisible +RECTANGLE 0 1077 notvisible +RECTANGLE 0 1078 notvisible +RECTANGLE 0 1079 notvisible +RECTANGLE 0 1080 129 16 140 51 +RECTANGLE 0 1081 126 16 137 51 +RECTANGLE 0 1082 123 16 134 52 +RECTANGLE 0 1083 119 16 131 52 +RECTANGLE 0 1084 116 16 128 53 +RECTANGLE 0 1085 113 16 125 53 +RECTANGLE 0 1086 110 16 122 54 +RECTANGLE 0 1087 106 15 119 54 +RECTANGLE 0 1088 102 15 115 55 +RECTANGLE 0 1089 99 15 112 55 +RECTANGLE 0 1090 95 15 108 56 +RECTANGLE 0 1091 91 15 104 56 +RECTANGLE 0 1092 86 15 100 57 +RECTANGLE 0 1093 82 15 96 58 +RECTANGLE 0 1094 78 14 92 58 +RECTANGLE 0 1095 73 14 88 59 +RECTANGLE 0 1096 69 14 84 60 +RECTANGLE 0 1097 64 14 79 60 +RECTANGLE 0 1098 60 14 75 61 +RECTANGLE 0 1099 54 14 70 62 +RECTANGLE 0 1100 49 13 65 63 +RECTANGLE 0 1101 44 13 60 63 +RECTANGLE 0 1102 38 13 55 64 +RECTANGLE 0 1103 32 13 49 65 +RECTANGLE 0 1104 26 13 43 66 +RECTANGLE 0 1105 20 12 38 67 +RECTANGLE 0 1106 14 12 32 68 +RECTANGLE 0 1107 7 12 26 69 +RECTANGLE 0 1108 0 12 19 70 +RECTANGLE 0 1109 0 11 12 71 +RECTANGLE 0 1110 0 11 5 72 +RECTANGLE 0 1111 notvisible +RECTANGLE 0 1112 notvisible +RECTANGLE 0 1113 notvisible +RECTANGLE 0 1114 notvisible +RECTANGLE 0 1115 notvisible +RECTANGLE 0 1116 126 17 137 50 +RECTANGLE 0 1117 123 16 134 51 +RECTANGLE 0 1118 120 16 131 51 +RECTANGLE 0 1119 117 16 128 52 +RECTANGLE 0 1120 114 16 125 52 +RECTANGLE 0 1121 110 16 122 52 +RECTANGLE 0 1122 107 16 119 53 +RECTANGLE 0 1123 103 16 115 53 +RECTANGLE 0 1124 100 16 112 54 +RECTANGLE 0 1125 96 15 109 54 +RECTANGLE 0 1126 92 15 105 55 +RECTANGLE 0 1127 88 15 101 56 +RECTANGLE 0 1128 84 15 97 56 +RECTANGLE 0 1129 80 15 94 57 +RECTANGLE 0 1130 76 15 90 57 +RECTANGLE 0 1131 72 15 86 58 +RECTANGLE 0 1132 67 14 81 59 +RECTANGLE 0 1133 62 14 77 59 +RECTANGLE 0 1134 58 14 73 60 +RECTANGLE 0 1135 53 14 68 61 +RECTANGLE 0 1136 48 14 63 61 +RECTANGLE 0 1137 42 14 58 62 +RECTANGLE 0 1138 37 13 53 63 +RECTANGLE 0 1139 32 13 48 64 +RECTANGLE 0 1140 26 13 43 65 +RECTANGLE 0 1141 20 13 37 65 +RECTANGLE 0 1142 14 13 31 66 +RECTANGLE 0 1143 7 12 25 67 +RECTANGLE 0 1144 0 12 18 68 +RECTANGLE 0 1145 0 12 12 69 +RECTANGLE 0 1146 0 12 5 70 +RECTANGLE 0 1147 notvisible +RECTANGLE 0 1148 notvisible +RECTANGLE 0 1149 notvisible +RECTANGLE 0 1150 notvisible +RECTANGLE 0 1151 notvisible +RECTANGLE 0 1152 123 17 134 50 +RECTANGLE 0 1153 120 17 131 50 +RECTANGLE 0 1154 117 17 128 50 +RECTANGLE 0 1155 114 16 125 51 +RECTANGLE 0 1156 111 16 122 51 +RECTANGLE 0 1157 108 16 119 52 +RECTANGLE 0 1158 104 16 116 52 +RECTANGLE 0 1159 101 16 113 53 +RECTANGLE 0 1160 97 16 109 53 +RECTANGLE 0 1161 94 16 106 54 +RECTANGLE 0 1162 90 16 102 54 +RECTANGLE 0 1163 86 16 99 55 +RECTANGLE 0 1164 82 15 95 55 +RECTANGLE 0 1165 78 15 91 56 +RECTANGLE 0 1166 74 15 87 56 +RECTANGLE 0 1167 70 15 84 57 +RECTANGLE 0 1168 65 15 79 58 +RECTANGLE 0 1169 61 15 75 58 +RECTANGLE 0 1170 56 15 70 59 +RECTANGLE 0 1171 51 14 66 60 +RECTANGLE 0 1172 46 14 61 60 +RECTANGLE 0 1173 42 14 57 61 +RECTANGLE 0 1174 36 14 52 62 +RECTANGLE 0 1175 31 14 47 62 +RECTANGLE 0 1176 25 13 41 63 +RECTANGLE 0 1177 19 13 36 64 +RECTANGLE 0 1178 13 13 30 65 +RECTANGLE 0 1179 7 13 24 66 +RECTANGLE 0 1180 0 13 18 67 +RECTANGLE 0 1181 0 12 12 68 +RECTANGLE 0 1182 0 12 5 69 +RECTANGLE 0 1183 notvisible +RECTANGLE 0 1184 notvisible +RECTANGLE 0 1185 notvisible +RECTANGLE 0 1186 notvisible +RECTANGLE 0 1187 notvisible +RECTANGLE 0 1188 120 17 130 49 +RECTANGLE 0 1189 117 17 127 49 +RECTANGLE 0 1190 114 17 125 50 +RECTANGLE 0 1191 111 17 122 50 +RECTANGLE 0 1192 108 17 119 51 +RECTANGLE 0 1193 105 16 116 51 +RECTANGLE 0 1194 102 16 113 51 +RECTANGLE 0 1195 98 16 109 52 +RECTANGLE 0 1196 95 16 107 52 +RECTANGLE 0 1197 91 16 103 53 +RECTANGLE 0 1198 88 16 100 53 +RECTANGLE 0 1199 84 16 96 54 +RECTANGLE 0 1200 80 16 92 54 +RECTANGLE 0 1201 76 16 89 55 +RECTANGLE 0 1202 72 15 85 55 +RECTANGLE 0 1203 68 15 81 56 +RECTANGLE 0 1204 64 15 77 57 +RECTANGLE 0 1205 59 15 73 57 +RECTANGLE 0 1206 55 15 69 58 +RECTANGLE 0 1207 50 15 64 58 +RECTANGLE 0 1208 46 15 60 59 +RECTANGLE 0 1209 40 14 55 60 +RECTANGLE 0 1210 35 14 50 60 +RECTANGLE 0 1211 30 14 45 61 +RECTANGLE 0 1212 24 14 40 62 +RECTANGLE 0 1213 19 14 35 63 +RECTANGLE 0 1214 13 13 29 63 +RECTANGLE 0 1215 7 13 24 64 +RECTANGLE 0 1216 1 13 18 65 +RECTANGLE 0 1217 0 13 12 66 +RECTANGLE 0 1218 0 13 6 67 +RECTANGLE 0 1219 notvisible +RECTANGLE 0 1220 notvisible +RECTANGLE 0 1221 notvisible +RECTANGLE 0 1222 notvisible +RECTANGLE 0 1223 notvisible +RECTANGLE 0 1224 117 17 127 48 +RECTANGLE 0 1225 115 17 125 49 +RECTANGLE 0 1226 112 17 122 49 +RECTANGLE 0 1227 108 17 119 50 +RECTANGLE 0 1228 105 17 116 50 +RECTANGLE 0 1229 102 17 113 50 +RECTANGLE 0 1230 99 17 110 51 +RECTANGLE 0 1231 96 16 107 51 +RECTANGLE 0 1232 93 16 104 52 +RECTANGLE 0 1233 89 16 101 52 +RECTANGLE 0 1234 85 16 97 53 +RECTANGLE 0 1235 82 16 94 53 +RECTANGLE 0 1236 78 16 90 54 +RECTANGLE 0 1237 75 16 87 54 +RECTANGLE 0 1238 70 16 83 55 +RECTANGLE 0 1239 66 16 79 55 +RECTANGLE 0 1240 62 15 75 56 +RECTANGLE 0 1241 58 15 71 56 +RECTANGLE 0 1242 54 15 67 57 +RECTANGLE 0 1243 49 15 63 57 +RECTANGLE 0 1244 44 15 58 58 +RECTANGLE 0 1245 40 15 54 59 +RECTANGLE 0 1246 35 15 49 59 +RECTANGLE 0 1247 29 14 44 60 +RECTANGLE 0 1248 24 14 39 61 +RECTANGLE 0 1249 19 14 34 61 +RECTANGLE 0 1250 13 14 29 62 +RECTANGLE 0 1251 7 14 23 63 +RECTANGLE 0 1252 1 14 17 64 +RECTANGLE 0 1253 0 13 12 65 +RECTANGLE 0 1254 0 13 6 65 +RECTANGLE 0 1255 0 13 0 66 +RECTANGLE 0 1256 notvisible +RECTANGLE 0 1257 notvisible +RECTANGLE 0 1258 notvisible +RECTANGLE 0 1259 notvisible +RECTANGLE 0 1260 115 17 125 48 +RECTANGLE 0 1261 112 17 122 48 +RECTANGLE 0 1262 109 17 119 49 +RECTANGLE 0 1263 106 17 116 49 +RECTANGLE 0 1264 103 17 113 49 +RECTANGLE 0 1265 100 17 111 50 +RECTANGLE 0 1266 97 17 108 50 +RECTANGLE 0 1267 94 17 105 51 +RECTANGLE 0 1268 91 17 102 51 +RECTANGLE 0 1269 87 16 98 51 +RECTANGLE 0 1270 84 16 95 52 +RECTANGLE 0 1271 80 16 92 52 +RECTANGLE 0 1272 76 16 88 53 +RECTANGLE 0 1273 73 16 85 53 +RECTANGLE 0 1274 69 16 81 54 +RECTANGLE 0 1275 65 16 77 54 +RECTANGLE 0 1276 61 16 74 55 +RECTANGLE 0 1277 56 16 69 55 +RECTANGLE 0 1278 52 15 65 56 +RECTANGLE 0 1279 48 15 61 57 +RECTANGLE 0 1280 43 15 57 57 +RECTANGLE 0 1281 39 15 53 58 +RECTANGLE 0 1282 34 15 48 58 +RECTANGLE 0 1283 29 15 43 59 +RECTANGLE 0 1284 24 15 39 60 +RECTANGLE 0 1285 18 14 33 60 +RECTANGLE 0 1286 13 14 28 61 +RECTANGLE 0 1287 8 14 23 62 +RECTANGLE 0 1288 2 14 18 62 +RECTANGLE 0 1289 0 14 12 63 +RECTANGLE 0 1290 0 14 6 64 +RECTANGLE 0 1291 0 13 0 65 +RECTANGLE 0 1292 notvisible +RECTANGLE 0 1293 notvisible +RECTANGLE 0 1294 notvisible +RECTANGLE 0 1295 notvisible +RECTANGLE 0 1296 112 17 122 47 +RECTANGLE 0 1297 110 17 120 48 +RECTANGLE 0 1298 107 17 117 48 +RECTANGLE 0 1299 104 17 114 48 +RECTANGLE 0 1300 101 17 111 49 +RECTANGLE 0 1301 98 17 108 49 +RECTANGLE 0 1302 95 17 106 50 +RECTANGLE 0 1303 92 17 103 50 +RECTANGLE 0 1304 88 17 99 50 +RECTANGLE 0 1305 85 17 96 51 +RECTANGLE 0 1306 82 17 93 51 +RECTANGLE 0 1307 78 17 89 52 +RECTANGLE 0 1308 74 16 86 52 +RECTANGLE 0 1309 71 16 83 53 +RECTANGLE 0 1310 67 16 79 53 +RECTANGLE 0 1311 63 16 75 54 +RECTANGLE 0 1312 59 16 71 54 +RECTANGLE 0 1313 55 16 68 55 +RECTANGLE 0 1314 51 16 64 55 +RECTANGLE 0 1315 47 16 60 56 +RECTANGLE 0 1316 42 15 55 56 +RECTANGLE 0 1317 38 15 51 57 +RECTANGLE 0 1318 33 15 47 57 +RECTANGLE 0 1319 28 15 42 58 +RECTANGLE 0 1320 23 15 37 59 +RECTANGLE 0 1321 18 15 32 59 +RECTANGLE 0 1322 13 15 28 60 +RECTANGLE 0 1323 8 14 23 61 +RECTANGLE 0 1324 2 14 17 61 +RECTANGLE 0 1325 0 14 11 62 +RECTANGLE 0 1326 0 14 6 63 +RECTANGLE 0 1327 0 14 0 63 +RECTANGLE 0 1328 notvisible +RECTANGLE 0 1329 notvisible +RECTANGLE 0 1330 notvisible +RECTANGLE 0 1331 notvisible +RECTANGLE 1 0 notvisible +RECTANGLE 1 1 notvisible +RECTANGLE 1 2 notvisible +RECTANGLE 1 3 notvisible +RECTANGLE 1 4 notvisible +RECTANGLE 1 5 notvisible +RECTANGLE 1 6 notvisible +RECTANGLE 1 7 notvisible +RECTANGLE 1 8 notvisible +RECTANGLE 1 9 notvisible +RECTANGLE 1 10 notvisible +RECTANGLE 1 11 notvisible +RECTANGLE 1 12 notvisible +RECTANGLE 1 13 notvisible +RECTANGLE 1 14 notvisible +RECTANGLE 1 15 notvisible +RECTANGLE 1 16 notvisible +RECTANGLE 1 17 notvisible +RECTANGLE 1 18 notvisible +RECTANGLE 1 19 notvisible +RECTANGLE 1 20 notvisible +RECTANGLE 1 21 notvisible +RECTANGLE 1 22 notvisible +RECTANGLE 1 23 notvisible +RECTANGLE 1 24 notvisible +RECTANGLE 1 25 notvisible +RECTANGLE 1 26 notvisible +RECTANGLE 1 27 notvisible +RECTANGLE 1 28 notvisible +RECTANGLE 1 29 notvisible +RECTANGLE 1 30 notvisible +RECTANGLE 1 31 notvisible +RECTANGLE 1 32 notvisible +RECTANGLE 1 33 notvisible +RECTANGLE 1 34 notvisible +RECTANGLE 1 35 notvisible +RECTANGLE 1 36 notvisible +RECTANGLE 1 37 notvisible +RECTANGLE 1 38 notvisible +RECTANGLE 1 39 notvisible +RECTANGLE 1 40 notvisible +RECTANGLE 1 41 notvisible +RECTANGLE 1 42 notvisible +RECTANGLE 1 43 notvisible +RECTANGLE 1 44 notvisible +RECTANGLE 1 45 notvisible +RECTANGLE 1 46 notvisible +RECTANGLE 1 47 notvisible +RECTANGLE 1 48 notvisible +RECTANGLE 1 49 notvisible +RECTANGLE 1 50 notvisible +RECTANGLE 1 51 notvisible +RECTANGLE 1 52 notvisible +RECTANGLE 1 53 notvisible +RECTANGLE 1 54 notvisible +RECTANGLE 1 55 notvisible +RECTANGLE 1 56 notvisible +RECTANGLE 1 57 notvisible +RECTANGLE 1 58 notvisible +RECTANGLE 1 59 notvisible +RECTANGLE 1 60 notvisible +RECTANGLE 1 61 notvisible +RECTANGLE 1 62 notvisible +RECTANGLE 1 63 notvisible +RECTANGLE 1 64 notvisible +RECTANGLE 1 65 notvisible +RECTANGLE 1 66 notvisible +RECTANGLE 1 67 notvisible +RECTANGLE 1 68 notvisible +RECTANGLE 1 69 notvisible +RECTANGLE 1 70 notvisible +RECTANGLE 1 71 notvisible +RECTANGLE 1 72 notvisible +RECTANGLE 1 73 notvisible +RECTANGLE 1 74 notvisible +RECTANGLE 1 75 notvisible +RECTANGLE 1 76 notvisible +RECTANGLE 1 77 notvisible +RECTANGLE 1 78 notvisible +RECTANGLE 1 79 notvisible +RECTANGLE 1 80 notvisible +RECTANGLE 1 81 notvisible +RECTANGLE 1 82 notvisible +RECTANGLE 1 83 notvisible +RECTANGLE 1 84 notvisible +RECTANGLE 1 85 notvisible +RECTANGLE 1 86 notvisible +RECTANGLE 1 87 notvisible +RECTANGLE 1 88 notvisible +RECTANGLE 1 89 notvisible +RECTANGLE 1 90 notvisible +RECTANGLE 1 91 notvisible +RECTANGLE 1 92 notvisible +RECTANGLE 1 93 notvisible +RECTANGLE 1 94 notvisible +RECTANGLE 1 95 notvisible +RECTANGLE 1 96 notvisible +RECTANGLE 1 97 notvisible +RECTANGLE 1 98 notvisible +RECTANGLE 1 99 notvisible +RECTANGLE 1 100 notvisible +RECTANGLE 1 101 notvisible +RECTANGLE 1 102 notvisible +RECTANGLE 1 103 notvisible +RECTANGLE 1 104 notvisible +RECTANGLE 1 105 notvisible +RECTANGLE 1 106 notvisible +RECTANGLE 1 107 notvisible +RECTANGLE 1 108 notvisible +RECTANGLE 1 109 notvisible +RECTANGLE 1 110 notvisible +RECTANGLE 1 111 notvisible +RECTANGLE 1 112 notvisible +RECTANGLE 1 113 notvisible +RECTANGLE 1 114 notvisible +RECTANGLE 1 115 notvisible +RECTANGLE 1 116 notvisible +RECTANGLE 1 117 notvisible +RECTANGLE 1 118 notvisible +RECTANGLE 1 119 notvisible +RECTANGLE 1 120 notvisible +RECTANGLE 1 121 notvisible +RECTANGLE 1 122 notvisible +RECTANGLE 1 123 notvisible +RECTANGLE 1 124 notvisible +RECTANGLE 1 125 notvisible +RECTANGLE 1 126 notvisible +RECTANGLE 1 127 notvisible +RECTANGLE 1 128 notvisible +RECTANGLE 1 129 notvisible +RECTANGLE 1 130 notvisible +RECTANGLE 1 131 notvisible +RECTANGLE 1 132 notvisible +RECTANGLE 1 133 notvisible +RECTANGLE 1 134 notvisible +RECTANGLE 1 135 notvisible +RECTANGLE 1 136 notvisible +RECTANGLE 1 137 notvisible +RECTANGLE 1 138 notvisible +RECTANGLE 1 139 notvisible +RECTANGLE 1 140 notvisible +RECTANGLE 1 141 notvisible +RECTANGLE 1 142 notvisible +RECTANGLE 1 143 notvisible +RECTANGLE 1 144 notvisible +RECTANGLE 1 145 notvisible +RECTANGLE 1 146 notvisible +RECTANGLE 1 147 notvisible +RECTANGLE 1 148 notvisible +RECTANGLE 1 149 notvisible +RECTANGLE 1 150 notvisible +RECTANGLE 1 151 notvisible +RECTANGLE 1 152 notvisible +RECTANGLE 1 153 notvisible +RECTANGLE 1 154 notvisible +RECTANGLE 1 155 notvisible +RECTANGLE 1 156 notvisible +RECTANGLE 1 157 notvisible +RECTANGLE 1 158 notvisible +RECTANGLE 1 159 notvisible +RECTANGLE 1 160 notvisible +RECTANGLE 1 161 notvisible +RECTANGLE 1 162 notvisible +RECTANGLE 1 163 notvisible +RECTANGLE 1 164 notvisible +RECTANGLE 1 165 notvisible +RECTANGLE 1 166 notvisible +RECTANGLE 1 167 notvisible +RECTANGLE 1 168 notvisible +RECTANGLE 1 169 notvisible +RECTANGLE 1 170 notvisible +RECTANGLE 1 171 notvisible +RECTANGLE 1 172 notvisible +RECTANGLE 1 173 notvisible +RECTANGLE 1 174 notvisible +RECTANGLE 1 175 notvisible +RECTANGLE 1 176 notvisible +RECTANGLE 1 177 notvisible +RECTANGLE 1 178 notvisible +RECTANGLE 1 179 notvisible +RECTANGLE 1 180 notvisible +RECTANGLE 1 181 notvisible +RECTANGLE 1 182 notvisible +RECTANGLE 1 183 notvisible +RECTANGLE 1 184 notvisible +RECTANGLE 1 185 notvisible +RECTANGLE 1 186 notvisible +RECTANGLE 1 187 notvisible +RECTANGLE 1 188 notvisible +RECTANGLE 1 189 notvisible +RECTANGLE 1 190 notvisible +RECTANGLE 1 191 notvisible +RECTANGLE 1 192 notvisible +RECTANGLE 1 193 notvisible +RECTANGLE 1 194 notvisible +RECTANGLE 1 195 notvisible +RECTANGLE 1 196 notvisible +RECTANGLE 1 197 notvisible +RECTANGLE 1 198 notvisible +RECTANGLE 1 199 notvisible +RECTANGLE 1 200 notvisible +RECTANGLE 1 201 notvisible +RECTANGLE 1 202 notvisible +RECTANGLE 1 203 notvisible +RECTANGLE 1 204 notvisible +RECTANGLE 1 205 notvisible +RECTANGLE 1 206 notvisible +RECTANGLE 1 207 notvisible +RECTANGLE 1 208 notvisible +RECTANGLE 1 209 notvisible +RECTANGLE 1 210 notvisible +RECTANGLE 1 211 notvisible +RECTANGLE 1 212 notvisible +RECTANGLE 1 213 notvisible +RECTANGLE 1 214 notvisible +RECTANGLE 1 215 notvisible +RECTANGLE 1 216 notvisible +RECTANGLE 1 217 notvisible +RECTANGLE 1 218 notvisible +RECTANGLE 1 219 notvisible +RECTANGLE 1 220 notvisible +RECTANGLE 1 221 notvisible +RECTANGLE 1 222 notvisible +RECTANGLE 1 223 notvisible +RECTANGLE 1 224 notvisible +RECTANGLE 1 225 notvisible +RECTANGLE 1 226 notvisible +RECTANGLE 1 227 notvisible +RECTANGLE 1 228 notvisible +RECTANGLE 1 229 notvisible +RECTANGLE 1 230 notvisible +RECTANGLE 1 231 notvisible +RECTANGLE 1 232 notvisible +RECTANGLE 1 233 notvisible +RECTANGLE 1 234 notvisible +RECTANGLE 1 235 0 0 79 119 +RECTANGLE 1 236 0 0 2 119 +RECTANGLE 1 237 notvisible +RECTANGLE 1 238 notvisible +RECTANGLE 1 239 notvisible +RECTANGLE 1 240 notvisible +RECTANGLE 1 241 notvisible +RECTANGLE 1 242 notvisible +RECTANGLE 1 243 notvisible +RECTANGLE 1 244 notvisible +RECTANGLE 1 245 notvisible +RECTANGLE 1 246 notvisible +RECTANGLE 1 247 notvisible +RECTANGLE 1 248 notvisible +RECTANGLE 1 249 notvisible +RECTANGLE 1 250 notvisible +RECTANGLE 1 251 notvisible +RECTANGLE 1 252 notvisible +RECTANGLE 1 253 notvisible +RECTANGLE 1 254 notvisible +RECTANGLE 1 255 notvisible +RECTANGLE 1 256 notvisible +RECTANGLE 1 257 notvisible +RECTANGLE 1 258 notvisible +RECTANGLE 1 259 notvisible +RECTANGLE 1 260 notvisible +RECTANGLE 1 261 notvisible +RECTANGLE 1 262 notvisible +RECTANGLE 1 263 notvisible +RECTANGLE 1 264 notvisible +RECTANGLE 1 265 notvisible +RECTANGLE 1 266 notvisible +RECTANGLE 1 267 0 0 159 119 +RECTANGLE 1 268 43 0 159 119 +RECTANGLE 1 269 5 0 159 119 +RECTANGLE 1 270 0 0 118 119 +RECTANGLE 1 271 0 0 69 119 +RECTANGLE 1 272 0 0 26 119 +RECTANGLE 1 273 notvisible +RECTANGLE 1 274 notvisible +RECTANGLE 1 275 notvisible +RECTANGLE 1 276 notvisible +RECTANGLE 1 277 notvisible +RECTANGLE 1 278 notvisible +RECTANGLE 1 279 notvisible +RECTANGLE 1 280 notvisible +RECTANGLE 1 281 notvisible +RECTANGLE 1 282 notvisible +RECTANGLE 1 283 notvisible +RECTANGLE 1 284 notvisible +RECTANGLE 1 285 notvisible +RECTANGLE 1 286 notvisible +RECTANGLE 1 287 notvisible +RECTANGLE 1 288 notvisible +RECTANGLE 1 289 notvisible +RECTANGLE 1 290 notvisible +RECTANGLE 1 291 notvisible +RECTANGLE 1 292 notvisible +RECTANGLE 1 293 notvisible +RECTANGLE 1 294 notvisible +RECTANGLE 1 295 notvisible +RECTANGLE 1 296 notvisible +RECTANGLE 1 297 notvisible +RECTANGLE 1 298 notvisible +RECTANGLE 1 299 notvisible +RECTANGLE 1 300 notvisible +RECTANGLE 1 301 notvisible +RECTANGLE 1 302 notvisible +RECTANGLE 1 303 119 0 159 119 +RECTANGLE 1 304 76 0 159 119 +RECTANGLE 1 305 39 0 154 119 +RECTANGLE 1 306 6 0 113 119 +RECTANGLE 1 307 0 0 77 119 +RECTANGLE 1 308 0 0 44 119 +RECTANGLE 1 309 0 0 14 119 +RECTANGLE 1 310 notvisible +RECTANGLE 1 311 notvisible +RECTANGLE 1 312 notvisible +RECTANGLE 1 313 notvisible +RECTANGLE 1 314 notvisible +RECTANGLE 1 315 notvisible +RECTANGLE 1 316 notvisible +RECTANGLE 1 317 notvisible +RECTANGLE 1 318 notvisible +RECTANGLE 1 319 notvisible +RECTANGLE 1 320 notvisible +RECTANGLE 1 321 notvisible +RECTANGLE 1 322 notvisible +RECTANGLE 1 323 notvisible +RECTANGLE 1 324 notvisible +RECTANGLE 1 325 notvisible +RECTANGLE 1 326 notvisible +RECTANGLE 1 327 notvisible +RECTANGLE 1 328 notvisible +RECTANGLE 1 329 notvisible +RECTANGLE 1 330 notvisible +RECTANGLE 1 331 notvisible +RECTANGLE 1 332 notvisible +RECTANGLE 1 333 notvisible +RECTANGLE 1 334 notvisible +RECTANGLE 1 335 notvisible +RECTANGLE 1 336 notvisible +RECTANGLE 1 337 notvisible +RECTANGLE 1 338 157 0 159 119 +RECTANGLE 1 339 120 0 159 119 +RECTANGLE 1 340 86 0 159 119 +RECTANGLE 1 341 56 0 144 119 +RECTANGLE 1 342 28 0 112 119 +RECTANGLE 1 343 2 0 83 119 +RECTANGLE 1 344 0 0 56 119 +RECTANGLE 1 345 0 0 31 119 +RECTANGLE 1 346 0 0 8 119 +RECTANGLE 1 347 notvisible +RECTANGLE 1 348 notvisible +RECTANGLE 1 349 notvisible +RECTANGLE 1 350 notvisible +RECTANGLE 1 351 notvisible +RECTANGLE 1 352 notvisible +RECTANGLE 1 353 notvisible +RECTANGLE 1 354 notvisible +RECTANGLE 1 355 notvisible +RECTANGLE 1 356 notvisible +RECTANGLE 1 357 notvisible +RECTANGLE 1 358 notvisible +RECTANGLE 1 359 notvisible +RECTANGLE 1 360 notvisible +RECTANGLE 1 361 notvisible +RECTANGLE 1 362 notvisible +RECTANGLE 1 363 notvisible +RECTANGLE 1 364 notvisible +RECTANGLE 1 365 notvisible +RECTANGLE 1 366 notvisible +RECTANGLE 1 367 notvisible +RECTANGLE 1 368 notvisible +RECTANGLE 1 369 notvisible +RECTANGLE 1 370 notvisible +RECTANGLE 1 371 notvisible +RECTANGLE 1 372 notvisible +RECTANGLE 1 373 notvisible +RECTANGLE 1 374 149 0 159 119 +RECTANGLE 1 375 119 0 159 119 +RECTANGLE 1 376 91 0 159 119 +RECTANGLE 1 377 66 0 138 119 +RECTANGLE 1 378 42 0 111 119 +RECTANGLE 1 379 20 0 87 119 +RECTANGLE 1 380 0 0 64 119 +RECTANGLE 1 381 0 0 43 119 +RECTANGLE 1 382 0 0 23 119 +RECTANGLE 1 383 0 0 4 119 +RECTANGLE 1 384 notvisible +RECTANGLE 1 385 notvisible +RECTANGLE 1 386 notvisible +RECTANGLE 1 387 notvisible +RECTANGLE 1 388 notvisible +RECTANGLE 1 389 notvisible +RECTANGLE 1 390 notvisible +RECTANGLE 1 391 notvisible +RECTANGLE 1 392 notvisible +RECTANGLE 1 393 notvisible +RECTANGLE 1 394 notvisible +RECTANGLE 1 395 notvisible +RECTANGLE 1 396 notvisible +RECTANGLE 1 397 notvisible +RECTANGLE 1 398 notvisible +RECTANGLE 1 399 notvisible +RECTANGLE 1 400 notvisible +RECTANGLE 1 401 notvisible +RECTANGLE 1 402 notvisible +RECTANGLE 1 403 notvisible +RECTANGLE 1 404 notvisible +RECTANGLE 1 405 notvisible +RECTANGLE 1 406 notvisible +RECTANGLE 1 407 notvisible +RECTANGLE 1 408 notvisible +RECTANGLE 1 409 notvisible +RECTANGLE 1 410 143 0 159 119 +RECTANGLE 1 411 118 0 159 119 +RECTANGLE 1 412 95 0 158 119 +RECTANGLE 1 413 73 0 134 119 +RECTANGLE 1 414 52 0 111 119 +RECTANGLE 1 415 33 0 90 119 +RECTANGLE 1 416 14 0 70 119 +RECTANGLE 1 417 0 0 52 119 +RECTANGLE 1 418 0 0 34 119 +RECTANGLE 1 419 0 0 17 119 +RECTANGLE 1 420 0 0 2 119 +RECTANGLE 1 421 notvisible +RECTANGLE 1 422 notvisible +RECTANGLE 1 423 notvisible +RECTANGLE 1 424 notvisible +RECTANGLE 1 425 notvisible +RECTANGLE 1 426 notvisible +RECTANGLE 1 427 notvisible +RECTANGLE 1 428 notvisible +RECTANGLE 1 429 notvisible +RECTANGLE 1 430 notvisible +RECTANGLE 1 431 notvisible +RECTANGLE 1 432 notvisible +RECTANGLE 1 433 notvisible +RECTANGLE 1 434 notvisible +RECTANGLE 1 435 notvisible +RECTANGLE 1 436 notvisible +RECTANGLE 1 437 notvisible +RECTANGLE 1 438 notvisible +RECTANGLE 1 439 notvisible +RECTANGLE 1 440 notvisible +RECTANGLE 1 441 notvisible +RECTANGLE 1 442 notvisible +RECTANGLE 1 443 notvisible +RECTANGLE 1 444 notvisible +RECTANGLE 1 445 notvisible +RECTANGLE 1 446 140 0 159 119 +RECTANGLE 1 447 118 0 159 119 +RECTANGLE 1 448 97 0 151 119 +RECTANGLE 1 449 78 0 131 119 +RECTANGLE 1 450 60 0 111 119 +RECTANGLE 1 451 43 0 93 119 +RECTANGLE 1 452 26 0 75 119 +RECTANGLE 1 453 11 0 59 119 +RECTANGLE 1 454 0 0 43 119 +RECTANGLE 1 455 0 0 27 119 +RECTANGLE 1 456 0 0 13 119 +RECTANGLE 1 457 0 0 0 119 +RECTANGLE 1 458 notvisible +RECTANGLE 1 459 notvisible +RECTANGLE 1 460 notvisible +RECTANGLE 1 461 notvisible +RECTANGLE 1 462 notvisible +RECTANGLE 1 463 notvisible +RECTANGLE 1 464 notvisible +RECTANGLE 1 465 notvisible +RECTANGLE 1 466 notvisible +RECTANGLE 1 467 notvisible +RECTANGLE 1 468 notvisible +RECTANGLE 1 469 notvisible +RECTANGLE 1 470 notvisible +RECTANGLE 1 471 notvisible +RECTANGLE 1 472 notvisible +RECTANGLE 1 473 notvisible +RECTANGLE 1 474 notvisible +RECTANGLE 1 475 notvisible +RECTANGLE 1 476 notvisible +RECTANGLE 1 477 notvisible +RECTANGLE 1 478 notvisible +RECTANGLE 1 479 notvisible +RECTANGLE 1 480 notvisible +RECTANGLE 1 481 156 0 159 119 +RECTANGLE 1 482 136 0 159 119 +RECTANGLE 1 483 117 0 159 119 +RECTANGLE 1 484 99 0 147 119 +RECTANGLE 1 485 82 0 128 119 +RECTANGLE 1 486 66 0 111 119 +RECTANGLE 1 487 50 0 94 119 +RECTANGLE 1 488 35 0 79 119 +RECTANGLE 1 489 21 0 64 119 +RECTANGLE 1 490 8 0 50 119 +RECTANGLE 1 491 0 0 36 119 +RECTANGLE 1 492 0 0 23 119 +RECTANGLE 1 493 0 0 10 117 +RECTANGLE 1 494 notvisible +RECTANGLE 1 495 notvisible +RECTANGLE 1 496 notvisible +RECTANGLE 1 497 notvisible +RECTANGLE 1 498 notvisible +RECTANGLE 1 499 notvisible +RECTANGLE 1 500 notvisible +RECTANGLE 1 501 notvisible +RECTANGLE 1 502 notvisible +RECTANGLE 1 503 notvisible +RECTANGLE 1 504 notvisible +RECTANGLE 1 505 notvisible +RECTANGLE 1 506 notvisible +RECTANGLE 1 507 notvisible +RECTANGLE 1 508 notvisible +RECTANGLE 1 509 notvisible +RECTANGLE 1 510 notvisible +RECTANGLE 1 511 notvisible +RECTANGLE 1 512 notvisible +RECTANGLE 1 513 notvisible +RECTANGLE 1 514 notvisible +RECTANGLE 1 515 notvisible +RECTANGLE 1 516 notvisible +RECTANGLE 1 517 152 0 159 119 +RECTANGLE 1 518 134 0 159 119 +RECTANGLE 1 519 117 0 159 119 +RECTANGLE 1 520 101 0 143 119 +RECTANGLE 1 521 85 0 126 119 +RECTANGLE 1 522 70 0 111 119 +RECTANGLE 1 523 56 0 96 118 +RECTANGLE 1 524 43 0 82 116 +RECTANGLE 1 525 30 0 68 114 +RECTANGLE 1 526 17 0 55 112 +RECTANGLE 1 527 6 0 43 110 +RECTANGLE 1 528 0 0 30 108 +RECTANGLE 1 529 0 0 19 107 +RECTANGLE 1 530 0 0 8 105 +RECTANGLE 1 531 notvisible +RECTANGLE 1 532 notvisible +RECTANGLE 1 533 notvisible +RECTANGLE 1 534 notvisible +RECTANGLE 1 535 notvisible +RECTANGLE 1 536 notvisible +RECTANGLE 1 537 notvisible +RECTANGLE 1 538 notvisible +RECTANGLE 1 539 notvisible +RECTANGLE 1 540 notvisible +RECTANGLE 1 541 notvisible +RECTANGLE 1 542 notvisible +RECTANGLE 1 543 notvisible +RECTANGLE 1 544 notvisible +RECTANGLE 1 545 notvisible +RECTANGLE 1 546 notvisible +RECTANGLE 1 547 notvisible +RECTANGLE 1 548 notvisible +RECTANGLE 1 549 notvisible +RECTANGLE 1 550 notvisible +RECTANGLE 1 551 notvisible +RECTANGLE 1 552 notvisible +RECTANGLE 1 553 147 0 159 119 +RECTANGLE 1 554 131 0 159 117 +RECTANGLE 1 555 116 0 155 115 +RECTANGLE 1 556 102 0 140 113 +RECTANGLE 1 557 88 0 125 111 +RECTANGLE 1 558 74 0 111 109 +RECTANGLE 1 559 61 0 97 107 +RECTANGLE 1 560 49 0 85 106 +RECTANGLE 1 561 37 0 72 104 +RECTANGLE 1 562 26 0 60 103 +RECTANGLE 1 563 14 0 48 101 +RECTANGLE 1 564 4 0 37 100 +RECTANGLE 1 565 0 0 26 99 +RECTANGLE 1 566 0 0 16 97 +RECTANGLE 1 567 0 0 6 96 +RECTANGLE 1 568 notvisible +RECTANGLE 1 569 notvisible +RECTANGLE 1 570 notvisible +RECTANGLE 1 571 notvisible +RECTANGLE 1 572 notvisible +RECTANGLE 1 573 notvisible +RECTANGLE 1 574 notvisible +RECTANGLE 1 575 notvisible +RECTANGLE 1 576 notvisible +RECTANGLE 1 577 notvisible +RECTANGLE 1 578 notvisible +RECTANGLE 1 579 notvisible +RECTANGLE 1 580 notvisible +RECTANGLE 1 581 notvisible +RECTANGLE 1 582 notvisible +RECTANGLE 1 583 notvisible +RECTANGLE 1 584 notvisible +RECTANGLE 1 585 notvisible +RECTANGLE 1 586 notvisible +RECTANGLE 1 587 notvisible +RECTANGLE 1 588 notvisible +RECTANGLE 1 589 144 0 159 108 +RECTANGLE 1 590 130 0 159 107 +RECTANGLE 1 591 116 0 151 105 +RECTANGLE 1 592 102 0 137 103 +RECTANGLE 1 593 90 0 124 102 +RECTANGLE 1 594 77 0 111 100 +RECTANGLE 1 595 65 0 98 99 +RECTANGLE 1 596 54 0 87 98 +RECTANGLE 1 597 43 0 75 96 +RECTANGLE 1 598 32 0 64 95 +RECTANGLE 1 599 22 0 53 94 +RECTANGLE 1 600 12 0 43 93 +RECTANGLE 1 601 2 0 32 92 +RECTANGLE 1 602 0 0 23 90 +RECTANGLE 1 603 0 0 13 89 +RECTANGLE 1 604 0 0 4 88 +RECTANGLE 1 605 notvisible +RECTANGLE 1 606 notvisible +RECTANGLE 1 607 notvisible +RECTANGLE 1 608 notvisible +RECTANGLE 1 609 notvisible +RECTANGLE 1 610 notvisible +RECTANGLE 1 611 notvisible +RECTANGLE 1 612 notvisible +RECTANGLE 1 613 notvisible +RECTANGLE 1 614 notvisible +RECTANGLE 1 615 notvisible +RECTANGLE 1 616 notvisible +RECTANGLE 1 617 notvisible +RECTANGLE 1 618 notvisible +RECTANGLE 1 619 notvisible +RECTANGLE 1 620 notvisible +RECTANGLE 1 621 notvisible +RECTANGLE 1 622 notvisible +RECTANGLE 1 623 notvisible +RECTANGLE 1 624 155 0 159 101 +RECTANGLE 1 625 142 0 159 99 +RECTANGLE 1 626 128 0 159 98 +RECTANGLE 1 627 116 0 148 97 +RECTANGLE 1 628 103 0 135 95 +RECTANGLE 1 629 92 0 123 94 +RECTANGLE 1 630 80 0 111 93 +RECTANGLE 1 631 69 0 100 92 +RECTANGLE 1 632 58 0 88 91 +RECTANGLE 1 633 48 0 78 90 +RECTANGLE 1 634 38 0 67 88 +RECTANGLE 1 635 28 0 57 87 +RECTANGLE 1 636 19 0 47 86 +RECTANGLE 1 637 10 0 38 86 +RECTANGLE 1 638 1 0 29 85 +RECTANGLE 1 639 0 0 20 84 +RECTANGLE 1 640 0 0 11 83 +RECTANGLE 1 641 0 0 3 82 +RECTANGLE 1 642 notvisible +RECTANGLE 1 643 notvisible +RECTANGLE 1 644 notvisible +RECTANGLE 1 645 notvisible +RECTANGLE 1 646 notvisible +RECTANGLE 1 647 notvisible +RECTANGLE 1 648 notvisible +RECTANGLE 1 649 notvisible +RECTANGLE 1 650 notvisible +RECTANGLE 1 651 notvisible +RECTANGLE 1 652 notvisible +RECTANGLE 1 653 notvisible +RECTANGLE 1 654 notvisible +RECTANGLE 1 655 notvisible +RECTANGLE 1 656 notvisible +RECTANGLE 1 657 notvisible +RECTANGLE 1 658 notvisible +RECTANGLE 1 659 notvisible +RECTANGLE 1 660 152 0 159 93 +RECTANGLE 1 661 139 0 159 92 +RECTANGLE 1 662 127 0 157 91 +RECTANGLE 1 663 115 0 145 90 +RECTANGLE 1 664 104 0 133 89 +RECTANGLE 1 665 93 0 122 88 +RECTANGLE 1 666 82 0 111 87 +RECTANGLE 1 667 72 0 100 86 +RECTANGLE 1 668 62 0 90 85 +RECTANGLE 1 669 52 0 80 84 +RECTANGLE 1 670 43 0 70 83 +RECTANGLE 1 671 34 0 61 82 +RECTANGLE 1 672 25 0 52 81 +RECTANGLE 1 673 16 0 42 80 +RECTANGLE 1 674 8 0 34 79 +RECTANGLE 1 675 0 0 26 79 +RECTANGLE 1 676 0 0 17 78 +RECTANGLE 1 677 0 0 9 77 +RECTANGLE 1 678 0 0 2 76 +RECTANGLE 1 679 notvisible +RECTANGLE 1 680 notvisible +RECTANGLE 1 681 notvisible +RECTANGLE 1 682 notvisible +RECTANGLE 1 683 notvisible +RECTANGLE 1 684 notvisible +RECTANGLE 1 685 notvisible +RECTANGLE 1 686 notvisible +RECTANGLE 1 687 notvisible +RECTANGLE 1 688 notvisible +RECTANGLE 1 689 notvisible +RECTANGLE 1 690 notvisible +RECTANGLE 1 691 notvisible +RECTANGLE 1 692 notvisible +RECTANGLE 1 693 notvisible +RECTANGLE 1 694 notvisible +RECTANGLE 1 695 notvisible +RECTANGLE 1 696 149 0 159 87 +RECTANGLE 1 697 138 0 159 86 +RECTANGLE 1 698 126 0 154 85 +RECTANGLE 1 699 115 0 143 84 +RECTANGLE 1 700 105 0 132 83 +RECTANGLE 1 701 94 0 121 82 +RECTANGLE 1 702 84 0 111 81 +RECTANGLE 1 703 75 0 101 80 +RECTANGLE 1 704 65 0 91 79 +RECTANGLE 1 705 56 0 82 79 +RECTANGLE 1 706 47 0 73 78 +RECTANGLE 1 707 39 0 64 77 +RECTANGLE 1 708 30 0 55 76 +RECTANGLE 1 709 22 0 47 76 +RECTANGLE 1 710 14 0 38 75 +RECTANGLE 1 711 6 0 30 74 +RECTANGLE 1 712 0 0 23 74 +RECTANGLE 1 713 0 0 15 73 +RECTANGLE 1 714 0 0 8 72 +RECTANGLE 1 715 0 1 0 72 +RECTANGLE 1 716 notvisible +RECTANGLE 1 717 notvisible +RECTANGLE 1 718 notvisible +RECTANGLE 1 719 notvisible +RECTANGLE 1 720 notvisible +RECTANGLE 1 721 notvisible +RECTANGLE 1 722 notvisible +RECTANGLE 1 723 notvisible +RECTANGLE 1 724 notvisible +RECTANGLE 1 725 notvisible +RECTANGLE 1 726 notvisible +RECTANGLE 1 727 notvisible +RECTANGLE 1 728 notvisible +RECTANGLE 1 729 notvisible +RECTANGLE 1 730 notvisible +RECTANGLE 1 731 158 0 159 82 +RECTANGLE 1 732 146 0 159 81 +RECTANGLE 1 733 136 0 159 80 +RECTANGLE 1 734 125 0 151 79 +RECTANGLE 1 735 115 0 141 78 +RECTANGLE 1 736 105 0 131 78 +RECTANGLE 1 737 96 0 121 77 +RECTANGLE 1 738 86 0 111 76 +RECTANGLE 1 739 77 0 102 75 +RECTANGLE 1 740 68 0 93 75 +RECTANGLE 1 741 59 0 83 74 +RECTANGLE 1 742 51 0 75 73 +RECTANGLE 1 743 43 0 67 73 +RECTANGLE 1 744 35 0 59 72 +RECTANGLE 1 745 27 0 50 71 +RECTANGLE 1 746 20 0 43 71 +RECTANGLE 1 747 12 0 35 70 +RECTANGLE 1 748 5 1 28 70 +RECTANGLE 1 749 0 1 20 69 +RECTANGLE 1 750 0 1 13 69 +RECTANGLE 1 751 0 1 6 68 +RECTANGLE 1 752 0 1 0 68 +RECTANGLE 1 753 notvisible +RECTANGLE 1 754 notvisible +RECTANGLE 1 755 notvisible +RECTANGLE 1 756 notvisible +RECTANGLE 1 757 notvisible +RECTANGLE 1 758 notvisible +RECTANGLE 1 759 notvisible +RECTANGLE 1 760 notvisible +RECTANGLE 1 761 notvisible +RECTANGLE 1 762 notvisible +RECTANGLE 1 763 notvisible +RECTANGLE 1 764 notvisible +RECTANGLE 1 765 notvisible +RECTANGLE 1 766 notvisible +RECTANGLE 1 767 155 0 159 77 +RECTANGLE 1 768 144 0 159 76 +RECTANGLE 1 769 134 0 159 75 +RECTANGLE 1 770 124 0 149 75 +RECTANGLE 1 771 115 0 139 74 +RECTANGLE 1 772 105 0 129 73 +RECTANGLE 1 773 96 0 120 72 +RECTANGLE 1 774 87 0 111 72 +RECTANGLE 1 775 79 0 102 71 +RECTANGLE 1 776 71 0 94 71 +RECTANGLE 1 777 62 0 85 70 +RECTANGLE 1 778 54 0 77 69 +RECTANGLE 1 779 47 0 69 69 +RECTANGLE 1 780 39 0 61 68 +RECTANGLE 1 781 32 1 54 68 +RECTANGLE 1 782 24 1 46 67 +RECTANGLE 1 783 17 1 39 67 +RECTANGLE 1 784 11 1 32 66 +RECTANGLE 1 785 4 1 25 66 +RECTANGLE 1 786 0 1 18 65 +RECTANGLE 1 787 0 1 12 65 +RECTANGLE 1 788 0 1 5 64 +RECTANGLE 1 789 notvisible +RECTANGLE 1 790 notvisible +RECTANGLE 1 791 notvisible +RECTANGLE 1 792 notvisible +RECTANGLE 1 793 notvisible +RECTANGLE 1 794 notvisible +RECTANGLE 1 795 notvisible +RECTANGLE 1 796 notvisible +RECTANGLE 1 797 notvisible +RECTANGLE 1 798 notvisible +RECTANGLE 1 799 notvisible +RECTANGLE 1 800 notvisible +RECTANGLE 1 801 notvisible +RECTANGLE 1 802 notvisible +RECTANGLE 1 803 152 0 159 72 +RECTANGLE 1 804 142 0 159 72 +RECTANGLE 1 805 133 0 156 71 +RECTANGLE 1 806 124 0 147 70 +RECTANGLE 1 807 114 0 137 70 +RECTANGLE 1 808 106 0 129 69 +RECTANGLE 1 809 97 0 119 69 +RECTANGLE 1 810 89 0 111 68 +RECTANGLE 1 811 81 0 103 68 +RECTANGLE 1 812 73 0 95 67 +RECTANGLE 1 813 65 1 86 66 +RECTANGLE 1 814 58 1 79 66 +RECTANGLE 1 815 50 1 71 65 +RECTANGLE 1 816 43 1 64 65 +RECTANGLE 1 817 36 1 57 65 +RECTANGLE 1 818 29 1 50 64 +RECTANGLE 1 819 22 1 43 64 +RECTANGLE 1 820 16 1 36 63 +RECTANGLE 1 821 9 1 29 63 +RECTANGLE 1 822 3 1 23 62 +RECTANGLE 1 823 0 1 16 62 +RECTANGLE 1 824 0 1 10 62 +RECTANGLE 1 825 0 1 4 61 +RECTANGLE 1 826 notvisible +RECTANGLE 1 827 notvisible +RECTANGLE 1 828 notvisible +RECTANGLE 1 829 notvisible +RECTANGLE 1 830 notvisible +RECTANGLE 1 831 notvisible +RECTANGLE 1 832 notvisible +RECTANGLE 1 833 notvisible +RECTANGLE 1 834 notvisible +RECTANGLE 1 835 notvisible +RECTANGLE 1 836 notvisible +RECTANGLE 1 837 notvisible +RECTANGLE 1 838 159 0 159 69 +RECTANGLE 1 839 150 0 159 68 +RECTANGLE 1 840 141 0 159 68 +RECTANGLE 1 841 132 0 154 67 +RECTANGLE 1 842 123 0 145 67 +RECTANGLE 1 843 114 0 136 66 +RECTANGLE 1 844 106 0 127 66 +RECTANGLE 1 845 98 0 119 65 +RECTANGLE 1 846 90 1 111 65 +RECTANGLE 1 847 82 1 103 64 +RECTANGLE 1 848 75 1 96 64 +RECTANGLE 1 849 68 1 88 63 +RECTANGLE 1 850 60 1 80 63 +RECTANGLE 1 851 53 1 73 62 +RECTANGLE 1 852 46 1 66 62 +RECTANGLE 1 853 39 1 59 62 +RECTANGLE 1 854 33 1 53 61 +RECTANGLE 1 855 27 1 46 61 +RECTANGLE 1 856 20 1 39 60 +RECTANGLE 1 857 14 1 33 60 +RECTANGLE 1 858 8 1 27 60 +RECTANGLE 1 859 2 1 21 59 +RECTANGLE 1 860 0 1 15 59 +RECTANGLE 1 861 0 1 9 59 +RECTANGLE 1 862 0 1 3 58 +RECTANGLE 1 863 notvisible +RECTANGLE 1 864 notvisible +RECTANGLE 1 865 notvisible +RECTANGLE 1 866 notvisible +RECTANGLE 1 867 notvisible +RECTANGLE 1 868 notvisible +RECTANGLE 1 869 notvisible +RECTANGLE 1 870 notvisible +RECTANGLE 1 871 notvisible +RECTANGLE 1 872 notvisible +RECTANGLE 1 873 notvisible +RECTANGLE 1 874 157 0 159 65 +RECTANGLE 1 875 148 0 159 65 +RECTANGLE 1 876 139 0 159 64 +RECTANGLE 1 877 131 0 152 64 +RECTANGLE 1 878 122 0 143 63 +RECTANGLE 1 879 115 1 135 63 +RECTANGLE 1 880 107 1 127 62 +RECTANGLE 1 881 99 1 119 62 +RECTANGLE 1 882 91 1 111 62 +RECTANGLE 1 883 84 1 104 61 +RECTANGLE 1 884 76 1 96 61 +RECTANGLE 1 885 70 1 89 60 +RECTANGLE 1 886 63 1 82 60 +RECTANGLE 1 887 56 1 75 60 +RECTANGLE 1 888 49 1 68 59 +RECTANGLE 1 889 43 1 62 59 +RECTANGLE 1 890 36 1 55 58 +RECTANGLE 1 891 30 1 49 58 +RECTANGLE 1 892 24 1 42 58 +RECTANGLE 1 893 18 1 36 57 +RECTANGLE 1 894 12 1 30 57 +RECTANGLE 1 895 7 1 25 57 +RECTANGLE 1 896 1 2 19 56 +RECTANGLE 1 897 0 2 13 56 +RECTANGLE 1 898 0 2 8 56 +RECTANGLE 1 899 0 2 3 56 +RECTANGLE 1 900 notvisible +RECTANGLE 1 901 notvisible +RECTANGLE 1 902 notvisible +RECTANGLE 1 903 notvisible +RECTANGLE 1 904 notvisible +RECTANGLE 1 905 notvisible +RECTANGLE 1 906 notvisible +RECTANGLE 1 907 notvisible +RECTANGLE 1 908 notvisible +RECTANGLE 1 909 notvisible +RECTANGLE 1 910 154 0 159 62 +RECTANGLE 1 911 146 1 159 62 +RECTANGLE 1 912 138 1 158 61 +RECTANGLE 1 913 130 1 150 61 +RECTANGLE 1 914 122 1 141 60 +RECTANGLE 1 915 114 1 133 60 +RECTANGLE 1 916 107 1 126 60 +RECTANGLE 1 917 99 1 118 59 +RECTANGLE 1 918 92 1 111 59 +RECTANGLE 1 919 85 1 104 58 +RECTANGLE 1 920 78 1 97 58 +RECTANGLE 1 921 72 1 90 58 +RECTANGLE 1 922 65 1 83 57 +RECTANGLE 1 923 59 1 77 57 +RECTANGLE 1 924 52 1 70 57 +RECTANGLE 1 925 46 1 64 56 +RECTANGLE 1 926 40 1 58 56 +RECTANGLE 1 927 34 1 52 56 +RECTANGLE 1 928 28 1 46 55 +RECTANGLE 1 929 22 2 39 55 +RECTANGLE 1 930 17 2 34 55 +RECTANGLE 1 931 11 2 28 55 +RECTANGLE 1 932 6 2 23 54 +RECTANGLE 1 933 0 2 17 54 +RECTANGLE 1 934 0 2 12 54 +RECTANGLE 1 935 0 2 7 53 +RECTANGLE 1 936 notvisible +RECTANGLE 1 937 notvisible +RECTANGLE 1 938 notvisible +RECTANGLE 1 939 notvisible +RECTANGLE 1 940 notvisible +RECTANGLE 1 941 notvisible +RECTANGLE 1 942 notvisible +RECTANGLE 1 943 notvisible +RECTANGLE 1 944 notvisible +RECTANGLE 1 945 notvisible +RECTANGLE 1 946 152 1 159 59 +RECTANGLE 1 947 144 1 159 59 +RECTANGLE 1 948 136 1 155 58 +RECTANGLE 1 949 129 1 148 58 +RECTANGLE 1 950 121 1 140 58 +RECTANGLE 1 951 114 1 132 57 +RECTANGLE 1 952 107 1 125 57 +RECTANGLE 1 953 100 1 118 57 +RECTANGLE 1 954 93 1 111 56 +RECTANGLE 1 955 86 1 104 56 +RECTANGLE 1 956 80 1 98 56 +RECTANGLE 1 957 73 1 91 55 +RECTANGLE 1 958 67 1 85 55 +RECTANGLE 1 959 61 1 78 55 +RECTANGLE 1 960 55 1 72 54 +RECTANGLE 1 961 49 1 66 54 +RECTANGLE 1 962 43 2 60 54 +RECTANGLE 1 963 37 2 54 54 +RECTANGLE 1 964 31 2 48 53 +RECTANGLE 1 965 26 2 43 53 +RECTANGLE 1 966 20 2 37 53 +RECTANGLE 1 967 15 2 32 53 +RECTANGLE 1 968 10 2 26 52 +RECTANGLE 1 969 5 2 21 52 +RECTANGLE 1 970 0 2 16 52 +RECTANGLE 1 971 0 2 11 52 +RECTANGLE 1 972 notvisible +RECTANGLE 1 973 notvisible +RECTANGLE 1 974 notvisible +RECTANGLE 1 975 notvisible +RECTANGLE 1 976 notvisible +RECTANGLE 1 977 notvisible +RECTANGLE 1 978 notvisible +RECTANGLE 1 979 notvisible +RECTANGLE 1 980 notvisible +RECTANGLE 1 981 158 1 159 57 +RECTANGLE 1 982 150 1 159 57 +RECTANGLE 1 983 143 1 159 56 +RECTANGLE 1 984 135 1 153 56 +RECTANGLE 1 985 128 1 146 56 +RECTANGLE 1 986 121 1 139 55 +RECTANGLE 1 987 114 1 131 55 +RECTANGLE 1 988 107 1 124 55 +RECTANGLE 1 989 101 1 118 54 +RECTANGLE 1 990 94 1 111 54 +RECTANGLE 1 991 87 1 104 54 +RECTANGLE 1 992 81 1 98 53 +RECTANGLE 1 993 75 1 92 53 +RECTANGLE 1 994 69 2 86 53 +RECTANGLE 1 995 63 2 80 53 +RECTANGLE 1 996 57 2 73 52 +RECTANGLE 1 997 51 2 67 52 +RECTANGLE 1 998 46 2 62 52 +RECTANGLE 1 999 40 2 56 52 +RECTANGLE 1 1000 35 2 51 51 +RECTANGLE 1 1001 29 2 45 51 +RECTANGLE 1 1002 24 2 40 51 +RECTANGLE 1 1003 19 2 35 51 +RECTANGLE 1 1004 14 2 30 50 +RECTANGLE 1 1005 9 2 25 50 +RECTANGLE 1 1006 4 2 20 50 +RECTANGLE 1 1007 0 2 15 50 +RECTANGLE 1 1008 notvisible +RECTANGLE 1 1009 notvisible +RECTANGLE 1 1010 notvisible +RECTANGLE 1 1011 notvisible +RECTANGLE 1 1012 notvisible +RECTANGLE 1 1013 notvisible +RECTANGLE 1 1014 notvisible +RECTANGLE 1 1015 notvisible +RECTANGLE 1 1016 notvisible +RECTANGLE 1 1017 156 1 159 54 +RECTANGLE 1 1018 149 1 159 54 +RECTANGLE 1 1019 142 1 159 54 +RECTANGLE 1 1020 134 1 151 54 +RECTANGLE 1 1021 127 1 144 53 +RECTANGLE 1 1022 121 1 138 53 +RECTANGLE 1 1023 114 1 131 53 +RECTANGLE 1 1024 107 1 124 52 +RECTANGLE 1 1025 101 1 118 52 +RECTANGLE 1 1026 95 1 111 52 +RECTANGLE 1 1027 89 2 105 52 +RECTANGLE 1 1028 83 2 99 51 +RECTANGLE 1 1029 76 2 92 51 +RECTANGLE 1 1030 71 2 87 51 +RECTANGLE 1 1031 65 2 81 51 +RECTANGLE 1 1032 59 2 75 50 +RECTANGLE 1 1033 53 2 69 50 +RECTANGLE 1 1034 48 2 64 50 +RECTANGLE 1 1035 43 2 59 50 +RECTANGLE 1 1036 38 2 53 49 +RECTANGLE 1 1037 33 2 48 49 +RECTANGLE 1 1038 27 2 42 49 +RECTANGLE 1 1039 22 2 37 49 +RECTANGLE 1 1040 17 2 32 49 +RECTANGLE 1 1041 13 2 28 48 +RECTANGLE 1 1042 8 2 23 48 +RECTANGLE 1 1043 3 2 18 48 +RECTANGLE 1 1044 notvisible +RECTANGLE 1 1045 notvisible +RECTANGLE 1 1046 notvisible +RECTANGLE 1 1047 notvisible +RECTANGLE 1 1048 notvisible +RECTANGLE 1 1049 notvisible +RECTANGLE 1 1050 notvisible +RECTANGLE 1 1051 notvisible +RECTANGLE 1 1052 notvisible +RECTANGLE 1 1053 154 1 159 52 +RECTANGLE 1 1054 147 1 159 52 +RECTANGLE 1 1055 140 1 156 52 +RECTANGLE 1 1056 134 1 150 51 +RECTANGLE 1 1057 127 1 143 51 +RECTANGLE 1 1058 120 1 136 51 +RECTANGLE 1 1059 114 1 130 51 +RECTANGLE 1 1060 108 2 124 50 +RECTANGLE 1 1061 101 2 117 50 +RECTANGLE 1 1062 95 2 111 50 +RECTANGLE 1 1063 89 2 105 50 +RECTANGLE 1 1064 84 2 99 49 +RECTANGLE 1 1065 78 2 93 49 +RECTANGLE 1 1066 72 2 87 49 +RECTANGLE 1 1067 67 2 82 49 +RECTANGLE 1 1068 61 2 76 49 +RECTANGLE 1 1069 56 2 71 48 +RECTANGLE 1 1070 51 2 66 48 +RECTANGLE 1 1071 45 2 60 48 +RECTANGLE 1 1072 40 2 55 48 +RECTANGLE 1 1073 35 2 50 48 +RECTANGLE 1 1074 30 2 45 47 +RECTANGLE 1 1075 25 2 40 47 +RECTANGLE 1 1076 20 2 35 47 +RECTANGLE 1 1077 16 2 30 47 +RECTANGLE 1 1078 12 2 26 47 +RECTANGLE 1 1079 7 2 21 46 +RECTANGLE 1 1080 notvisible +RECTANGLE 1 1081 notvisible +RECTANGLE 1 1082 notvisible +RECTANGLE 1 1083 notvisible +RECTANGLE 1 1084 notvisible +RECTANGLE 1 1085 notvisible +RECTANGLE 1 1086 notvisible +RECTANGLE 1 1087 notvisible +RECTANGLE 1 1088 159 1 159 50 +RECTANGLE 1 1089 152 1 159 50 +RECTANGLE 1 1090 146 1 159 50 +RECTANGLE 1 1091 139 1 155 50 +RECTANGLE 1 1092 133 2 148 49 +RECTANGLE 1 1093 126 2 141 49 +RECTANGLE 1 1094 120 2 135 49 +RECTANGLE 1 1095 114 2 129 49 +RECTANGLE 1 1096 108 2 123 49 +RECTANGLE 1 1097 102 2 117 48 +RECTANGLE 1 1098 96 2 111 48 +RECTANGLE 1 1099 90 2 105 48 +RECTANGLE 1 1100 85 2 100 48 +RECTANGLE 1 1101 79 2 94 48 +RECTANGLE 1 1102 74 2 89 47 +RECTANGLE 1 1103 68 2 83 47 +RECTANGLE 1 1104 63 2 78 47 +RECTANGLE 1 1105 58 2 73 47 +RECTANGLE 1 1106 53 2 67 47 +RECTANGLE 1 1107 48 2 62 46 +RECTANGLE 1 1108 43 2 57 46 +RECTANGLE 1 1109 38 2 52 46 +RECTANGLE 1 1110 33 2 47 46 +RECTANGLE 1 1111 29 2 43 46 +RECTANGLE 1 1112 24 2 38 46 +RECTANGLE 1 1113 19 2 33 45 +RECTANGLE 1 1114 15 2 29 45 +RECTANGLE 1 1115 10 2 24 45 +RECTANGLE 1 1116 notvisible +RECTANGLE 1 1117 notvisible +RECTANGLE 1 1118 notvisible +RECTANGLE 1 1119 notvisible +RECTANGLE 1 1120 notvisible +RECTANGLE 1 1121 notvisible +RECTANGLE 1 1122 notvisible +RECTANGLE 1 1123 notvisible +RECTANGLE 1 1124 157 1 159 49 +RECTANGLE 1 1125 151 2 159 48 +RECTANGLE 1 1126 144 2 159 48 +RECTANGLE 1 1127 138 2 153 48 +RECTANGLE 1 1128 132 2 147 48 +RECTANGLE 1 1129 126 2 141 47 +RECTANGLE 1 1130 120 2 135 47 +RECTANGLE 1 1131 114 2 129 47 +RECTANGLE 1 1132 108 2 123 47 +RECTANGLE 1 1133 102 2 117 47 +RECTANGLE 1 1134 97 2 111 46 +RECTANGLE 1 1135 91 2 105 46 +RECTANGLE 1 1136 86 2 100 46 +RECTANGLE 1 1137 80 2 94 46 +RECTANGLE 1 1138 75 2 89 46 +RECTANGLE 1 1139 70 2 84 46 +RECTANGLE 1 1140 65 2 79 45 +RECTANGLE 1 1141 60 2 74 45 +RECTANGLE 1 1142 55 2 69 45 +RECTANGLE 1 1143 50 2 64 45 +RECTANGLE 1 1144 45 2 59 45 +RECTANGLE 1 1145 40 2 54 45 +RECTANGLE 1 1146 36 2 50 44 +RECTANGLE 1 1147 31 2 45 44 +RECTANGLE 1 1148 27 2 41 44 +RECTANGLE 1 1149 23 2 36 44 +RECTANGLE 1 1150 18 2 31 44 +RECTANGLE 1 1151 14 2 27 44 +RECTANGLE 1 1152 notvisible +RECTANGLE 1 1153 notvisible +RECTANGLE 1 1154 notvisible +RECTANGLE 1 1155 notvisible +RECTANGLE 1 1156 notvisible +RECTANGLE 1 1157 notvisible +RECTANGLE 1 1158 notvisible +RECTANGLE 1 1159 notvisible +RECTANGLE 1 1160 155 2 159 47 +RECTANGLE 1 1161 149 2 159 47 +RECTANGLE 1 1162 143 2 157 46 +RECTANGLE 1 1163 137 2 151 46 +RECTANGLE 1 1164 131 2 145 46 +RECTANGLE 1 1165 125 2 139 46 +RECTANGLE 1 1166 119 2 133 46 +RECTANGLE 1 1167 114 2 128 45 +RECTANGLE 1 1168 108 2 122 45 +RECTANGLE 1 1169 103 2 117 45 +RECTANGLE 1 1170 97 2 111 45 +RECTANGLE 1 1171 92 2 106 45 +RECTANGLE 1 1172 86 2 100 45 +RECTANGLE 1 1173 81 2 95 44 +RECTANGLE 1 1174 76 2 90 44 +RECTANGLE 1 1175 71 2 85 44 +RECTANGLE 1 1176 67 2 80 44 +RECTANGLE 1 1177 62 2 75 44 +RECTANGLE 1 1178 57 2 70 44 +RECTANGLE 1 1179 52 2 65 44 +RECTANGLE 1 1180 48 2 61 43 +RECTANGLE 1 1181 43 2 56 43 +RECTANGLE 1 1182 38 2 51 43 +RECTANGLE 1 1183 34 2 47 43 +RECTANGLE 1 1184 30 2 43 43 +RECTANGLE 1 1185 25 2 38 43 +RECTANGLE 1 1186 21 2 34 43 +RECTANGLE 1 1187 17 2 30 42 +RECTANGLE 1 1188 notvisible +RECTANGLE 1 1189 notvisible +RECTANGLE 1 1190 notvisible +RECTANGLE 1 1191 notvisible +RECTANGLE 1 1192 notvisible +RECTANGLE 1 1193 notvisible +RECTANGLE 1 1194 notvisible +RECTANGLE 1 1195 notvisible +RECTANGLE 1 1196 154 2 159 45 +RECTANGLE 1 1197 148 2 159 45 +RECTANGLE 1 1198 142 2 156 45 +RECTANGLE 1 1199 136 2 150 45 +RECTANGLE 1 1200 130 2 144 44 +RECTANGLE 1 1201 125 2 139 44 +RECTANGLE 1 1202 119 2 133 44 +RECTANGLE 1 1203 113 2 127 44 +RECTANGLE 1 1204 108 2 121 44 +RECTANGLE 1 1205 103 2 116 44 +RECTANGLE 1 1206 98 2 111 43 +RECTANGLE 1 1207 93 2 106 43 +RECTANGLE 1 1208 88 2 101 43 +RECTANGLE 1 1209 83 2 96 43 +RECTANGLE 1 1210 78 2 91 43 +RECTANGLE 1 1211 73 2 86 43 +RECTANGLE 1 1212 68 2 81 43 +RECTANGLE 1 1213 63 2 76 42 +RECTANGLE 1 1214 59 2 72 42 +RECTANGLE 1 1215 54 2 67 42 +RECTANGLE 1 1216 49 2 62 42 +RECTANGLE 1 1217 45 2 58 42 +RECTANGLE 1 1218 41 2 54 42 +RECTANGLE 1 1219 36 2 49 42 +RECTANGLE 1 1220 32 2 45 42 +RECTANGLE 1 1221 28 2 41 41 +RECTANGLE 1 1222 23 2 36 41 +RECTANGLE 1 1223 19 2 32 41 +RECTANGLE 1 1224 notvisible +RECTANGLE 1 1225 notvisible +RECTANGLE 1 1226 notvisible +RECTANGLE 1 1227 notvisible +RECTANGLE 1 1228 notvisible +RECTANGLE 1 1229 notvisible +RECTANGLE 1 1230 notvisible +RECTANGLE 1 1231 158 2 159 44 +RECTANGLE 1 1232 152 2 159 44 +RECTANGLE 1 1233 147 2 159 43 +RECTANGLE 1 1234 141 2 154 43 +RECTANGLE 1 1235 135 2 148 43 +RECTANGLE 1 1236 130 2 143 43 +RECTANGLE 1 1237 124 2 137 43 +RECTANGLE 1 1238 119 2 132 43 +RECTANGLE 1 1239 114 2 127 43 +RECTANGLE 1 1240 108 2 121 42 +RECTANGLE 1 1241 103 2 116 42 +RECTANGLE 1 1242 98 2 111 42 +RECTANGLE 1 1243 93 2 106 42 +RECTANGLE 1 1244 88 2 101 42 +RECTANGLE 1 1245 83 2 96 42 +RECTANGLE 1 1246 78 2 91 42 +RECTANGLE 1 1247 74 2 87 42 +RECTANGLE 1 1248 69 2 82 41 +RECTANGLE 1 1249 65 2 78 41 +RECTANGLE 1 1250 60 2 73 41 +RECTANGLE 1 1251 56 2 69 41 +RECTANGLE 1 1252 52 2 64 41 +RECTANGLE 1 1253 47 2 59 41 +RECTANGLE 1 1254 43 2 55 41 +RECTANGLE 1 1255 39 2 51 41 +RECTANGLE 1 1256 35 2 47 40 +RECTANGLE 1 1257 30 3 42 40 +RECTANGLE 1 1258 26 3 38 40 +RECTANGLE 1 1259 22 3 34 40 +RECTANGLE 1 1260 notvisible +RECTANGLE 1 1261 notvisible +RECTANGLE 1 1262 notvisible +RECTANGLE 1 1263 notvisible +RECTANGLE 1 1264 notvisible +RECTANGLE 1 1265 notvisible +RECTANGLE 1 1266 notvisible +RECTANGLE 1 1267 157 2 159 42 +RECTANGLE 1 1268 151 2 159 42 +RECTANGLE 1 1269 145 2 158 42 +RECTANGLE 1 1270 140 2 153 42 +RECTANGLE 1 1271 134 2 147 42 +RECTANGLE 1 1272 129 2 142 42 +RECTANGLE 1 1273 124 2 137 42 +RECTANGLE 1 1274 118 2 131 41 +RECTANGLE 1 1275 113 2 126 41 +RECTANGLE 1 1276 108 2 121 41 +RECTANGLE 1 1277 103 2 116 41 +RECTANGLE 1 1278 99 2 111 41 +RECTANGLE 1 1279 94 2 106 41 +RECTANGLE 1 1280 89 2 101 41 +RECTANGLE 1 1281 84 2 96 41 +RECTANGLE 1 1282 80 2 92 40 +RECTANGLE 1 1283 75 2 87 40 +RECTANGLE 1 1284 71 2 83 40 +RECTANGLE 1 1285 66 2 78 40 +RECTANGLE 1 1286 62 2 74 40 +RECTANGLE 1 1287 58 2 70 40 +RECTANGLE 1 1288 53 2 65 40 +RECTANGLE 1 1289 49 2 61 40 +RECTANGLE 1 1290 45 3 57 40 +RECTANGLE 1 1291 41 3 53 39 +RECTANGLE 1 1292 37 3 49 39 +RECTANGLE 1 1293 33 3 45 39 +RECTANGLE 1 1294 29 3 41 39 +RECTANGLE 1 1295 25 3 37 39 +RECTANGLE 1 1296 notvisible +RECTANGLE 1 1297 notvisible +RECTANGLE 1 1298 notvisible +RECTANGLE 1 1299 notvisible +RECTANGLE 1 1300 notvisible +RECTANGLE 1 1301 notvisible +RECTANGLE 1 1302 notvisible +RECTANGLE 1 1303 155 2 159 41 +RECTANGLE 1 1304 150 2 159 41 +RECTANGLE 1 1305 145 2 157 41 +RECTANGLE 1 1306 139 2 151 41 +RECTANGLE 1 1307 134 2 146 41 +RECTANGLE 1 1308 129 2 141 40 +RECTANGLE 1 1309 124 2 136 40 +RECTANGLE 1 1310 119 2 131 40 +RECTANGLE 1 1311 114 2 126 40 +RECTANGLE 1 1312 109 2 121 40 +RECTANGLE 1 1313 104 2 116 40 +RECTANGLE 1 1314 99 2 111 40 +RECTANGLE 1 1315 94 2 106 40 +RECTANGLE 1 1316 90 2 102 40 +RECTANGLE 1 1317 85 2 97 39 +RECTANGLE 1 1318 81 2 93 39 +RECTANGLE 1 1319 76 2 88 39 +RECTANGLE 1 1320 72 2 84 39 +RECTANGLE 1 1321 67 2 79 39 +RECTANGLE 1 1322 63 3 75 39 +RECTANGLE 1 1323 59 3 71 39 +RECTANGLE 1 1324 55 3 67 39 +RECTANGLE 1 1325 51 3 63 39 +RECTANGLE 1 1326 47 3 59 39 +RECTANGLE 1 1327 43 3 54 38 +RECTANGLE 1 1328 39 3 50 38 +RECTANGLE 1 1329 35 3 46 38 +RECTANGLE 1 1330 31 3 42 38 +RECTANGLE 1 1331 28 3 39 38 + +# The filenames of the view to load + +INPUT_VIEW_FORMAT images/view-f%f-c%c.png + +# Where to save the "average synthetic views" + +RESULT_VIEW_FORMAT /tmp/result-f%f-c%c.png + +# Where to save the maps of marginal probabilities + +RESULT_FORMAT /tmp/proba-f%f.dat + +# Where to save the images for every iteration of the estimation +# process + +# CONVERGENCE_VIEW_FORMAT /tmp/convergence-f%f-c%c-i%i.png + +# To speed-up the convergence, the solver ignores locations when the +# probability of absence is greater than 0.99 + +PROBA_IGNORED 0.99 + +# Processes 30 frames from frame 160 + +PROCESS 160 30 diff --git a/vector.h b/vector.h new file mode 100644 index 0000000..fdfe5fe --- /dev/null +++ b/vector.h @@ -0,0 +1,139 @@ + +////////////////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify // +// it under the terms of the version 3 of the GNU General Public License // +// as published by the Free Software Foundation. // +// // +// 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, see . // +// // +// Written by Francois Fleuret // +// (C) Ecole Polytechnique Federale de Lausanne // +// Contact for comments & bug reports // +////////////////////////////////////////////////////////////////////////////////// + +#ifndef VECTOR_H +#define VECTOR_H + +#include +#include +#include + +using namespace std; + +#include "misc.h" + +template +class Vector { +protected: + int size; + T *content; +public: + inline void resize(int s) { + delete[] content; + size = s; + content = new T[size]; + } + + inline int length() const { return size; } + + inline Vector(std::istream &is) { + is.read((char *) &size, sizeof(size)); + content = new T[size]; + is.read((char *) content, sizeof(T)*size); + } + + inline Vector() : size(0), content(0) { } + inline Vector(int s) : size(s), content(new T[size]) {} + inline Vector(const Vector &v) : size(v.size), content(new T[size]) { + if(size > 0) memcpy(content, v.content, size * sizeof(T)); + } + inline ~Vector() { + delete[] content; +#ifdef DEBUG + content = 0; +#endif + } + + inline void load(std::istream &is) { + is.read((char *) &size, sizeof(size)); + resize(size); + is.read((char *) content, sizeof(T) * size); + } + + inline void save(std::ostream &os) const { + os.write((char *) &size, sizeof(size)); + os.write((char *) content, sizeof(T) * size); + } + +// inline void fill(const T &t) { +// T *s = content; +// for(int i = 0; i < size; i++) *(s++) = t; +// } + + inline Vector &operator = (const Vector &v) { + if(this != &v) { + if(v.size != size) { + delete[] content; + size = v.size; + content = new T[size]; + } + if(size > 0) memcpy(content, v.content, size * sizeof(T)); + } + return *this; + } + + inline bool operator == (const Vector &v) { + if(this != &v) { + if(v.size != size) return false; + return memcmp(content, v.content, size * sizeof(T)) == 0; + } else return true; + } + + inline bool operator != (const Vector &v) { + if(this != &v) { + if(v.size != size) return true; + return memcmp(content, v.content, size * sizeof(T)) != 0; + } else return false; + } + + inline Vector & clear() { + if(size > 0) memset(content, 0, size * sizeof(T)); + return *this; + } + + inline T &operator [] (int k) { + ASSERT(k >= 0 && k < size, "Index out of bound in Vector::operator []"); + return content[k]; + } + + inline T operator [] (int k) const { + ASSERT(k >= 0 && k < size, "Index out of bound in Vector::operator [] const"); + return content[k]; + } + + inline T norme() const { + T s = 0; + for(int i = 0; i +std::ostream &operator << (std::ostream &os, const Vector &v) { v.print(os); return os; } + +#endif -- 2.39.5