├── LICENSE ├── README.md └── program ├── base ├── cmvs │ ├── bundle.cc │ ├── bundle.h │ ├── graclus.cc │ └── graclus.h ├── image │ ├── camera.cc │ ├── camera.h │ ├── image.cc │ ├── image.h │ ├── photo.cc │ ├── photo.h │ ├── photoSetS.cc │ └── photoSetS.h ├── numeric │ ├── mat2.h │ ├── mat3.h │ ├── mat4.h │ ├── mylapack.cc │ ├── mylapack.h │ ├── vec2.h │ ├── vec3.h │ └── vec4.h ├── pmvs │ ├── asyncQueue.h │ ├── detectFeatures.cc │ ├── detectFeatures.h │ ├── detector.cc │ ├── detector.h │ ├── dog.cc │ ├── dog.h │ ├── expand.cc │ ├── expand.h │ ├── filter.cc │ ├── filter.h │ ├── findMatch.cc │ ├── findMatch.h │ ├── harris.cc │ ├── harris.h │ ├── optim.cc │ ├── optim.h │ ├── option.cc │ ├── option.h │ ├── patch.cc │ ├── patch.h │ ├── patchOrganizerS.cc │ ├── patchOrganizerS.h │ ├── point.cc │ ├── point.h │ ├── refinePatch.cl │ ├── refineThread.cc │ ├── refineThread.h │ ├── seed.cc │ └── seed.h └── stann │ ├── Copyright.txt │ ├── assert.hpp │ ├── assert.hpp~ │ ├── bruteNN.hpp │ ├── bruteNN.hpp~ │ ├── bsearch.hpp │ ├── bsearch.hpp~ │ ├── dpoint.hpp │ ├── pair_iter.hpp │ ├── qknn.hpp │ ├── rand.hpp │ ├── sep_float.hpp │ ├── sfcnn.hpp │ ├── sfcnn.hpp~ │ ├── sfcnn_knng.hpp │ ├── sfcnn_knng.hpp~ │ ├── test.hpp │ ├── test.hpp~ │ ├── zorder_lt.hpp │ ├── zorder_lt.hpp~ │ ├── zorder_type_traits.hpp │ └── zorder_type_traits.hpp~ └── main ├── Makefile ├── cmvs.cc ├── genOption.cc ├── pmvs2.cc ├── run0.sh ├── run1.sh └── run2.sh /LICENSE: -------------------------------------------------------------------------------- 1 | This program is free software: you can redistribute it and/or modify 2 | it under the terms of the GNU General Public License as published by 3 | the Free Software Foundation, either version 3 of the License, or 4 | (at your option) any later version. 5 | 6 | This program is distributed in the hope that it will be useful, 7 | but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | GNU General Public License for more details. 10 | 11 | You should have received a copy of the GNU General Public License 12 | along with this program. If not, see . 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PMVS-GPU 2 | This project modifies [PMVS](http://www.di.ens.fr/pmvs/) to use the GPU. So far it has only been tested on Ubuntu 14.04 with NVIDIA graphics cards. 3 | 4 | ## Requirements 5 | #### OpenCL 1.2 6 | Verify OpenCL is configured correctly by running the `clinfo` utility. It should find a GPU device and return lots of info. On Ubuntu, OpenCL appears to be broken when using NVIDIA Ubuntu packages. If OpenCL isn't working, try removing all NVIDIA Ubuntu packages and reinstall drivers using the NVIDIA binary installer downloaded from [http://www.geforce.com/drivers](http://www.geforce.com/drivers). 7 | 8 | #### Ubuntu packages 9 | 10 | ``` 11 | sudo apt-get install libgsl0-dev libblas-dev libatlas-dev liblapack-dev opencl-headers libjpeg-dev 12 | ``` 13 | 14 | #### Other 15 | * [Graclus](http://www.cs.utexas.edu/users/dml/Software/graclus.html) 16 | 17 | When compiling Graclus be sure to set DNUMBITS to 64 in Makefile.in if you're using a 64 bit system. 18 | 19 | ## Build Instructions 20 | Update `program/main/Makefile` to point to your graclus dir (`YOUR_INCLUDE_METIS_PATH` and `YOUR_LDLIB_PATH`) 21 | ``` 22 | cd program/main 23 | make depend 24 | make 25 | sudo make install 26 | ``` 27 | 28 | ## Using with OpenDroneMap 29 | There is a more up-to-date branch of OpenDroneMap called python-port. When the input images have GPS metadata, the point matching step is much faster for large datasets. To use python-port, first clone the OpenDroneMap repository, then check out the branch using git. 30 | ``` 31 | git clone https://github.com/OpenDroneMap/OpenDroneMap.git 32 | cd OpenDroneMap 33 | git fetch 34 | git checkout python-port 35 | ./install.sh 36 | ``` 37 | 38 | OpenDroneMap comes with the original version of pmvs2. To use pmvs-gpu instead, copy the binary to the OpenDroneMap bin directory. 39 | ```cp /program/main/pmvs2 /bin``` 40 | 41 | After installing, run OpenDroneMap by launching the `run.py` script from the directory that contains the input images. Note that if you're using the default branch (gh-pages), use `run.pl` instead. 42 | -------------------------------------------------------------------------------- /program/base/cmvs/graclus.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "graclus.h" 3 | 4 | using namespace CMVS; 5 | using namespace std; 6 | 7 | // Required by library 8 | int boundary_points; 9 | int spectral_initialization; 10 | int cutType; 11 | int memory_saving; 12 | 13 | Cgraclus::Cgraclus(void) { 14 | } 15 | 16 | Cgraclus::~Cgraclus() { 17 | } 18 | 19 | /************************************************************************* 20 | * This function reads the spd matrix 21 | **************************************************************************/ 22 | void Cgraclus::initGraph(GraphType& graph) { 23 | graph.gdata = graph.rdata = NULL; 24 | 25 | graph.nvtxs = graph.nedges = -1; 26 | graph.mincut = graph.minvol = -1; 27 | 28 | graph.xadj = graph.vwgt = graph.adjncy = graph.adjwgt = NULL; 29 | graph.adjwgtsum = NULL; 30 | graph.label = NULL; 31 | graph.cmap = NULL; 32 | 33 | graph.where = graph.pwgts = NULL; 34 | graph.id = graph.ed = NULL; 35 | graph.bndptr = graph.bndind = NULL; 36 | graph.rinfo = NULL; 37 | graph.vrinfo = NULL; 38 | graph.nrinfo = NULL; 39 | 40 | graph.ncon = -1; 41 | graph.nvwgt = NULL; 42 | graph.npwgts = NULL; 43 | 44 | graph.vsize = NULL; 45 | 46 | graph.coarser = graph.finer = NULL; 47 | } 48 | 49 | //---------------------------------------------------------------------- 50 | // cutType 51 | // 0: NCUT, 1: RASSO 52 | void Cgraclus::run(std::vector& xadj, 53 | std::vector& adjncy, 54 | const int nparts, const int cutType, 55 | std::vector& part) { 56 | GraphType graph; 57 | initGraph(graph); 58 | 59 | graph.ncon = 1; 60 | 61 | graph.xadj = &xadj[0]; 62 | graph.adjncy = &adjncy[0]; 63 | graph.vwgt = NULL; 64 | graph.adjwgt = NULL; 65 | 66 | graph.nvtxs = (int)xadj.size() - 1; 67 | graph.nedges = (int)adjncy.size(); 68 | 69 | const int wgtflag = 0; 70 | runSub(graph, nparts, cutType, wgtflag, part); 71 | } 72 | 73 | void Cgraclus::runV(std::vector& xadj, 74 | std::vector& adjncy, 75 | std::vector& vwgt, 76 | const int nparts, const int cutType, 77 | std::vector& part) { 78 | GraphType graph; 79 | initGraph(graph); 80 | 81 | graph.ncon = 1; 82 | 83 | graph.xadj = &xadj[0]; 84 | graph.adjncy = &adjncy[0]; 85 | graph.vwgt = &vwgt[0]; 86 | graph.adjwgt = NULL; 87 | 88 | graph.nvtxs = (int)xadj.size() - 1; 89 | graph.nedges = (int)adjncy.size(); 90 | 91 | const int wgtflag = 2; 92 | runSub(graph, nparts, cutType, wgtflag, part); 93 | } 94 | 95 | //---------------------------------------------------------------------- 96 | void Cgraclus::runE(std::vector& xadj, 97 | std::vector& adjncy, 98 | std::vector& adjwgt, 99 | const int nparts, const int cutType, 100 | std::vector& part) { 101 | GraphType graph; 102 | initGraph(graph); 103 | 104 | graph.ncon = 1; 105 | 106 | graph.xadj = &xadj[0]; 107 | graph.adjncy = &adjncy[0]; 108 | graph.vwgt = NULL; 109 | graph.adjwgt = &adjwgt[0]; 110 | 111 | graph.nvtxs = (int)xadj.size() - 1; 112 | graph.nedges = (int)adjncy.size(); 113 | 114 | const int wgtflag = 1; 115 | runSub(graph, nparts, cutType, wgtflag, part); 116 | } 117 | 118 | void Cgraclus::runVE(std::vector& xadj, 119 | std::vector& adjncy, 120 | std::vector& vwgt, 121 | std::vector& adjwgt, 122 | const int nparts, const int cutType, 123 | std::vector& part) { 124 | GraphType graph; 125 | initGraph(graph); 126 | 127 | graph.ncon = 1; 128 | 129 | graph.xadj = &xadj[0]; 130 | graph.adjncy = &adjncy[0]; 131 | graph.vwgt = &vwgt[0]; 132 | graph.adjwgt = &adjwgt[0]; 133 | 134 | graph.nvtxs = (int)xadj.size() - 1; 135 | graph.nedges = (int)adjncy.size(); 136 | 137 | const int wgtflag = 3; 138 | runSub(graph, nparts, cutType, wgtflag, part); 139 | } 140 | 141 | int Cgraclus::mylog2(int a) { 142 | int i; 143 | for (i = 1 ; a > 1; i++, a = a>>1); 144 | return i-1; 145 | } 146 | 147 | void Cgraclus::runSub(GraphType& graph, int nparts, int cutType, 148 | int wgtflag, std::vector& part) { 149 | const int levels = 150 | amax((graph.nvtxs)/(40*mylog2(nparts)), 20*(nparts)); 151 | part.resize(graph.nvtxs); 152 | 153 | int options[11]; options[0] = 0; 154 | int numflag = 0; 155 | int chain_length = 0; int edgecut; 156 | 157 | MLKKM_PartGraphKway(&graph.nvtxs, graph.xadj, graph.adjncy, 158 | graph.vwgt, graph.adjwgt, 159 | &wgtflag, &numflag, &nparts, 160 | &chain_length, options, &edgecut, &part[0], levels); 161 | 162 | float lbvec[MAXNCON]; 163 | ComputePartitionBalance(&graph, nparts, &part[0], lbvec); 164 | 165 | float result; 166 | if (cutType == 0){ 167 | result = ComputeNCut(&graph, &part[0], nparts); 168 | printf("\nNormalized-Cut... \n Cut value: %7f, Balance: ", result); 169 | } 170 | else{ 171 | result = ComputeRAsso(&graph, &part[0], nparts); 172 | printf("\nRatio Association... \n Association value: %7f, Balance: ", result); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /program/base/cmvs/graclus.h: -------------------------------------------------------------------------------- 1 | #ifndef CMVS_GRACLUS_H 2 | #define CMVS_GRACLUS_H 3 | 4 | #include 5 | #include 6 | 7 | /* 8 | 0 -- 1 -- 2 -- 3 -- 4 9 | | | | | | 10 | 5 -- 6 -- 7 -- 8 -- 9 11 | | | | | | 12 | 10 --11 --12 --13 --14 13 | 14 | CSR format 15 | xadj: 0 2 5 8 11 13 16 20 24 28 31 33 36 39 42 44 16 | Size of xadj is the number of vertices plus 1. 17 | 18 | adjncy: 1 5 0 2 6 1 3 7 2 4 8 3 9 0 6 10 1 5 7 11 2 6 8 12 3 7 9 13 4 8 14 5 11 6 10 12 7 11 13 8 12 14 9 13 19 | 20 | Size of adjncy is twice the number of edges. 21 | */ 22 | 23 | namespace CMVS { 24 | class Cgraclus { 25 | public: 26 | Cgraclus(void); 27 | virtual ~Cgraclus(); 28 | 29 | // Threads free. no weights 30 | static void run(std::vector& xadj, 31 | std::vector& adjncy, 32 | const int nparts, const int cutType, 33 | std::vector& part); 34 | 35 | // Threads free. vertex weights 36 | static void runV(std::vector& xadj, 37 | std::vector& adjncy, 38 | std::vector& vwgt, 39 | const int nparts, const int cutType, 40 | std::vector& part); 41 | 42 | // Threads free. edge weights 43 | static void runE(std::vector& xadj, 44 | std::vector& adjncy, 45 | std::vector& adjwgt, 46 | const int nparts, const int cutType, 47 | std::vector& part); 48 | 49 | // Threads free. vertex and edge weights 50 | static void runVE(std::vector& xadj, 51 | std::vector& adjncy, 52 | std::vector& vwgt, 53 | std::vector& adjwgt, 54 | const int nparts, const int cutType, 55 | std::vector& part); 56 | 57 | protected: 58 | static int mylog2(int a); 59 | 60 | static void runSub(GraphType& graph, int nparts, int cutType, 61 | int wgtflag, std::vector& part); 62 | 63 | static void initGraph(GraphType& graph); 64 | }; 65 | }; 66 | 67 | #endif // CMVS_GRACLUS_H 68 | -------------------------------------------------------------------------------- /program/base/image/camera.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGE_CAMERA_H 2 | #define IMAGE_CAMERA_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../numeric/vec4.h" 8 | #include "../numeric/mat4.h" 9 | #include "../numeric/mat3.h" 10 | 11 | namespace Image { 12 | 13 | class Ccamera { 14 | public: 15 | Ccamera(void); 16 | virtual ~Ccamera(); 17 | 18 | // Update projection matrices from intrinsics and extrinsics 19 | void updateProjection(void); 20 | // Update all the camera related parameters 21 | void updateCamera(void); 22 | 23 | virtual void init(const std::string cname, const int maxLevel); 24 | void write(const std::string file); 25 | 26 | inline Vec3f project(const Vec4f& coord, const int level) const; 27 | inline Vec3f mult(const Vec4f& coord, const int level) const; 28 | 29 | static void setProjection(const std::vector& intrinsics, 30 | const std::vector& extrinsics, 31 | std::vector& projection, 32 | const int txtType); 33 | 34 | float getScale(const Vec4f& coord, const int level) const; 35 | void getPAxes(const Vec4f& coord, const Vec4f& normal, 36 | Vec4f& pxaxis, Vec4f& pyaxis, const int level = 0) const; 37 | 38 | void setAxesScale(const float axesScale); 39 | 40 | static void proj2q(Mat4& mat, double q[6]); 41 | static void q2proj(const double q[6], Mat4& mat); 42 | static void setProjectionSub(double params[], std::vector& projection, 43 | const int level); 44 | 45 | float computeDistance(const Vec4f& point) const; 46 | float computeDepth(const Vec4f& point) const; 47 | float computeDepthDif(const Vec4f& rhs, const Vec4f& lhs) const; 48 | 49 | // Compute where the viewing ray passing through coord intersects 50 | // with the plane abcd. 51 | Vec4f intersect(const Vec4f& coord, const Vec4f& abcd) const; 52 | void intersect(const Vec4f& coord, const Vec4f& abcd, 53 | Vec4f& cross, float& distance) const; 54 | // Computer a 3D coordinate that projects to a given image 55 | // coordinate. You can specify a different depth by the third 56 | // component of icoord. 57 | Vec4f unproject(const Vec3f& icoord, const int m_level) const; 58 | 59 | void setK(Mat3f& K) const; 60 | void setRT(Mat4f& RT) const; 61 | 62 | void getR(Mat3f& R) const; 63 | 64 | //---------------------------------------------------------------------- 65 | // txt file name 66 | std::string m_cname; 67 | // Optical center 68 | Vec4f m_center; 69 | // Optical axis 70 | Vec4f m_oaxis; 71 | 72 | float m_ipscale; 73 | // 3x4 projection matrix 74 | std::vector > m_projection; 75 | Vec3f m_xaxis; 76 | Vec3f m_yaxis; 77 | Vec3f m_zaxis; 78 | 79 | // intrinsic and extrinsic camera parameters. Compact form. 80 | std::vector m_intrinsics; 81 | std::vector m_extrinsics; 82 | // camera parameter type 83 | int m_txtType; 84 | protected: 85 | int m_maxLevel; 86 | 87 | float m_axesScale; 88 | 89 | Vec4f getOpticalCenter(void) const; 90 | }; 91 | 92 | inline Vec3f Ccamera::project(const Vec4f& coord, 93 | const int level) const { 94 | Vec3f vtmp; 95 | for (int i = 0; i < 3; ++i) 96 | vtmp[i] = m_projection[level][i] * coord; 97 | 98 | if (vtmp[2] <= 0.0) { 99 | vtmp[0] = -0xffff; 100 | vtmp[1] = -0xffff; 101 | vtmp[2] = -1.0f; 102 | return vtmp; 103 | } 104 | else 105 | vtmp /= vtmp[2]; 106 | 107 | vtmp[0] = std::max((float)(INT_MIN + 3.0f), 108 | std::min((float)(INT_MAX - 3.0f), 109 | vtmp[0])); 110 | vtmp[1] = std::max((float)(INT_MIN + 3.0f), 111 | std::min((float)(INT_MAX - 3.0f), 112 | vtmp[1])); 113 | 114 | return vtmp; 115 | }; 116 | 117 | inline Vec3f Ccamera::mult(const Vec4f& coord, 118 | const int level) const { 119 | Vec3f vtmp; 120 | for (int i = 0; i < 3; ++i) 121 | vtmp[i] = m_projection[level][i] * coord; 122 | 123 | return vtmp; 124 | }; 125 | 126 | template 127 | float computeEPD(const TMat3& F, const TVec3& p0, const TVec3& p1) { 128 | TVec3 line = F * p1; 129 | const T ftmp = sqrt(line[0] * line[0] + line[1] * line[1]); 130 | if (ftmp == 0.0) 131 | return 0.0; 132 | 133 | line /= ftmp; 134 | return fabs(line * p0); 135 | }; 136 | 137 | template 138 | void setF(const Image::Ccamera& lhs, const Image::Ccamera& rhs, 139 | TMat3& F, const int level = 0) { 140 | const TVec4& p00 = lhs.m_projection[level][0]; 141 | const TVec4& p01 = lhs.m_projection[level][1]; 142 | const TVec4& p02 = lhs.m_projection[level][2]; 143 | 144 | const TVec4& p10 = rhs.m_projection[level][0]; 145 | const TVec4& p11 = rhs.m_projection[level][1]; 146 | const TVec4& p12 = rhs.m_projection[level][2]; 147 | 148 | F[0][0] = det(TMat4(p01, p02, p11, p12)); 149 | F[0][1] = det(TMat4(p01, p02, p12, p10)); 150 | F[0][2] = det(TMat4(p01, p02, p10, p11)); 151 | 152 | F[1][0] = det(TMat4(p02, p00, p11, p12)); 153 | F[1][1] = det(TMat4(p02, p00, p12, p10)); 154 | F[1][2] = det(TMat4(p02, p00, p10, p11)); 155 | 156 | F[2][0] = det(TMat4(p00, p01, p11, p12)); 157 | F[2][1] = det(TMat4(p00, p01, p12, p10)); 158 | F[2][2] = det(TMat4(p00, p01, p10, p11)); 159 | }; 160 | 161 | }; // namespace image 162 | 163 | #endif // CAMERA_H 164 | -------------------------------------------------------------------------------- /program/base/image/photo.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "photo.h" 3 | 4 | using namespace std; 5 | using namespace Image; 6 | 7 | Cphoto::Cphoto(void) { 8 | } 9 | 10 | Cphoto::~Cphoto() { 11 | } 12 | 13 | void Cphoto::init(const std::string name, const std::string mname, 14 | const std::string cname, const int maxLevel) { 15 | Cimage::init(name, mname, maxLevel); 16 | Ccamera::init(cname, maxLevel); 17 | } 18 | 19 | void Cphoto::init(const std::string name, const std::string mname, 20 | const std::string ename, 21 | const std::string cname, const int maxLevel) { 22 | Cimage::init(name, mname, ename, maxLevel); 23 | Ccamera::init(cname, maxLevel); 24 | } 25 | 26 | float Cphoto::ssd(const std::vector& tex0, 27 | const std::vector& tex1) { 28 | float ans = 0.0f; 29 | for (int i = 0; i < (int)tex0.size(); ++i) 30 | ans += norm2(tex0[i] - tex1[i]); 31 | 32 | // Make sure that the score is below 2.0f 33 | ans /= (int)tex0.size() * (255.0 * 255.0 * 3.0); 34 | 35 | return ans; 36 | } 37 | 38 | float Cphoto::idot(const std::vector& tex0, 39 | const std::vector& tex1) { 40 | if (tex0.empty() || tex1.empty()) { 41 | cerr << "Error in idot. Empty textures" << endl; 42 | exit (1); 43 | } 44 | float ans = 0.0; 45 | for (int i = 0; i < (int)tex0.size(); ++i) { 46 | ans += tex0[i] * tex1[i]; 47 | } 48 | 49 | return 1.0f - ans / (3 * (int)tex0.size()); 50 | } 51 | 52 | void Cphoto::idotC(const std::vector& tex0, 53 | const std::vector& tex1, double* idc) { 54 | if (tex0.empty() || tex1.empty()) { 55 | cerr << "Error in idotC. Empty textures" << endl; 56 | exit (1); 57 | } 58 | idc[0] = 0.0; idc[1] = 0.0; idc[2] = 0.0; 59 | for (int i = 0; i < (int)tex0.size(); ++i) { 60 | for (int j = 0; j < 3; ++j) 61 | idc[j] += tex0[i][j] * tex1[i][j]; 62 | } 63 | for (int j = 0; j < 3; ++j) 64 | idc[j] = 1.0 - idc[j] / (int)tex0.size(); 65 | } 66 | 67 | void Cphoto::normalize(std::vector& tex) { 68 | //---------------------------------------------------------------------- 69 | // normalize average 70 | Vec3f ave; 71 | for (int i = 0; i < (int)tex.size(); ++i) 72 | ave += tex[i]; 73 | ave /= (int)tex.size(); 74 | 75 | for (int i = 0; i < (int)tex.size(); ++i) 76 | tex[i] -= ave; 77 | //---------------------------------------------------------------------- 78 | // compute variance 79 | float ave2 = 0.0f; 80 | for (int i = 0; i < (int)tex.size(); ++i) 81 | ave2 += tex[i] * tex[i]; 82 | ave2 /= (int)tex.size() * 3; 83 | ave2 = sqrt(ave2); 84 | if (ave2 == 0.0f) 85 | ave2 = 1.0f; 86 | 87 | for (int i = 0; i < (int)tex.size(); ++i) 88 | tex[i] /= ave2; 89 | } 90 | 91 | void Cphoto::grabTex(const int level, const Vec2f& icoord, 92 | const Vec2f& xaxis, const Vec2f& yaxis, 93 | const int size, std::vector& tex, 94 | const int normalizef) const{ 95 | const int margin = size / 2; 96 | 97 | // Check boundary condition 98 | const float maxx = icoord[0] + size * fabs(xaxis[0]) + size * fabs(yaxis[0]); 99 | const float minx = icoord[0] - size * fabs(xaxis[0]) - size * fabs(yaxis[0]); 100 | const float maxy = icoord[1] + size * fabs(xaxis[1]) + size * fabs(yaxis[1]); 101 | const float miny = icoord[1] - size * fabs(xaxis[1]) - size * fabs(yaxis[1]); 102 | 103 | tex.clear(); 104 | if (minx < 0 || getWidth(level) - 1 <= maxx || 105 | miny < 0 || getHeight(level) - 1 <= maxy) 106 | return; 107 | 108 | //tex.reserve(size * size); 109 | for (int y = -margin; y <= margin; ++y) { 110 | Vec2f v2ftmp = icoord - margin * xaxis + y * yaxis; 111 | for (int x = -margin; x <= margin; ++x) { 112 | tex.push_back(Cimage::getColor(v2ftmp[0], v2ftmp[1], level)); 113 | v2ftmp += xaxis; 114 | } 115 | } 116 | 117 | if (normalizef) 118 | normalize(tex); 119 | } 120 | 121 | void Cphoto::grabTex(const int level, const Vec4f& coord, 122 | const Vec4f& pxaxis, const Vec4f& pyaxis, const Vec4f& pzaxis, 123 | const int size, 124 | std::vector& tex, float& weight, 125 | const int normalizef) const { 126 | const int scale = 0x0001 << level; 127 | 128 | const Vec3f icoord3 = project(coord, level); 129 | const Vec2f icoord(icoord3[0], icoord3[1]); 130 | 131 | const Vec3f xaxis3 = project(coord + pxaxis * scale, level) - icoord3; 132 | const Vec2f xaxis(xaxis3[0], xaxis3[1]); 133 | 134 | const Vec3f yaxis3 = project(coord + pyaxis * scale, level) - icoord3; 135 | const Vec2f yaxis(yaxis3[0], yaxis3[1]); 136 | 137 | grabTex(level, icoord, xaxis, yaxis, size, tex, normalizef); 138 | 139 | Vec4f ray = m_center - coord; 140 | unitize(ray); 141 | weight = max(0.0f, pzaxis * ray); 142 | } 143 | -------------------------------------------------------------------------------- /program/base/image/photo.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGE_PHOTO_H 2 | #define IMAGE_PHOTO_H 3 | 4 | #include "../numeric/vec4.h" 5 | #include "image.h" 6 | #include "camera.h" 7 | 8 | namespace Image { 9 | 10 | // Cphoto is an image with camera parameters 11 | class Cphoto : public Cimage, public Ccamera { 12 | public: 13 | Cphoto(void); 14 | virtual ~Cphoto(); 15 | 16 | virtual void init(const std::string name, const std::string mname, 17 | const std::string cname, const int maxLevel = 1); 18 | 19 | virtual void init(const std::string name, const std::string mname, 20 | const std::string ename, 21 | const std::string cname, const int maxLevel = 1); 22 | 23 | // grabTex given 2D sampling information 24 | void grabTex(const int level, const Vec2f& icoord, 25 | const Vec2f& xaxis, const Vec2f& yaxis, const int size, 26 | std::vector& tex, const int normalizef = 1) const; 27 | 28 | // grabTex given 3D sampling information 29 | void grabTex(const int level, const Vec4f& coord, 30 | const Vec4f& pxaxis, const Vec4f& pyaxis, const Vec4f& pzaxis, 31 | const int size, std::vector& tex, float& weight, 32 | const int normalizef = 1) const; 33 | 34 | 35 | inline Vec3f getColor(const float fx, const float fy, const int level) const; 36 | inline Vec3f getColor(const Vec4f& coord, const int level) const; 37 | inline int getMask(const Vec4f& coord, const int level) const; 38 | inline int getEdge(const Vec4f& coord, const int level) const; 39 | 40 | static float idot(const std::vector& tex0, 41 | const std::vector& tex1); 42 | 43 | static void idotC(const std::vector& tex0, 44 | const std::vector& tex1, double* idc); 45 | 46 | static void normalize(std::vector& tex); 47 | 48 | static float ssd(const std::vector& tex0, 49 | const std::vector& tex1); 50 | protected: 51 | }; 52 | 53 | Vec3f Cphoto::getColor(const float fx, const float fy, const int level) const { 54 | return Cimage::getColor(fx, fy, level); 55 | }; 56 | 57 | Vec3f Cphoto::getColor(const Vec4f& coord, const int level) const { 58 | const Vec3f icoord = project(coord, level); 59 | return Cimage::getColor(icoord[0], icoord[1], level); 60 | }; 61 | 62 | int Cphoto::getMask(const Vec4f& coord, const int level) const { 63 | if (m_masks[level].empty()) 64 | return 1; 65 | 66 | const Vec3f icoord = project(coord, level); 67 | return Cimage::getMask(icoord[0], icoord[1], level); 68 | }; 69 | 70 | int Cphoto::getEdge(const Vec4f& coord, const int level) const { 71 | if (m_edges[level].empty()) 72 | return 1; 73 | 74 | const Vec3f icoord = project(coord, level); 75 | 76 | if (icoord[0] < 0 || m_widths[level] - 1 <= icoord[0] || 77 | icoord[1] < 0 || m_heights[level] - 1 <= icoord[1]) 78 | return 0; 79 | 80 | return Cimage::getEdge(icoord[0], icoord[1], level); 81 | }; 82 | 83 | }; 84 | 85 | #endif // PHOTO_H 86 | -------------------------------------------------------------------------------- /program/base/image/photoSetS.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGE_PHOTOSETS_H 2 | #define IMAGE_PHOTOSETS_H 3 | 4 | #include 5 | #include "photo.h" 6 | 7 | namespace Image { 8 | 9 | class CphotoSetS { 10 | public: 11 | CphotoSetS(void); 12 | virtual ~CphotoSetS(); 13 | 14 | void init(const std::vector& images, const std::string prefix, 15 | const int maxLevel, const int size, const int alloc); 16 | 17 | // grabTex given 2D sampling information 18 | void grabTex(const int index, const int level, const Vec2f& icoord, 19 | const Vec2f& xaxis, const Vec2f& yaxis, 20 | std::vector& tex, const int normalizef = 1) const; 21 | 22 | // grabTex given 3D sampling information 23 | void grabTex(const int index, const int level, const Vec4f& coord, 24 | const Vec4f& pxaxis, const Vec4f& pyaxis, const Vec4f& pzaxis, 25 | std::vector& tex, float& weight, 26 | const int normalizef = 1) const; 27 | 28 | void write(const std::string outdir); 29 | void freePhotoSet(void); 30 | void freePhotoSet(const int level); 31 | 32 | void setEdge(const float threshold); 33 | 34 | inline Vec3f project(const int index, const Vec4f& coord, const int level) const; 35 | inline Vec3f mult(const int index, const Vec4f& coord, const int level) const; 36 | 37 | inline int getWidth(const int index, const int level) const; 38 | inline int getHeight(const int index, const int level) const; 39 | 40 | inline Vec3f getColor(const Vec4f& coord, const int index, 41 | const int level) const; 42 | inline Vec3f getColor(const int index, const float fx, const float fy, 43 | const int level) const; 44 | inline Vec3f getColor(const int index, const int ix, const int iy, 45 | const int level) const; 46 | 47 | inline int getMask(const Vec4f& coord, const int level) const; 48 | inline int getMask(const Vec4f& coord, const int index, const int level) const; 49 | inline int getMask(const int index, const float fx, const float fy, 50 | const int level) const; 51 | inline int getMask(const int index, const int ix, const int iy, 52 | const int level) const; 53 | 54 | inline int getEdge(const Vec4f& coord, const int index, const int level) const; 55 | inline int getEdge(const int index, const float fx, const float fy, 56 | const int level) const; 57 | inline int getEdge(const int index, const int ix, const int iy, 58 | const int level) const; 59 | 60 | static float incc(const std::vector >& texs, 61 | const std::vector& weights); 62 | 63 | int checkAngles(const Vec4f& coord, const std::vector& indexes, 64 | const float minAngle, const float maxAngle, 65 | const int tau) const; 66 | 67 | void getMinMaxAngles(const Vec4f& coord, const std::vector& indexes, 68 | float& minAngle, float& maxAngle) const; 69 | 70 | float computeDepth(const int index, const Vec4f& coord) const; 71 | 72 | // Take care of indexes 73 | std::vector m_images; 74 | std::vector m_photos; 75 | 76 | int image2index(const int image) const; 77 | std::map m_dict; 78 | 79 | // Number of cameras. 80 | int m_num; 81 | // Root directory 82 | std::string m_prefix; 83 | // maximum level 84 | int m_maxLevel; 85 | // Window size used to refine location 86 | int m_size; 87 | 88 | // getPAxes 89 | void getPAxes(const int index, const Vec4f& coord, const Vec4f& normal, 90 | Vec4f& pxaxis, Vec4f& pyaxis) const; 91 | 92 | // pairwise distance based on optical center and viewing direction 93 | void setDistances(void); 94 | std::vector > m_distances; 95 | }; 96 | 97 | Vec3f CphotoSetS::project(const int index, const Vec4f& coord, 98 | const int level) const{ 99 | return m_photos[index].project(coord, level); 100 | }; 101 | 102 | Vec3f CphotoSetS::mult(const int index, const Vec4f& coord, 103 | const int level) const{ 104 | return m_photos[index].mult(coord, level); 105 | }; 106 | 107 | int CphotoSetS::getWidth(const int index, const int level) const { 108 | return m_photos[index].getWidth(level); 109 | }; 110 | 111 | int CphotoSetS::getHeight(const int index, const int level) const { 112 | return m_photos[index].getHeight(level); 113 | }; 114 | 115 | Vec3f CphotoSetS::getColor(const Vec4f& coord, const int index, 116 | const int level) const { 117 | return m_photos[index].getColor(coord, level); 118 | }; 119 | 120 | Vec3f CphotoSetS::getColor(const int index, const float fx, const float fy, 121 | const int level) const { 122 | return m_photos[index].Image::Cimage::getColor(fx, fy, level); 123 | }; 124 | 125 | Vec3f CphotoSetS::getColor(const int index, const int ix, const int iy, 126 | const int level) const { 127 | return m_photos[index].Image::Cimage::getColor(ix, iy, level); 128 | }; 129 | 130 | int CphotoSetS::getMask(const Vec4f& coord, const int level) const { 131 | for (int index = 0; index < m_num; ++index) 132 | if (getMask(coord, index, level) == 0) 133 | return 0; 134 | return 1; 135 | }; 136 | 137 | int CphotoSetS::getMask(const Vec4f& coord, const int index, 138 | const int level) const { 139 | return m_photos[index].getMask(coord, level); 140 | }; 141 | 142 | int CphotoSetS::getMask(const int index, const float fx, const float fy, 143 | const int level) const { 144 | return m_photos[index].Image::Cimage::getMask(fx, fy, level); 145 | }; 146 | 147 | int CphotoSetS::getMask(const int index, const int ix, const int iy, 148 | const int level) const { 149 | return m_photos[index].Image::Cimage::getMask(ix, iy, level); 150 | }; 151 | 152 | int CphotoSetS::getEdge(const Vec4f& coord, const int index, 153 | const int level) const { 154 | return m_photos[index].getEdge(coord, level); 155 | }; 156 | 157 | int CphotoSetS::getEdge(const int index, const float fx, const float fy, 158 | const int level) const { 159 | return m_photos[index].Image::Cimage::getEdge(fx, fy, level); 160 | }; 161 | 162 | int CphotoSetS::getEdge(const int index, const int ix, const int iy, 163 | const int level) const { 164 | return m_photos[index].Image::Cimage::getEdge(ix, iy, level); 165 | }; 166 | 167 | }; 168 | 169 | #endif // IMAGE_PHOTOSETS_H 170 | 171 | -------------------------------------------------------------------------------- /program/base/numeric/mat2.h: -------------------------------------------------------------------------------- 1 | #ifndef NUMERIC_MAT2_H 2 | #define NUMERIC_MAT2_H 3 | 4 | #include "vec2.h" 5 | 6 | template 7 | class TMat2 8 | { 9 | private: 10 | TVec2 m_row[2]; 11 | 12 | public: 13 | // Standard constructors 14 | // 15 | TMat2() { *this = 0.0; } 16 | TMat2(T a, T b, T c, T d) 17 | { m_row[0][0]=a; m_row[0][1]=b; m_row[1][0]=c; m_row[1][1]=d; } 18 | TMat2(const TVec2 &r0,const TVec2 &r1) { m_row[0]=r0; m_row[1]=r1; } 19 | TMat2(const TMat2 &m) { *this = m; } 20 | 21 | // Descriptive interface 22 | // 23 | typedef T value_type; 24 | typedef TVec2 vector_type; 25 | typedef TMat2 inverse_type; 26 | static int dim() { return 2; } 27 | 28 | // Access methods note: A(i, j) == row i, col j 29 | // 30 | T& operator()(int i, int j) { return m_row[i][j]; } 31 | T operator()(int i, int j) const { return m_row[i][j]; } 32 | TVec2& operator[](int i) { return m_row[i]; } 33 | const TVec2& operator[](int i) const { return m_row[i]; } 34 | inline TVec2 col(int i) const {return TVec2(m_row[0][i],m_row[1][i]);} 35 | 36 | operator T*() { return m_row[0]; } 37 | operator const T*() { return m_row[0]; } 38 | operator const T*() const { return m_row[0]; } 39 | 40 | // Assignment methods 41 | // 42 | inline TMat2& operator=(const TMat2& m); 43 | inline TMat2& operator=(T s); 44 | 45 | inline TMat2& operator+=(const TMat2& m); 46 | inline TMat2& operator-=(const TMat2& m); 47 | inline TMat2& operator*=(T s); 48 | inline TMat2& operator/=(T s); 49 | 50 | inline bool operator==(const TMat2& m) const; 51 | inline bool operator!=(const TMat2& m) const; 52 | 53 | 54 | // Construction of standard matrices 55 | // 56 | static TMat2 I(); 57 | static TMat2 outer_product(const TVec2 &u, const TVec2 &v) 58 | { return TMat2(u[0]*v[0], u[0]*v[1], u[1]*v[0], u[1]*v[1]); } 59 | static TMat2 outer_product(const TVec2 &u) { return outer_product(u,u); } 60 | 61 | TMat2 &diag(T d); 62 | TMat2 &ident() { return diag(1.0); } 63 | }; 64 | 65 | //////////////////////////////////////////////////////////////////////// 66 | // 67 | // Method definitions 68 | // 69 | 70 | template 71 | inline TMat2& TMat2::operator=(const TMat2& m) 72 | { m_row[0]=m[0]; m_row[1]=m[1]; return *this; } 73 | 74 | template 75 | inline TMat2& TMat2::operator=(T s) 76 | { m_row[0]=s; m_row[1]=s; return *this; } 77 | 78 | template 79 | inline TMat2& TMat2::operator+=(const TMat2& m) 80 | { m_row[0] += m.m_row[0]; m_row[1] += m.m_row[1]; return *this;} 81 | 82 | template 83 | inline TMat2& TMat2::operator-=(const TMat2& m) 84 | { m_row[0] -= m.m_row[0]; m_row[1] -= m.m_row[1]; return *this; } 85 | 86 | template 87 | inline TMat2& TMat2::operator*=(T s) 88 | { m_row[0] *= s; m_row[1] *= s; return *this; } 89 | 90 | template 91 | inline TMat2& TMat2::operator/=(T s) 92 | { m_row[0] /= s; m_row[1] /= s; return *this; } 93 | 94 | template 95 | inline bool TMat2::operator==(const TMat2& m) const { 96 | if (m_row[0] == m.m_row[0] && m_row[1] == m.m_row[1]) 97 | return true; 98 | else 99 | return false; 100 | } 101 | 102 | template 103 | inline bool TMat2::operator!=(const TMat2& m) const { 104 | return !(*this == m); 105 | } 106 | 107 | //////////////////////////////////////////////////////////////////////// 108 | // 109 | // Operator definitions 110 | // 111 | 112 | template 113 | inline TMat2 operator+(const TMat2 &n, const TMat2 &m) 114 | { return TMat2(n[0]+m[0], n[1]+m[1]); } 115 | 116 | template 117 | inline TMat2 operator-(const TMat2 &n, const TMat2 &m) 118 | { return TMat2(n[0]-m[0], n[1]-m[1]); } 119 | 120 | template 121 | inline TMat2 operator-(const TMat2 &m) 122 | { return TMat2(-m[0], -m[1]); } 123 | 124 | template 125 | inline TMat2 operator*(T s, const TMat2 &m) 126 | { return TMat2(m[0]*s, m[1]*s); } 127 | 128 | template 129 | inline TMat2 operator*(const TMat2 &m, T s) 130 | { return s*m; } 131 | 132 | template 133 | inline TMat2 operator/(const TMat2 &m, T s) 134 | { return TMat2(m[0]/s, m[1]/s); } 135 | 136 | template 137 | inline TVec2 operator*(const TMat2 &m, const TVec2 &v) 138 | { return TVec2(m[0]*v, m[1]*v); } 139 | 140 | template 141 | extern TMat2 operator*(const TMat2 &n, const TMat2 &m); 142 | 143 | template 144 | inline std::ostream &operator<<(std::ostream &out, const TMat2& M) 145 | { return out << M[0] << std::endl << M[1]; } 146 | 147 | template 148 | inline std::istream &operator>>(std::istream &in, TMat2& M) 149 | { return in >> M[0] >> M[1]; } 150 | 151 | //////////////////////////////////////////////////////////////////////// 152 | // 153 | // Misc. function definitions 154 | // 155 | 156 | template 157 | inline T det(const TMat2 &m) 158 | { return m(0,0)*m(1,1) - m(0,1)*m(1,0); } 159 | 160 | template 161 | inline T trace(const TMat2 &m) 162 | { return m(0,0) + m(1,1); } 163 | 164 | template 165 | inline TMat2 transpose(const TMat2 &m) 166 | { return TMat2(m.col(0), m.col(1)); } 167 | 168 | template 169 | inline TMat2 adjoint(const TMat2 &m) 170 | { return TMat2(perp(m[1]), -perp(m[0])); } 171 | 172 | 173 | template 174 | TMat2 TMat2::I() { return TMat2(1,0, 0,1); } 175 | 176 | template 177 | TMat2 &TMat2::diag(T d) 178 | { 179 | m_row[0][0] = d; m_row[0][1] = 0; 180 | m_row[1][0] = 0; m_row[1][1] = d; 181 | 182 | return *this; 183 | } 184 | 185 | template 186 | TMat2 operator*(const TMat2 &n, const TMat2& m) 187 | { 188 | TMat2 A; 189 | int i,j; 190 | 191 | for(i=0;i<2;i++) 192 | for(j=0;j<2;j++) 193 | A(i,j) = n[i]*m.col(j); 194 | 195 | return A; 196 | } 197 | 198 | template 199 | T invert(TMat2 &inv, const TMat2 &m) 200 | { 201 | T d = det(m); 202 | 203 | if( d==0.0 ) 204 | return 0.0; 205 | 206 | inv(0, 0) = m(1,1)/d; 207 | inv(0, 1) = -m(0,1)/d; 208 | inv(1, 0) = -m(1,0)/d; 209 | inv(1, 1) = m(0,0)/d; 210 | 211 | return d; 212 | } 213 | 214 | template 215 | bool eigenvalues(const TMat2& M, TVec2& evals) 216 | { 217 | T B = -M(0,0)-M(1,1); 218 | T C = det(M); 219 | 220 | T dis = B*B - 4.0*C; 221 | if( dis< 1e-6 ) 222 | return false; 223 | else 224 | { 225 | T s = sqrt(dis); 226 | 227 | evals[0] = 0.5*(-B + s); 228 | evals[1] = 0.5*(-B - s); 229 | return true; 230 | } 231 | } 232 | 233 | template 234 | bool eigenvectors(const TMat2& M, const TVec2& evals, TVec2 evecs[2]) 235 | { 236 | evecs[0] = Vec2(-M(0,1), M(0,0)-evals[0]); 237 | evecs[1] = Vec2(-M(0,1), M(0,0)-evals[1]); 238 | 239 | unitize(evecs[0]); 240 | unitize(evecs[1]); 241 | 242 | return true; 243 | } 244 | 245 | template 246 | bool eigen(const TMat2& M, TVec2& evals, TVec2 evecs[2]) 247 | { 248 | bool result = eigenvalues(M, evals); 249 | if( result ) 250 | eigenvectors(M, evals, evecs); 251 | return result; 252 | } 253 | 254 | typedef TMat2 Mat2; 255 | typedef TMat2 Mat2f; 256 | 257 | #endif // MAT2_H 258 | -------------------------------------------------------------------------------- /program/base/numeric/mylapack.cc: -------------------------------------------------------------------------------- 1 | #include "mylapack.h" 2 | #include 3 | #include 4 | 5 | extern "C" { 6 | //#include 7 | //#include 8 | #include 9 | }; 10 | #define integer int 11 | 12 | using namespace std; 13 | 14 | // Solve Ax = 0. 15 | // Values contain singular values stored in an increasing order 16 | void Cmylapack::hlls(const std::vector >& A, 17 | std::vector& vec, 18 | std::vector& values) { 19 | char jobu = 'N'; char jobvt = 'S'; 20 | integer M = (int)A.size(); 21 | if (M == 0) { 22 | cerr << "Error in hlls" << endl; exit (1); 23 | } 24 | integer N = (int)A[0].size(); 25 | 26 | float C[M * N]; 27 | int count = 0; 28 | for (int x = 0; x < N; ++x) 29 | for (int y = 0; y < M; ++y) { 30 | C[count++] = A[y][x]; 31 | } 32 | integer lda = M; 33 | float S[M]; 34 | integer LDU = 1; 35 | float VT[N * N]; 36 | integer LDVT = N; 37 | integer lwork = 5 * max(N, M); 38 | float work[lwork]; 39 | integer info; 40 | 41 | sgesvd_(&jobu, &jobvt, &M, &N, C, &lda, S, NULL, &LDU, 42 | VT, &LDVT, work, &lwork, &info); 43 | 44 | vec.resize(N); 45 | values.resize(N); 46 | for (int i = 0; i < N; ++i) { 47 | vec[i] = VT[N * (i + 1) - 1]; 48 | values[i] = S[N - 1 - i]; 49 | } 50 | } 51 | 52 | // Solve Ax = 0. 53 | // Values contain singular values stored in an increasing order 54 | void Cmylapack::hlls(const std::vector >& A, 55 | std::vector& vec, 56 | std::vector& values) { 57 | 58 | char jobu = 'N'; char jobvt = 'S'; 59 | integer M = (int)A.size(); 60 | if (M == 0) { 61 | cerr << "Error in hlls" << endl; exit (1); 62 | } 63 | integer N = (int)A[0].size(); 64 | 65 | double C[M * N]; 66 | int count = 0; 67 | for (int x = 0; x < N; ++x) 68 | for (int y = 0; y < M; ++y) { 69 | C[count++] = A[y][x]; 70 | } 71 | integer lda = M; 72 | double S[M]; 73 | integer LDU = 1; 74 | double VT[N * N]; 75 | integer LDVT = N; 76 | integer lwork = 5 * max(N, M); 77 | double work[lwork]; 78 | integer info; 79 | 80 | dgesvd_(&jobu, &jobvt, &M, &N, C, &lda, S, NULL, &LDU, 81 | VT, &LDVT, work, &lwork, &info); 82 | 83 | vec.resize(N); 84 | values.resize(N); 85 | for (int i = 0; i < N; ++i) { 86 | vec[i] = VT[N * (i + 1) - 1]; 87 | values[i] = S[N - 1 - i]; 88 | } 89 | } 90 | 91 | void Cmylapack::lls(const std::vector >& A, 92 | const std::vector& b, 93 | std::vector& ans) { 94 | char trans = 'N'; 95 | integer m = (int)A.size(); 96 | integer n = (int)A[0].size(); 97 | integer nrhs = 1; 98 | vector a; 99 | a.resize(m * n); 100 | 101 | int count = 0; 102 | for (int x = 0; x < n; ++x) 103 | for (int y = 0; y < m; ++y) 104 | a[count++] = A[y][x]; 105 | integer lda = m; 106 | vector b2; 107 | b2.resize(m); 108 | for (int i = 0; i < m; ++i) 109 | b2[i] = b[i]; 110 | 111 | integer ldb = m; 112 | integer lwork = n + m; 113 | vector work; 114 | work.resize(lwork); 115 | integer info; 116 | sgels_(&trans, &m, &n, &nrhs, &a[0], &lda, &b2[0], &ldb, &work[0], 117 | &lwork, &info); 118 | 119 | ans.resize(n); 120 | for (int i = 0; i < n; ++i) 121 | ans[i] = b2[i]; 122 | } 123 | 124 | void Cmylapack::lls(const std::vector >& A, 125 | const std::vector& b, 126 | std::vector& ans) { 127 | char trans = 'N'; 128 | integer m = (int)A.size(); 129 | integer n = (int)A[0].size(); 130 | integer nrhs = 1; 131 | vector a; 132 | a.resize(m * n); 133 | 134 | int count = 0; 135 | for (int x = 0; x < n; ++x) 136 | for (int y = 0; y < m; ++y) 137 | a[count++] = A[y][x]; 138 | integer lda = m; 139 | vector b2; 140 | b2.resize(m); 141 | for (int i = 0; i < m; ++i) 142 | b2[i] = b[i]; 143 | 144 | integer ldb = m; 145 | integer lwork = n + m; 146 | vector work; 147 | work.resize(lwork); 148 | integer info; 149 | dgels_(&trans, &m, &n, &nrhs, &a[0], &lda, &b2[0], &ldb, &work[0], 150 | &lwork, &info); 151 | 152 | ans.resize(n); 153 | for (int i = 0; i < n; ++i) 154 | ans[i] = b2[i]; 155 | } 156 | 157 | void Cmylapack::lls(std::vector& A, 158 | std::vector& b, 159 | integer width, integer height) { 160 | char trans = 'N'; 161 | integer nrhs = 1; 162 | integer lwork = width * height; 163 | integer info; 164 | vector work(width * height); 165 | 166 | sgels_(&trans, &width, &height, &nrhs, &A[0], &width, &b[0], &width, &work[0], 167 | &lwork, &info); 168 | } 169 | 170 | void Cmylapack::lls(std::vector& A, 171 | std::vector& b, 172 | integer width, integer height) { 173 | char trans = 'N'; 174 | integer nrhs = 1; 175 | integer lwork = width * height; 176 | integer info; 177 | vector work(width * height); 178 | 179 | dgels_(&trans, &width, &height, &nrhs, &A[0], &width, &b[0], &width, &work[0], 180 | &lwork, &info); 181 | } 182 | 183 | // SVD 184 | void Cmylapack::svd(const std::vector >& A, 185 | std::vector >& U, 186 | std::vector >& VT, 187 | std::vector& S) { 188 | char jobu = 'A'; char jobvt = 'A'; 189 | integer M = (int)A.size(); 190 | if (M == 0) { 191 | cerr << "Error in hlls" << endl; exit (1); 192 | } 193 | integer N = (int)A[0].size(); 194 | 195 | float C[M * N]; 196 | int count = 0; 197 | for (int x = 0; x < N; ++x) 198 | for (int y = 0; y < M; ++y) { 199 | C[count++] = A[y][x]; 200 | } 201 | const integer minMN = min(M, N); 202 | integer lda = M; 203 | float S2[minMN]; 204 | float U2[M * M]; 205 | integer LDU = M; 206 | float VT2[N * N]; 207 | integer LDVT = N; 208 | integer lwork = 5 * max(N, M); 209 | float work[lwork]; 210 | integer info; 211 | 212 | sgesvd_(&jobu, &jobvt, &M, &N, C, &lda, S2, U2, &LDU, 213 | VT2, &LDVT, work, &lwork, &info); 214 | 215 | U.resize(M); 216 | for (int y = 0; y < M; ++y) 217 | U[y].resize(M); 218 | 219 | VT.resize(N); 220 | for (int y = 0; y < N; ++y) 221 | VT[y].resize(N); 222 | 223 | count = 0; 224 | for (int x = 0; x < M; ++x) 225 | for (int y = 0; y < M; ++y) 226 | U[y][x] = U2[count++]; 227 | 228 | count = 0; 229 | for (int x = 0; x < N; ++x) 230 | for (int y = 0; y < N; ++y) 231 | VT[y][x] = VT2[count++]; 232 | 233 | S.resize(minMN); 234 | for (int i = 0; i < minMN; ++i) 235 | S[i] = S2[i]; 236 | } 237 | -------------------------------------------------------------------------------- /program/base/numeric/mylapack.h: -------------------------------------------------------------------------------- 1 | #ifndef NUMERIC_MYLAPACK_H 2 | #define NUMERIC_MYLAPACK_H 3 | 4 | #include 5 | 6 | class Cmylapack { 7 | public: 8 | 9 | 10 | // Solve Ax = 0. 11 | // Values contain singular values stored in an increasing order 12 | static void hlls(const std::vector >& A, 13 | std::vector& vec, 14 | std::vector& values); 15 | 16 | static void hlls(const std::vector >& A, 17 | std::vector& vec, 18 | std::vector& values); 19 | 20 | // Solve Ax = b 21 | static void lls(const std::vector >& A, 22 | const std::vector& b, 23 | std::vector& x); 24 | 25 | static void lls(const std::vector >& A, 26 | const std::vector& b, 27 | std::vector& x); 28 | 29 | static void lls(std::vector& A, 30 | std::vector& b, 31 | int width, int height); 32 | 33 | static void lls(std::vector& A, 34 | std::vector& b, 35 | int width, int height); 36 | 37 | // SVD 38 | // A = U Sigma V^T 39 | static void svd(const std::vector >& A, 40 | std::vector >& U, 41 | std::vector >& VT, 42 | std::vector& S); 43 | 44 | }; 45 | 46 | #endif // NUMERIC_MYLAPACK_H 47 | -------------------------------------------------------------------------------- /program/base/numeric/vec3.h: -------------------------------------------------------------------------------- 1 | #ifndef NUMERIC_VEC3_H 2 | #define NUMERIC_VEC3_H 3 | 4 | #include 5 | #include "vec2.h" 6 | 7 | template 8 | class TVec3 { 9 | private: 10 | T m_elt[3]; 11 | 12 | public: 13 | // Standard constructors 14 | // 15 | TVec3(T s=0) { *this = s; } 16 | TVec3(T x, T y, T z) { m_elt[0]=x; m_elt[1]=y; m_elt[2]=z; } 17 | 18 | // Copy constructors & assignment operators 19 | template TVec3(const TVec3& v) { *this = v; } 20 | template TVec3(const TVec2& v,T w) 21 | { m_elt[0]=v[0]; m_elt[1]=v[1]; m_elt[2]=w; } 22 | 23 | template TVec3(const U v[3]) 24 | { m_elt[0]=v[0]; m_elt[1]=v[1]; m_elt[2]=v[2]; } 25 | 26 | template TVec3& operator=(const TVec3& v) 27 | { m_elt[0]=v[0]; m_elt[1]=v[1]; m_elt[2]=v[2]; return *this; } 28 | TVec3& operator=(T s) { m_elt[0]=m_elt[1]=m_elt[2]=s; return *this; } 29 | 30 | // Descriptive interface 31 | // 32 | typedef T value_type; 33 | static int size() { return 3; } 34 | 35 | // Access methods 36 | // 37 | operator T*() { return m_elt; } 38 | operator const T*() const { return m_elt; } 39 | 40 | T& operator[](int i) { return m_elt[i]; } 41 | T operator[](int i) const { return m_elt[i]; } 42 | operator const T*() { return m_elt; } 43 | 44 | // Assignment and in-place arithmetic methods 45 | // 46 | inline TVec3& operator+=(const TVec3& v); 47 | inline TVec3& operator-=(const TVec3& v); 48 | inline TVec3& operator*=(T s); 49 | inline TVec3& operator/=(T s); 50 | 51 | inline bool operator==(const TVec3& v) const; 52 | inline bool operator!=(const TVec3& v) const; 53 | 54 | inline T norm2(void) const{ 55 | return (*this) * (*this); 56 | } 57 | inline T norm(void) const{ 58 | return sqrt(norm2()); 59 | } 60 | inline void unitize(void) { 61 | const T denom2 = norm2(); 62 | 63 | if(denom2 != 1.0 && denom2 != 0.0 ) { 64 | const T denom = sqrt(denom2); 65 | m_elt[0] /= denom; 66 | m_elt[1] /= denom; 67 | m_elt[2] /= denom; 68 | } 69 | } 70 | inline T sum(void) const { 71 | return m_elt[0] + m_elt[1] + m_elt[2]; 72 | } 73 | 74 | }; 75 | 76 | //////////////////////////////////////////////////////////////////////// 77 | // 78 | // Method definitions 79 | // 80 | 81 | template inline TVec3& TVec3::operator+=(const TVec3& v) 82 | { m_elt[0] += v[0]; m_elt[1] += v[1]; m_elt[2] += v[2]; return *this; }; 83 | 84 | template inline TVec3& TVec3::operator-=(const TVec3& v) 85 | { m_elt[0] -= v[0]; m_elt[1] -= v[1]; m_elt[2] -= v[2]; return *this; }; 86 | 87 | template inline TVec3& TVec3::operator*=(T s) 88 | { m_elt[0] *= s; m_elt[1] *= s; m_elt[2] *= s; return *this; }; 89 | 90 | template inline TVec3& TVec3::operator/=(T s) 91 | { m_elt[0] /= s; m_elt[1] /= s; m_elt[2] /= s; return *this; }; 92 | 93 | template inline bool TVec3::operator==(const TVec3& v) const{ 94 | if (m_elt[0] == v.m_elt[0] && m_elt[1] == v.m_elt[1] && m_elt[2] == v.m_elt[2]) 95 | return true; 96 | else 97 | return false; 98 | }; 99 | 100 | template inline bool TVec3::operator!=(const TVec3& v) const{ 101 | return !(*this == v); 102 | }; 103 | 104 | //////////////////////////////////////////////////////////////////////// 105 | // 106 | // Operator definitions 107 | // 108 | 109 | template 110 | inline TVec3 operator+(const TVec3 &u, const TVec3& v) 111 | { return TVec3(u[0]+v[0], u[1]+v[1], u[2]+v[2]); }; 112 | 113 | template 114 | inline TVec3 operator-(const TVec3 &u, const TVec3& v) 115 | { return TVec3(u[0]-v[0], u[1]-v[1], u[2]-v[2]); }; 116 | 117 | template inline TVec3 operator-(const TVec3 &v) 118 | { return TVec3(-v[0], -v[1], -v[2]); }; 119 | 120 | template inline TVec3 operator*(N s, const TVec3 &v) 121 | { return TVec3(v[0]*s, v[1]*s, v[2]*s); }; 122 | template inline TVec3 operator*(const TVec3 &v, N s) 123 | { return s*v; }; 124 | 125 | template inline TVec3 operator/(const TVec3 &v, N s) 126 | { return TVec3(v[0]/s, v[1]/s, v[2]/s); }; 127 | 128 | template inline T operator*(const TVec3 &u, const TVec3& v) 129 | { return u[0]*v[0] + u[1]*v[1] + u[2]*v[2]; }; 130 | 131 | template inline TVec3 cross(const TVec3& u, const TVec3& v) 132 | { 133 | return TVec3( u[1]*v[2] - v[1]*u[2], 134 | -u[0]*v[2] + v[0]*u[2], 135 | u[0]*v[1] - v[0]*u[1] ); 136 | }; 137 | 138 | template 139 | inline TVec3 operator^(const TVec3& u, const TVec3& v) 140 | { return cross(u, v); }; 141 | 142 | 143 | template 144 | inline std::ostream &operator<<(std::ostream &out, const TVec3& v) 145 | { return out << v[0] << " " << v[1] << " " << v[2]; }; 146 | 147 | template 148 | inline std::istream &operator>>(std::istream &in, TVec3& v) 149 | { return in >> v[0] >> v[1] >> v[2]; }; 150 | 151 | //////////////////////////////////////////////////////////////////////// 152 | // 153 | // Misc. function definitions 154 | // 155 | 156 | template inline T norm2(const TVec3& v) { return v*v; }; 157 | template inline T norm(const TVec3& v) { return sqrt(norm2(v)); }; 158 | 159 | template inline void unitize(TVec3& v) 160 | { 161 | T l = norm2(v); 162 | if( l!=1.0 && l!=0.0 ) v /= sqrt(l); 163 | }; 164 | 165 | template inline TVec2 proj(const TVec3& v) 166 | { 167 | TVec2 u(v[0], v[1]); 168 | if( v[2]!=1.0 && v[2]!=0.0 ) 169 | u /= v[2]; 170 | return u; 171 | }; 172 | 173 | template inline void ortho(const TVec3& z, 174 | TVec3& x, TVec3& y) { 175 | if (fabs(z[0]) > 0.5) { 176 | x[0] = z[1]; x[1] = -z[0]; x[2] = 0; 177 | } 178 | else if (fabs(z[1]) > 0.5) { 179 | x[1] = z[2]; x[2] = -z[1]; x[0] = 0; 180 | } 181 | else { 182 | x[2] = z[0]; x[0] = -z[2]; x[1] = 0; 183 | } 184 | unitize(x); 185 | y = cross(z, x); 186 | }; 187 | 188 | template 189 | bool predVec30(const TVec3& lhs, const TVec3& rhs) { 190 | if (lhs[0] < rhs[0]) 191 | return true; 192 | else 193 | return false; 194 | }; 195 | 196 | template 197 | bool predVec31(const TVec3& lhs, const TVec3& rhs) { 198 | if (lhs[1] < rhs[1]) 199 | return true; 200 | else 201 | return false; 202 | }; 203 | 204 | template 205 | bool predVec32(const TVec3& lhs, const TVec3& rhs) { 206 | if (lhs[2] < rhs[2]) 207 | return true; 208 | else 209 | return false; 210 | }; 211 | 212 | typedef TVec3 Vec3; 213 | typedef TVec3 Vec3f; 214 | typedef TVec3 Vec3i; 215 | 216 | template 217 | struct Svec3cmp { 218 | bool operator()(const TVec3& lhs, const TVec3& rhs) const { 219 | if (lhs[0] < rhs[0] || 220 | (lhs[0] == rhs[0] && lhs[1] < rhs[1]) || 221 | (lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] < rhs[2])) 222 | return true; 223 | else 224 | return false; 225 | } 226 | }; 227 | 228 | #endif // VEC3_H 229 | -------------------------------------------------------------------------------- /program/base/numeric/vec4.h: -------------------------------------------------------------------------------- 1 | #ifndef NUMERIC_VEC4_H 2 | #define NUMERIC_VEC4_H 3 | 4 | #include 5 | #include "vec3.h" 6 | 7 | template 8 | class TVec4 { 9 | private: 10 | T m_elt[4]; 11 | 12 | public: 13 | // Standard constructors 14 | // 15 | TVec4(T s=0) { *this = s; } 16 | TVec4(T x, T y, T z, T w) { m_elt[0]=x; m_elt[1]=y; m_elt[2]=z; m_elt[3]=w; } 17 | 18 | // Copy constructors & assignment operators 19 | template TVec4(const TVec4& v) { *this = v; } 20 | template TVec4(const TVec3& v,T w) 21 | { m_elt[0]=v[0]; m_elt[1]=v[1]; m_elt[2]=v[2]; m_elt[3]=w; } 22 | template TVec4(const U v[4]) 23 | { m_elt[0]=v[0]; m_elt[1]=v[1]; m_elt[2]=v[2]; m_elt[3]=v[3]; } 24 | template TVec4& operator=(const TVec4& v) 25 | { m_elt[0]=v[0]; m_elt[1]=v[1]; m_elt[2]=v[2]; m_elt[3]=v[3]; return *this; } 26 | TVec4& operator=(T s) { m_elt[0]=m_elt[1]=m_elt[2]=m_elt[3]=s; return *this; } 27 | 28 | 29 | // Descriptive interface 30 | // 31 | typedef T value_type; 32 | static int size() { return 4; } 33 | 34 | // Access methods 35 | // 36 | operator T*() { return m_elt; } 37 | operator const T*() const { return m_elt; } 38 | 39 | T& operator[](int i) { return m_elt[i]; } 40 | T operator[](int i) const { return m_elt[i]; } 41 | operator const T*() { return m_elt; } 42 | 43 | // Assignment and in-place arithmetic methods 44 | // 45 | inline TVec4& operator+=(const TVec4& v); 46 | inline TVec4& operator-=(const TVec4& v); 47 | inline TVec4& operator*=(T s); 48 | inline TVec4& operator/=(T s); 49 | 50 | inline bool operator==(const TVec4& v) const; 51 | inline bool operator!=(const TVec4& v) const; 52 | 53 | inline T norm2(void) const{ 54 | return (*this) * (*this); 55 | } 56 | inline T norm(void) const{ 57 | return sqrt(norm2()); 58 | } 59 | inline void unitize(void) { 60 | const T denom2 = norm2(); 61 | 62 | if(denom2 != 1.0 && denom2 != 0.0 ) { 63 | const T denom = sqrt(denom2); 64 | m_elt[0] /= denom; m_elt[1] /= denom; 65 | m_elt[2] /= denom; m_elt[3] /= denom; 66 | } 67 | } 68 | }; 69 | 70 | //////////////////////////////////////////////////////////////////////// 71 | // 72 | // Method definitions 73 | // 74 | template inline TVec4& TVec4::operator+=(const TVec4& v) 75 | { m_elt[0]+=v[0]; m_elt[1]+=v[1]; m_elt[2]+=v[2]; m_elt[3]+=v[3]; return *this;}; 76 | 77 | template inline TVec4& TVec4::operator-=(const TVec4& v) 78 | { m_elt[0]-=v[0]; m_elt[1]-=v[1]; m_elt[2]-=v[2]; m_elt[3]-=v[3]; return *this;}; 79 | 80 | template inline TVec4& TVec4::operator*=(T s) 81 | { m_elt[0] *= s; m_elt[1] *= s; m_elt[2] *= s; m_elt[3] *= s; return *this; }; 82 | 83 | template inline TVec4& TVec4::operator/=(T s) 84 | { m_elt[0] /= s; m_elt[1] /= s; m_elt[2] /= s; m_elt[3] /= s; return *this; }; 85 | 86 | template inline bool TVec4::operator==(const TVec4& v) const{ 87 | if (m_elt[0] == v.m_elt[0] && m_elt[1] == v.m_elt[1] && 88 | m_elt[2] == v.m_elt[2] && m_elt[3] == v.m_elt[3]) 89 | return true; 90 | else 91 | return false; 92 | }; 93 | 94 | template inline bool TVec4::operator!=(const TVec4& v) const{ 95 | return !(*this == v); 96 | }; 97 | 98 | //////////////////////////////////////////////////////////////////////// 99 | // 100 | // Operator definitions 101 | // 102 | 103 | template 104 | inline TVec4 operator+(const TVec4 &u, const TVec4 &v) 105 | { return TVec4(u[0]+v[0], u[1]+v[1], u[2]+v[2], u[3]+v[3]); }; 106 | 107 | template 108 | inline TVec4 operator-(const TVec4 &u, const TVec4& v) 109 | { return TVec4(u[0]-v[0], u[1]-v[1], u[2]-v[2], u[3]-v[3]); }; 110 | 111 | template inline TVec4 operator-(const TVec4 &u) 112 | { return TVec4(-u[0], -u[1], -u[2], -u[3]); }; 113 | 114 | template inline TVec4 operator*(N s, const TVec4 &v) 115 | { return TVec4(v[0]*s, v[1]*s, v[2]*s, v[3]*s); }; 116 | template inline TVec4 operator*(const TVec4 &v, N s) 117 | { return s*v; }; 118 | 119 | template inline TVec4 operator/(const TVec4 &v, N s) 120 | { return TVec4(v[0]/s, v[1]/s, v[2]/s, v[3]/s); }; 121 | 122 | template inline T operator*(const TVec4 &u, const TVec4 &v) 123 | { return u[0]*v[0] + u[1]*v[1] + u[2]*v[2] + u[3]*v[3]; }; 124 | 125 | template 126 | inline std::ostream &operator<<(std::ostream &out, const TVec4& v) 127 | { return out < 130 | inline std::istream &operator>>(std::istream &in, TVec4& v) 131 | { return in >> v[0] >> v[1] >> v[2] >> v[3]; }; 132 | 133 | //////////////////////////////////////////////////////////////////////// 134 | // 135 | // Misc. function definitions 136 | // 137 | template 138 | inline TVec4 cross(const TVec4& a, const TVec4& b, const TVec4& c) 139 | { 140 | // Code adapted from VecLib4d.c in Graphics Gems V 141 | 142 | T d1 = (b[2] * c[3]) - (b[3] * c[2]); 143 | T d2 = (b[1] * c[3]) - (b[3] * c[1]); 144 | T d3 = (b[1] * c[2]) - (b[2] * c[1]); 145 | T d4 = (b[0] * c[3]) - (b[3] * c[0]); 146 | T d5 = (b[0] * c[2]) - (b[2] * c[0]); 147 | T d6 = (b[0] * c[1]) - (b[1] * c[0]); 148 | 149 | return TVec4(- a[1] * d1 + a[2] * d2 - a[3] * d3, 150 | a[0] * d1 - a[2] * d4 + a[3] * d5, 151 | - a[0] * d2 + a[1] * d4 - a[3] * d6, 152 | a[0] * d3 - a[1] * d5 + a[2] * d6); 153 | }; 154 | 155 | template 156 | inline TVec4 cross(const TVec4& u, const TVec4& v) { 157 | // Code adapted from VecLib4d.c in Graphics Gems V 158 | return TVec4(u[1]*v[2] - v[1]*u[2], 159 | -u[0]*v[2] + v[0]*u[2], 160 | u[0]*v[1] - v[0]*u[1], 161 | 0); 162 | }; 163 | 164 | template inline T norm2(const TVec4& v) { return v*v; }; 165 | template inline T norm(const TVec4& v) { return sqrt(norm2(v)); }; 166 | 167 | template inline void unitize(TVec4& v) 168 | { 169 | T l = norm2(v); 170 | if( l!=1.0 && l!=0.0 ) v /= sqrt(l); 171 | }; 172 | 173 | template inline TVec3 proj(const TVec4& v) 174 | { 175 | TVec3 u(v[0], v[1], v[2]); 176 | if( v[3]!=1.0 && v[3]!=0.0 ) 177 | u /= v[3]; 178 | return u; 179 | }; 180 | 181 | 182 | template 183 | bool predVec40(const TVec4& lhs, const TVec4& rhs) { 184 | if (lhs[0] < rhs[0]) 185 | return true; 186 | else 187 | return false; 188 | }; 189 | 190 | template 191 | bool predVec41(const TVec4& lhs, const TVec4& rhs) { 192 | if (lhs[1] < rhs[1]) 193 | return true; 194 | else 195 | return false; 196 | }; 197 | 198 | template 199 | bool predVec42(const TVec4& lhs, const TVec4& rhs) { 200 | if (lhs[2] < rhs[2]) 201 | return true; 202 | else 203 | return false; 204 | }; 205 | 206 | template 207 | bool predVec43(const TVec4& lhs, const TVec4& rhs) { 208 | if (lhs[3] < rhs[3]) 209 | return true; 210 | else 211 | return false; 212 | }; 213 | 214 | typedef TVec4 Vec4; 215 | typedef TVec4 Vec4f; 216 | typedef TVec4 Vec4i; 217 | 218 | template 219 | struct Svec4cmp { 220 | bool operator()(const TVec4& lhs, const TVec4& rhs) const { 221 | if (lhs[0] < rhs[0] || 222 | (lhs[0] == rhs[0] && lhs[1] < rhs[1]) || 223 | (lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] < rhs[2]) || 224 | (lhs[0] == rhs[0] && lhs[1] == rhs[1] && 225 | lhs[2] == rhs[2] && lhs[3] < rhs[3])) 226 | return true; 227 | else 228 | return false; 229 | } 230 | }; 231 | 232 | template inline void ortho(const TVec4& z, 233 | TVec4& x, TVec4& y) { 234 | if (fabs(z[0]) > 0.5) { 235 | x[0] = z[1]; x[1] = -z[0]; x[2] = 0; 236 | } 237 | else if (fabs(z[1]) > 0.5) { 238 | x[1] = z[2]; x[2] = -z[1]; x[0] = 0; 239 | } 240 | else { 241 | x[2] = z[0]; x[0] = -z[2]; x[1] = 0; 242 | } 243 | unitize(x); 244 | 245 | y[0] = z[1] * x[2] - z[2] * x[1]; 246 | y[1] = z[2] * x[0] - z[0] * x[2]; 247 | y[2] = z[0] * x[1] - z[1] * x[0]; 248 | }; 249 | 250 | #endif // VEC4_H 251 | -------------------------------------------------------------------------------- /program/base/pmvs/asyncQueue.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_ASYNC_QUEUE_H 2 | #define PMVS3_ASYNC_QUEUE_H 3 | #include 4 | #include 5 | 6 | namespace PMVS3 { 7 | template 8 | class CasyncQueue 9 | { 10 | public: 11 | CasyncQueue(int maxLength) : 12 | _maxLength(maxLength) 13 | { 14 | pthread_mutex_init(&_queueLock, NULL); 15 | pthread_cond_init(&_emptyCondition, NULL); 16 | pthread_cond_init(&_fullCondition, NULL); 17 | _numWaiting = 0; 18 | } 19 | 20 | ~CasyncQueue() 21 | { 22 | pthread_mutex_destroy(&_queueLock); 23 | pthread_cond_destroy(&_emptyCondition); 24 | pthread_cond_destroy(&_fullCondition); 25 | } 26 | 27 | void enqueue(T t) 28 | { 29 | pthread_mutex_lock(&_queueLock); 30 | if(_maxLength > 0) { 31 | while(_queue.size() >= _maxLength) { 32 | pthread_cond_wait(&_fullCondition, &_queueLock); 33 | } 34 | } 35 | _queue.push(t); 36 | pthread_cond_signal(&_emptyCondition); 37 | pthread_mutex_unlock(&_queueLock); 38 | } 39 | 40 | T dequeue() 41 | { 42 | pthread_mutex_lock(&_queueLock); 43 | _numWaiting++; 44 | while(_queue.empty()) { 45 | pthread_cond_wait(&_emptyCondition, &_queueLock); 46 | } 47 | T val = _queue.front(); 48 | _queue.pop(); 49 | pthread_cond_signal(&_fullCondition); 50 | _numWaiting--; 51 | pthread_mutex_unlock(&_queueLock); 52 | return val; 53 | } 54 | 55 | bool isEmpty() { 56 | pthread_mutex_lock(&_queueLock); 57 | bool isEmpty = _queue.empty(); 58 | pthread_mutex_unlock(&_queueLock); 59 | return isEmpty; 60 | } 61 | 62 | int numWaiting() { 63 | int rval; 64 | pthread_mutex_lock(&_queueLock); 65 | rval = _numWaiting; 66 | pthread_mutex_unlock(&_queueLock); 67 | return rval; 68 | } 69 | 70 | void clear() { 71 | pthread_mutex_lock(&_queueLock); 72 | while(!_queue.empty()) { 73 | _queue.pop(); 74 | } 75 | pthread_mutex_unlock(&_queueLock); 76 | } 77 | 78 | private: 79 | std::queue _queue; 80 | pthread_mutex_t _queueLock; 81 | pthread_cond_t _emptyCondition; 82 | pthread_cond_t _fullCondition; 83 | int _maxLength; 84 | int _numWaiting; 85 | }; 86 | } 87 | #endif 88 | -------------------------------------------------------------------------------- /program/base/pmvs/detectFeatures.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../image/image.h" 4 | #include "detectFeatures.h" 5 | #include "harris.h" 6 | #include "dog.h" 7 | #include "point.h" 8 | 9 | using namespace PMVS3; 10 | using namespace std; 11 | using namespace Image; 12 | 13 | CdetectFeatures::CdetectFeatures(void) { 14 | pthread_rwlock_init(&m_rwlock, NULL); 15 | } 16 | 17 | CdetectFeatures::~CdetectFeatures() { 18 | pthread_rwlock_destroy(&m_rwlock); 19 | } 20 | 21 | void CdetectFeatures::run(const CphotoSetS& pss, const int num, 22 | const int csize, const int level, 23 | const int CPU) { 24 | m_ppss = &pss; 25 | m_csize = csize; 26 | m_level = level; 27 | m_CPU = CPU; 28 | 29 | m_points.clear(); 30 | m_points.resize(num); 31 | 32 | //---------------------------------------------------------------------- 33 | for (int index = 0; index < num; ++index) 34 | m_jobs.push_back(index); 35 | 36 | pthread_t threads[m_CPU]; 37 | for (int i = 0; i < m_CPU; ++i) 38 | pthread_create(&threads[i], NULL, runThreadTmp, (void*)this); 39 | for (int i = 0; i < m_CPU; ++i) 40 | pthread_join(threads[i], NULL); 41 | //---------------------------------------------------------------------- 42 | cerr << "done" << endl; 43 | } 44 | 45 | void* CdetectFeatures::runThreadTmp(void* arg) { 46 | CdetectFeatures* detectFeatures = (CdetectFeatures*)arg; 47 | detectFeatures->runThread(); 48 | return NULL; 49 | } 50 | 51 | void CdetectFeatures::runThread(void) { 52 | while (1) { 53 | int index = -1; 54 | pthread_rwlock_wrlock(&m_rwlock); 55 | if (!m_jobs.empty()) { 56 | index = m_jobs.front(); 57 | m_jobs.pop_front(); 58 | } 59 | pthread_rwlock_unlock(&m_rwlock); 60 | if (index == -1) 61 | break; 62 | 63 | const int image = m_ppss->m_images[index]; 64 | cerr << image << ' ' << flush; 65 | 66 | //????????????? May need file lock, because targetting images 67 | //should not overlap among multiple processors. 68 | char buffer[1024]; 69 | sprintf(buffer, "%smodels/%08d.affin%d", m_ppss->m_prefix.c_str(), image, m_level); 70 | ifstream ifstr; 71 | ifstr.open(buffer); 72 | if (ifstr.is_open()) { 73 | ifstr.close(); 74 | continue; 75 | } 76 | ifstr.close(); 77 | 78 | //---------------------------------------------------------------------- 79 | // parameters 80 | // for harris 81 | const float sigma = 4.0f; 82 | // for DoG 83 | const float firstScale = 1.0f; const float lastScale = 3.0f; 84 | 85 | //---------------------------------------------------------------------- 86 | // Harris 87 | { 88 | Charris harris; 89 | multiset result; 90 | harris.run(m_ppss->m_photos[index].getImage(m_level), 91 | m_ppss->m_photos[index].Cimage::getMask(m_level), 92 | m_ppss->m_photos[index].Cimage::getEdge(m_level), 93 | m_ppss->m_photos[index].getWidth(m_level), 94 | m_ppss->m_photos[index].getHeight(m_level), m_csize, sigma, result); 95 | 96 | multiset::reverse_iterator rbegin = result.rbegin(); 97 | while (rbegin != result.rend()) { 98 | m_points[index].push_back(*rbegin); 99 | rbegin++; 100 | } 101 | } 102 | 103 | //---------------------------------------------------------------------- 104 | // DoG 105 | { 106 | Cdog dog; 107 | multiset result; 108 | dog.run(m_ppss->m_photos[index].getImage(m_level), 109 | m_ppss->m_photos[index].Cimage::getMask(m_level), 110 | m_ppss->m_photos[index].Cimage::getEdge(m_level), 111 | m_ppss->m_photos[index].getWidth(m_level), 112 | m_ppss->m_photos[index].getHeight(m_level), 113 | m_csize, firstScale, lastScale, result); 114 | 115 | multiset::reverse_iterator rbegin = result.rbegin(); 116 | while (rbegin != result.rend()) { 117 | m_points[index].push_back(*rbegin); 118 | rbegin++; 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /program/base/pmvs/detectFeatures.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_DETECTFEATURES_H 2 | #define PMVS3_DETECTFEATURES_H 3 | 4 | /* 5 | * A main class to detect features 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include "../image/photoSetS.h" 12 | #include "point.h" 13 | 14 | namespace Image { 15 | class CphotoSetS; 16 | }; 17 | 18 | namespace PMVS3 { 19 | 20 | class CdetectFeatures { 21 | public: 22 | CdetectFeatures(void); 23 | virtual ~CdetectFeatures(); 24 | 25 | void run(const Image::CphotoSetS& pss, 26 | const int num, const int csize, const int level, 27 | const int CPU = 1); 28 | 29 | std::vector > m_points; 30 | 31 | protected: 32 | const Image::CphotoSetS* m_ppss; 33 | int m_csize; 34 | int m_level; 35 | 36 | //---------------------------------------------------------------------- 37 | // thread related 38 | //---------------------------------------------------------------------- 39 | pthread_rwlock_t m_rwlock; 40 | int m_CPU; 41 | 42 | std::list m_jobs; 43 | 44 | void runThread(void); 45 | static void* runThreadTmp(void*arg); 46 | }; 47 | }; 48 | 49 | #endif // PMVS3_DETECTFEATURES_H 50 | -------------------------------------------------------------------------------- /program/base/pmvs/detector.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "point.h" 3 | #include "detector.h" 4 | 5 | using namespace PMVS3; 6 | using namespace std; 7 | 8 | void Cdetector::setGaussD(const float sigmaD, std::vector& gaussD) { 9 | //---------------------------------------------------------------------- 10 | const int marginD = (int)ceil(2 * sigmaD); 11 | const int sizeD = 2 * marginD + 1; 12 | 13 | gaussD.resize(sizeD); 14 | 15 | //---------------------------------------------------------------------- 16 | // set m_gaussD 17 | float denom = 0.0; 18 | for (int x = 0; x < sizeD; ++x) { 19 | int xtmp = x - marginD; 20 | const float dtmp = xtmp * exp(- (xtmp * xtmp) / (2 * sigmaD * sigmaD)); 21 | gaussD[x] = dtmp; 22 | if (0.0 < dtmp) 23 | denom += dtmp; 24 | } 25 | 26 | for (int x = 0; x < sizeD; ++x) 27 | gaussD[x] /= denom; 28 | } 29 | 30 | void Cdetector::setGaussI(const float sigmaI, std::vector& gaussI) { 31 | const int marginI = (int)ceil(2 * sigmaI); 32 | const int sizeI = 2 * marginI + 1; 33 | 34 | gaussI.resize(sizeI); 35 | 36 | //---------------------------------------------------------------------- 37 | // set m_gaussI 38 | float denom = 0.0; 39 | for (int x = 0; x < sizeI; ++x) { 40 | int xtmp = x - marginI; 41 | const float dtmp = exp(- (xtmp * xtmp) / (2 * sigmaI * sigmaI)); 42 | gaussI[x] = dtmp; 43 | denom += dtmp; 44 | } 45 | for (int x = 0; x < sizeI; ++x) 46 | gaussI[x] /= denom; 47 | } 48 | 49 | 50 | float Cdetector::setThreshold(std::multiset& grid) { 51 | float ave = 0.0; 52 | float ave2 = 0.0; 53 | multiset::iterator begin = grid.begin(); 54 | multiset::iterator end = grid.end(); 55 | int count = 0; 56 | while (begin != end) { 57 | count++; 58 | ave += begin->m_response; 59 | ave2 += begin->m_response * begin->m_response; 60 | begin++; 61 | } 62 | if (count == 0) 63 | count = 1; 64 | ave /= count; ave2 /= count; 65 | ave2 = sqrt(max(0.0f, ave2 - ave * ave)); 66 | const float threshold = ave + ave2; 67 | 68 | //cout << ave << ' ' << ave2 << endl; 69 | 70 | return threshold; 71 | } 72 | 73 | int Cdetector::isCloseBoundary(const int x, const int y, const int margin) const { 74 | if (m_mask.empty()) 75 | return 0; 76 | 77 | if (x - margin < 0 || m_width <= x + margin || 78 | y - margin < 0 || m_height <= y + margin) 79 | return 1; 80 | 81 | for (int j = -margin; j <= margin; ++j) { 82 | const int ytmp = y + j; 83 | for (int i = -margin; i <= margin; ++i) { 84 | const int xtmp = x + i; 85 | 86 | if (m_mask[ytmp][xtmp] == 0) 87 | return 1; 88 | } 89 | } 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /program/base/pmvs/detector.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_DETECTOR_H 2 | #define PMVS3_DETECTOR_H 3 | 4 | #include 5 | #include "point.h" 6 | 7 | namespace PMVS3 { 8 | class Cdetector { 9 | public: 10 | static void setGaussD(const float sigmaD, std::vector& gaussD); 11 | static void setGaussI(const float sigmaI, std::vector& gaussI); 12 | virtual ~Cdetector() { 13 | } 14 | 15 | protected: 16 | static float setThreshold(std::multiset& grid); 17 | int isCloseBoundary(const int x, const int y, const int margin) const; 18 | int m_width; 19 | int m_height; 20 | std::vector > m_image; 21 | std::vector > m_mask; 22 | 23 | public: 24 | template 25 | void convolveX(std::vector >& image, 26 | const std::vector >& mask, 27 | const std::vector& filter, 28 | std::vector >& buffer) { 29 | const int width = image[0].size(); 30 | const int height = image.size(); 31 | const int margin = ((int)filter.size()) / 2; 32 | 33 | for (int y = 0; y < height; ++y) { 34 | for (int x = 0; x < width; ++x) { 35 | buffer[y][x] *= 0.0; 36 | 37 | if (!mask.empty() && mask[y][x] == 0) 38 | continue; 39 | 40 | for (int j = 0; j < (int)filter.size(); ++j) { 41 | int xtmp = x + j - margin; 42 | if (xtmp < 0) 43 | xtmp = 0; 44 | else if (width <= xtmp) 45 | xtmp = width - 1; 46 | 47 | const int ytmp = y; 48 | 49 | if (!mask.empty() && mask[ytmp][xtmp] == 0) 50 | continue; 51 | 52 | buffer[y][x] += filter[j] * image[ytmp][xtmp]; 53 | } 54 | } 55 | } 56 | 57 | buffer.swap(image); 58 | } 59 | 60 | 61 | template 62 | void convolveY(std::vector >& image, 63 | const std::vector >& mask, 64 | const std::vector& filter, 65 | std::vector >& buffer) { 66 | const int width = image[0].size(); 67 | const int height = image.size(); 68 | const int margin = ((int)filter.size()) / 2; 69 | 70 | for (int y = 0; y < height; ++y) { 71 | for (int x = 0; x < width; ++x) { 72 | buffer[y][x] *= 0.0; 73 | 74 | if (!mask.empty() && mask[y][x] == 0) 75 | continue; 76 | 77 | for (int j = 0; j < (int)filter.size(); ++j) { 78 | const int xtmp = x; 79 | int ytmp = y + j - margin; 80 | if (ytmp < 0) 81 | ytmp = 0; 82 | else if (height <= ytmp) 83 | ytmp = height - 1; 84 | 85 | if (!mask.empty() && mask[ytmp][xtmp] == 0) 86 | continue; 87 | 88 | buffer[y][x] += filter[j] * image[ytmp][xtmp]; 89 | } 90 | } 91 | } 92 | 93 | buffer.swap(image); 94 | } 95 | 96 | template 97 | void convolveX(std::vector >& image, 98 | const std::vector& filter, 99 | std::vector >& buffer) { 100 | const int width = image[0].size(); 101 | const int height = image.size(); 102 | const int margin = ((int)filter.size()) / 2; 103 | 104 | for (int y = 0; y < height; ++y) { 105 | for (int x = 0; x < width; ++x) { 106 | buffer[y][x] *= 0.0; 107 | 108 | for (int j = 0; j < (int)filter.size(); ++j) { 109 | const int xtmp = x + j - margin; 110 | const int ytmp = y; 111 | if (xtmp < 0 || width <= xtmp) 112 | continue; 113 | 114 | buffer[y][x] += filter[j] * image[ytmp][xtmp]; 115 | } 116 | } 117 | } 118 | 119 | buffer.swap(image); 120 | } 121 | 122 | 123 | template 124 | void convolveY(std::vector >& image, 125 | const std::vector& filter, 126 | std::vector >& buffer) { 127 | const int width = image[0].size(); 128 | const int height = image.size(); 129 | const int margin = ((int)filter.size()) / 2; 130 | 131 | for (int y = 0; y < height; ++y) { 132 | for (int x = 0; x < width; ++x) { 133 | buffer[y][x] *= 0.0; 134 | 135 | for (int j = 0; j < (int)filter.size(); ++j) { 136 | const int xtmp = x; 137 | const int ytmp = y + j - margin; 138 | if (ytmp < 0 || height <= ytmp) 139 | continue; 140 | 141 | buffer[y][x] += filter[j] * image[ytmp][xtmp]; 142 | } 143 | } 144 | } 145 | 146 | buffer.swap(image); 147 | } 148 | }; 149 | }; 150 | 151 | #endif // PMVS3_DETECTOR_H 152 | -------------------------------------------------------------------------------- /program/base/pmvs/dog.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_DOG_H 2 | #define PMVS3_DOG_H 3 | 4 | #include 5 | #include 6 | #include "../numeric/vec3.h" 7 | #include "detector.h" 8 | #include "point.h" 9 | 10 | namespace PMVS3 { 11 | class Cdog: public Cdetector { 12 | public: 13 | void run (const std::vector& image, 14 | const std::vector& mask, 15 | const std::vector& edge, 16 | const int width, const int height, 17 | const int gspeedup, 18 | const float firstScale, // 1.4f 19 | const float lastScale, // 4.0f 20 | std::multiset & result); 21 | 22 | virtual ~Cdog() { 23 | } 24 | 25 | protected: 26 | float m_firstScale; 27 | float m_lastScale; 28 | 29 | void init(const std::vector& image, 30 | const std::vector& mask, 31 | const std::vector& edge); 32 | 33 | void setRes(const float sigma, 34 | std::vector >& res); 35 | 36 | static int isLocalMax(const std::vector >& pdog, 37 | const std::vector >& cdog, 38 | const std::vector >& ndog, 39 | const int x, const int y); 40 | 41 | static int isLocalMax(const std::vector >& dog, 42 | const int x, const int y); 43 | 44 | static int notOnEdge(const std::vector >& dog, int x, int y); 45 | 46 | static float getResponse(const std::vector >& pdog, 47 | const std::vector >& cdog, 48 | const std::vector >& ndog, 49 | const int x, const int y); 50 | 51 | static float getResponse(const std::vector >& dog, 52 | const int x, const int y); 53 | 54 | static void setDOG(const std::vector >& cres, 55 | const std::vector >& nres, 56 | std::vector >& dog); 57 | 58 | }; 59 | }; 60 | #endif // DOG_H 61 | -------------------------------------------------------------------------------- /program/base/pmvs/expand.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_EXPAND_H 2 | #define PMVS3_EXPAND_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "patchOrganizerS.h" 8 | #include "refineThread.h" 9 | 10 | namespace PMVS3 { 11 | class CfindMatch; 12 | 13 | class Cexpand { 14 | public: 15 | Cexpand(CfindMatch& findMatch); 16 | ~Cexpand(); 17 | 18 | void init(void); 19 | void run(void); 20 | 21 | float computeRadius(const Patch::Cpatch& patch); 22 | 23 | protected: 24 | int expandSub(const Patch::Ppatch& orgppatch, const int id, 25 | const Vec4f& canCoord); 26 | int postProcessSub(const Patch::Ppatch& newppatch, const int id); 27 | 28 | int updateCounts(const Patch::Cpatch& patch); 29 | 30 | int checkCounts(Patch::Cpatch& patch); 31 | 32 | void findEmptyBlocks(const Patch::Ppatch& ppatch, 33 | std::vector >& canCoords); 34 | protected: 35 | 36 | std::priority_queue, P_compare> 37 | m_queue; 38 | pthread_cond_t m_emptyCondition; 39 | pthread_mutex_t m_queueLock; 40 | 41 | CfindMatch& m_fm; 42 | 43 | //----------------------------------------------------------------- 44 | // thread related 45 | //----------------------------------------------------------------- 46 | void expandThread(void); 47 | static void* expandThreadTmp(void* arg); 48 | 49 | void postProcessThread(void); 50 | static void* postProcessThreadTmp(void *arg); 51 | 52 | CasyncQueue m_idQueue; 53 | CasyncQueue m_postProcessQueue; 54 | CrefineThread m_refineThread; 55 | int m_numPatchesInFlight; 56 | 57 | // Number of trials 58 | std::vector m_ecounts; 59 | // Number of failures in the prep 60 | std::vector m_fcounts0; 61 | // Number of failures in the post processing 62 | std::vector m_fcounts1; 63 | // Number passes 64 | std::vector m_pcounts; 65 | 66 | }; 67 | }; 68 | 69 | #endif // PMVS3_EXPAND_H 70 | -------------------------------------------------------------------------------- /program/base/pmvs/filter.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_FILTER_H 2 | #define PMVS3_FILTER_H 3 | 4 | #include "patch.h" 5 | #include 6 | #include "../numeric/vec2.h" 7 | 8 | namespace PMVS3 { 9 | 10 | class CfindMatch; 11 | 12 | class Cfilter { 13 | public: 14 | Cfilter(CfindMatch& findMatch); 15 | 16 | void init(void); 17 | void run(void); 18 | 19 | float computeGain(const Patch::Cpatch& patch, const int lock); 20 | 21 | int filterQuad(const Patch::Cpatch& patch, 22 | const std::vector& neighbors) const; 23 | 24 | 25 | protected: 26 | void filterOutside(void); 27 | void filterOutsideThread(void); 28 | static void* filterOutsideThreadTmp(void* arg); 29 | 30 | void filterExact(void); 31 | void filterExactThread(void); 32 | static void* filterExactThreadTmp(void* arg); 33 | 34 | void filterNeighbor(const int time); 35 | void filterSmallGroups(void); 36 | void filterSmallGroupsSub(const int pid, const int id, 37 | std::vector& label, 38 | std::list& ltmp) const; 39 | void setDepthMaps(void); 40 | void setDepthMapsVGridsVPGridsAddPatchV(const int additive); 41 | 42 | void setConf(const int image); 43 | 44 | std::vector m_gains; 45 | 46 | std::vector > m_newimages, m_removeimages; 47 | std::vector > > m_newgrids, m_removegrids; 48 | 49 | int m_time; 50 | std::vector m_rejects; 51 | 52 | //---------------------------------------------------------------------- 53 | // Thread related 54 | //---------------------------------------------------------------------- 55 | void setDepthMapsThread(void); 56 | static void* setDepthMapsThreadTmp(void* arg); 57 | 58 | void addPatchVThread(void); 59 | static void* addPatchVThreadTmp(void* arg); 60 | 61 | void setVGridsVPGridsThread(void); 62 | static void* setVGridsVPGridsThreadTmp(void* arg); 63 | 64 | void filterNeighborThread(void); 65 | static void* filterNeighborThreadTmp(void* arg); 66 | 67 | CfindMatch& m_fm; 68 | 69 | }; 70 | }; 71 | 72 | #endif // PMVS3_FILTER_H 73 | -------------------------------------------------------------------------------- /program/base/pmvs/findMatch.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "findMatch.h" 5 | #include "detectFeatures.h" 6 | 7 | using namespace PMVS3; 8 | using namespace std; 9 | using namespace Patch; 10 | 11 | CfindMatch::CfindMatch(void) 12 | : m_pos(*this), m_seed(*this), m_expand(*this), m_filter(*this), m_optim(*this) { 13 | m_debug = 0; 14 | } 15 | 16 | CfindMatch::~CfindMatch() { 17 | pthread_rwlock_destroy(&m_lock); 18 | 19 | for (int image = 0; image < (int)m_imageLocks.size(); ++image) 20 | pthread_rwlock_destroy(&m_imageLocks[image]); 21 | for (int image = 0; image < (int)m_countLocks.size(); ++image) 22 | pthread_rwlock_destroy(&m_countLocks[image]); 23 | } 24 | 25 | void CfindMatch::updateThreshold(void) { 26 | m_nccThreshold -= 0.05f; 27 | m_nccThresholdBefore -= 0.05f; 28 | 29 | m_countThreshold1 = 2; 30 | } 31 | 32 | void CfindMatch::init(const Soption& option) { 33 | m_timages = option.m_timages; 34 | m_oimages = option.m_oimages; 35 | m_images.clear(); 36 | m_images.insert(m_images.end(), m_timages.begin(), m_timages.end()); 37 | m_images.insert(m_images.end(), m_oimages.begin(), m_oimages.end()); 38 | 39 | m_tnum = (int)m_timages.size(); 40 | m_num = (int)m_images.size(); 41 | 42 | m_prefix = option.m_prefix; 43 | m_level = option.m_level; 44 | m_csize = option.m_csize; 45 | m_nccThreshold = option.m_threshold; 46 | m_wsize = option.m_wsize; 47 | m_minImageNumThreshold = option.m_minImageNum; 48 | m_CPU = option.m_CPU; 49 | //m_CPU = 128; 50 | m_setEdge = option.m_setEdge; 51 | m_sequenceThreshold = option.m_sequence; 52 | 53 | m_junit = 100; 54 | // This initialization does not matter 55 | m_visibleThreshold = 0.0f; 56 | m_visibleThresholdLoose = 0.0f; 57 | 58 | //m_tau = max(option.m_minImageNum * 2, min(m_num, 5)); 59 | m_tau = min(M_TAU_MAX, min(option.m_minImageNum * 2, m_num)); 60 | 61 | m_depth = 0; 62 | 63 | // set target images and other images 64 | m_bindexes = option.m_bindexes; 65 | m_visdata = option.m_visdata; 66 | m_visdata2 = option.m_visdata2; 67 | 68 | //---------------------------------------------------------------------- 69 | pthread_rwlock_init(&m_lock, NULL); 70 | m_imageLocks.resize(m_num); 71 | m_countLocks.resize(m_num); 72 | for (int image = 0; image < m_num; ++image) { 73 | pthread_rwlock_init(&m_imageLocks[image], NULL); 74 | pthread_rwlock_init(&m_countLocks[image], NULL); 75 | } 76 | // We set m_level + 3, to use multi-resolutional texture grabbing 77 | m_pss.init(m_images, m_prefix, m_level + 3, m_wsize, 1); 78 | 79 | if (m_setEdge != 0.0f) 80 | m_pss.setEdge(m_setEdge); 81 | m_pss.setDistances(); 82 | 83 | // Detect features if not yet done 84 | CdetectFeatures df; 85 | const int fcsize = 16; 86 | df.run(m_pss, m_num, fcsize, m_level, m_CPU); 87 | 88 | // Initialize each core member. m_po should be first 89 | m_pos.init(); 90 | m_seed.init(df.m_points); 91 | m_expand.init(); 92 | m_filter.init(); 93 | m_optim.init(); 94 | 95 | //---------------------------------------------------------------------- 96 | // Init thresholds 97 | m_angleThreshold0 = 60.0f * M_PI / 180.0f; 98 | m_angleThreshold1 = 60.0f * M_PI / 180.0f; 99 | 100 | m_countThreshold0 = 2; 101 | m_countThreshold1 = 4; 102 | m_countThreshold2 = 2; 103 | 104 | m_neighborThreshold = 0.5f; 105 | m_neighborThreshold1 = 1.0f; 106 | 107 | m_neighborThreshold2 = 1.0f; 108 | 109 | m_maxAngleThreshold = option.m_maxAngleThreshold; 110 | 111 | m_nccThresholdBefore = m_nccThreshold - 0.3f; 112 | 113 | m_quadThreshold = option.m_quadThreshold; 114 | 115 | m_epThreshold = 2.0f; 116 | } 117 | 118 | int CfindMatch::insideBimages(const Vec4f& coord) const { 119 | for (int i = 0; i < (int)m_bindexes.size(); ++i) { 120 | const int index = m_bindexes[i]; 121 | const Vec3f icoord = m_pss.project(index, coord, m_level); 122 | if (icoord[0] < 0.0 || m_pss.getWidth(index, m_level) - 1 < icoord[0] || 123 | icoord[1] < 0.0 || m_pss.getHeight(index, m_level) - 1 < icoord[1]) 124 | return 0; 125 | } 126 | return 1; 127 | } 128 | 129 | int CfindMatch::isNeighbor(const Patch::Cpatch& lhs, const Patch::Cpatch& rhs, 130 | const float neighborThreshold) const { 131 | const float hunit = (m_optim.getUnit(lhs.m_images[0], lhs.m_coord) + 132 | m_optim.getUnit(rhs.m_images[0], rhs.m_coord)) / 2.0 133 | * m_csize; 134 | return isNeighbor(lhs, rhs, hunit, neighborThreshold); 135 | } 136 | 137 | int CfindMatch::isNeighbor(const Patch::Cpatch& lhs, const Patch::Cpatch& rhs, 138 | const float hunit, const float neighborThreshold) const { 139 | if (lhs.m_normal * rhs.m_normal < cos(120.0 * M_PI / 180.0)) 140 | return 0; 141 | const Vec4f diff = rhs.m_coord - lhs.m_coord; 142 | 143 | const float vunit = lhs.m_dscale + rhs.m_dscale; 144 | 145 | const float f0 = lhs.m_normal * diff; 146 | const float f1 = rhs.m_normal * diff; 147 | float ftmp = (fabs(f0) + fabs(f1)) / 2.0; 148 | ftmp /= vunit; 149 | 150 | // this may loosen the isneighbor testing. need to tighten (decrease) threshold? 151 | const float hsize = norm(2 * diff - lhs.m_normal * f0 - rhs.m_normal * f1) / 2.0 / hunit; 152 | if (1.0 < hsize) 153 | ftmp /= min(2.0f, hsize); 154 | 155 | if (ftmp < neighborThreshold) 156 | return 1; 157 | else 158 | return 0; 159 | } 160 | 161 | int CfindMatch::isNeighborRadius(const Patch::Cpatch& lhs, 162 | const Patch::Cpatch& rhs, 163 | const float hunit, 164 | const float neighborThreshold, 165 | const float radius) const { 166 | if (lhs.m_normal * rhs.m_normal < cos(120.0 * M_PI / 180.0)) 167 | return 0; 168 | const Vec4f diff = rhs.m_coord - lhs.m_coord; 169 | 170 | const float vunit = lhs.m_dscale + rhs.m_dscale; 171 | 172 | const float f0 = lhs.m_normal * diff; 173 | const float f1 = rhs.m_normal * diff; 174 | float ftmp = (fabs(f0) + fabs(f1)) / 2.0; 175 | ftmp /= vunit; 176 | 177 | // this may loosen the isneighbor testing. need to tighten (decrease) threshold? 178 | const float hsize = norm(2 * diff - lhs.m_normal * f0 - rhs.m_normal * f1) / 2.0 / hunit; 179 | 180 | // radius check 181 | if (radius / hunit < hsize) 182 | return 0; 183 | 184 | if (1.0 < hsize) 185 | ftmp /= min(2.0f, hsize); 186 | 187 | if (ftmp < neighborThreshold) 188 | return 1; 189 | else 190 | return 0; 191 | } 192 | 193 | void CfindMatch::run(void) { 194 | struct timeval tv; 195 | gettimeofday(&tv, NULL); 196 | time_t curtime = tv.tv_sec; 197 | 198 | //---------------------------------------------------------------------- 199 | // Seed generation 200 | m_seed.run(); 201 | m_seed.clear(); 202 | 203 | ++m_depth; 204 | m_pos.collectPatches(); 205 | 206 | //---------------------------------------------------------------------- 207 | // Expansion 208 | const int TIME = 3; 209 | for (int t = 0; t < TIME; ++t) { 210 | m_expand.run(); 211 | 212 | m_filter.run(); 213 | 214 | updateThreshold(); 215 | 216 | cout << "STATUS: "; 217 | for (int i = 0; i < (int)m_optim.m_status.size(); ++i) { 218 | cout << m_optim.m_status[i] << ' '; 219 | if (i % 10 == 9) 220 | cout << endl; 221 | } 222 | cout << endl; 223 | 224 | ++m_depth; 225 | } 226 | cerr << "---- Total: " << tv.tv_sec - curtime << " secs ----" << endl; 227 | } 228 | 229 | void CfindMatch::write(const std::string prefix) { 230 | m_pos.writePatches2(prefix); 231 | } 232 | -------------------------------------------------------------------------------- /program/base/pmvs/findMatch.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_FINDMATCH_H 2 | #define PMVS3_FINDMATCH_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "patch.h" 11 | #include 12 | #include 13 | 14 | #include "../image/photoSetS.h" 15 | #include "patchOrganizerS.h" 16 | #include "seed.h" 17 | #include "expand.h" 18 | #include "filter.h" 19 | #include "optim.h" 20 | #include "option.h" 21 | 22 | namespace PMVS3 { 23 | 24 | class CfindMatch { 25 | public: 26 | CfindMatch(void); 27 | virtual ~CfindMatch(); 28 | 29 | void init(const PMVS3::Soption& option); 30 | void initCL(); 31 | void run(void); 32 | void write(const std::string prefix); 33 | 34 | int insideBimages(const Vec4f& coord) const; 35 | 36 | int isNeighborRadius(const Patch::Cpatch& lhs, const Patch::Cpatch& rhs, 37 | const float hunit, const float neighborThreshold, 38 | const float radius) const; 39 | 40 | int isNeighbor(const Patch::Cpatch& lhs, const Patch::Cpatch& rhs, 41 | const float hunit, const float neighborThreshold) const; 42 | int isNeighbor(const Patch::Cpatch& lhs, const Patch::Cpatch& rhs, 43 | const float neighborThreshold) const; 44 | 45 | //---------------------------------------------------------------------- 46 | // num of target images 47 | int m_tnum; 48 | // num of total images 49 | int m_num; 50 | // target images 51 | std::vector m_timages; 52 | // other images where patches are not computed 53 | std::vector m_oimages; 54 | // total images 55 | std::vector m_images; 56 | 57 | // prefix 58 | std::string m_prefix; 59 | // level 60 | int m_level; 61 | // cellsize 62 | int m_csize; 63 | // nccThreshold 64 | float m_nccThreshold; 65 | // windows size 66 | int m_wsize; 67 | // mininum image num threshold 68 | int m_minImageNumThreshold; 69 | // use edge detection or not 70 | float m_setEdge; 71 | // bounding images 72 | std::vector m_bindexes; 73 | // visdata from SfM. m_num x m_num matrix 74 | std::vector > m_visdata; 75 | // an array of relavant images 76 | std::vector > m_visdata2; 77 | // sequence Threshold 78 | int m_sequenceThreshold; 79 | // CPU 80 | int m_CPU; 81 | // Threshold on filterQuad 82 | float m_quadThreshold; 83 | 84 | // Maximum number of images used in the optimization 85 | int m_tau; 86 | 87 | // If patches are dense or not, that is, if we use check(patch) after patch optimization 88 | int m_depth; 89 | 90 | //---------------------------------------------------------------------- 91 | // Thresholds 92 | //---------------------------------------------------------------------- 93 | // For first feature matching. Images within this angle are used in 94 | // matching. 95 | float m_angleThreshold0; 96 | // tigher angle 97 | float m_angleThreshold1; 98 | 99 | // Number of success generation from each seed point 100 | int m_countThreshold0; 101 | // Number of counts, expansion can be tried 102 | int m_countThreshold1; 103 | 104 | // Number of trials for each cell in seed 105 | int m_countThreshold2; 106 | 107 | // Parameter for isNeighbor in findemptyblocks 108 | float m_neighborThreshold; 109 | // Parameter for isNeighbor in filterOutside 110 | float m_neighborThreshold1; 111 | // Parameter for filterNeighbor 112 | float m_neighborThreshold2; 113 | 114 | // ncc threshold before optim 115 | float m_nccThresholdBefore; 116 | // Maximum angle of images must be at least as large as this 117 | float m_maxAngleThreshold; 118 | 119 | // visibility consistency threshold 120 | float m_visibleThreshold; 121 | float m_visibleThresholdLoose; 122 | 123 | // Epipolar distance in seed generation 124 | float m_epThreshold; 125 | 126 | //---------------------------------------------------------------------- 127 | // For threads related 128 | //---------------------------------------------------------------------- 129 | // General lock 130 | pthread_rwlock_t m_lock; 131 | // For each image 132 | std::vector m_imageLocks; 133 | std::vector m_countLocks; 134 | // count 135 | int m_count; 136 | // jobs 137 | std::list m_jobs; 138 | // job unit 139 | int m_junit; 140 | 141 | //---------------------------------------------------------------------- 142 | // Core members 143 | //---------------------------------------------------------------------- 144 | // Images 145 | Image::CphotoSetS m_pss; 146 | // Patch organizer 147 | CpatchOrganizerS m_pos; 148 | 149 | // Seed generator 150 | Cseed m_seed; 151 | // Patch expansion 152 | Cexpand m_expand; 153 | public: 154 | // Patch filter 155 | Cfilter m_filter; 156 | // Patch optimizer 157 | Coptim m_optim; 158 | 159 | int m_debug; 160 | protected: 161 | void init(void); 162 | void initTargets(void); 163 | void updateThreshold(void); 164 | void initImages(void); 165 | }; 166 | }; 167 | 168 | #endif // PMVS3_FINDMATCH_H 169 | -------------------------------------------------------------------------------- /program/base/pmvs/harris.cc: -------------------------------------------------------------------------------- 1 | #include "harris.h" 2 | 3 | using namespace PMVS3; 4 | using namespace std; 5 | 6 | void Charris::init(const std::vector& image, 7 | const std::vector& mask, 8 | const std::vector& edge) { 9 | m_image.clear(); 10 | m_image.resize(m_height); 11 | int count = 0; 12 | for (int y = 0; y < m_height; ++y) { 13 | m_image[y].resize(m_width); 14 | for (int x = 0; x < m_width; ++x) { 15 | m_image[y][x][0] = ((int)image[count++]) / 255.0f; 16 | m_image[y][x][1] = ((int)image[count++]) / 255.0f; 17 | m_image[y][x][2] = ((int)image[count++]) / 255.0f; 18 | } 19 | } 20 | 21 | m_mask.clear(); 22 | if (!mask.empty() || !edge.empty()) { 23 | m_mask.resize(m_height); 24 | count = 0; 25 | for (int y = 0; y < m_height; ++y) { 26 | m_mask[y].resize(m_width); 27 | for (int x = 0; x < m_width; ++x) { 28 | if (mask.empty()) 29 | m_mask[y][x] = edge[count++]; 30 | else if (edge.empty()) 31 | m_mask[y][x] = mask[count++]; 32 | else { 33 | if (mask[count] && edge[count]) 34 | m_mask[y][x] = (unsigned char)255; 35 | else 36 | m_mask[y][x] = 0; 37 | count++; 38 | } 39 | } 40 | } 41 | } 42 | 43 | setGaussD(m_sigmaD, m_gaussD); 44 | setGaussI(m_sigmaI, m_gaussI); 45 | } 46 | 47 | void Charris::setDerivatives(void) { 48 | // set m_dIdx, m_dIdy 49 | preprocess(); 50 | 51 | // now set m_dIdxdIdx, m_dIdydIdy, m_dIdxDIdy 52 | preprocess2(); 53 | } 54 | 55 | void Charris::preprocess2(void) { 56 | m_dIdxdIdx.clear(); m_dIdydIdy.clear(); m_dIdxdIdy.clear(); 57 | m_dIdxdIdx.resize(m_height); 58 | m_dIdydIdy.resize(m_height); 59 | m_dIdxdIdy.resize(m_height); 60 | for (int y = 0; y < m_height; ++y) { 61 | m_dIdxdIdx[y].resize(m_width); 62 | m_dIdydIdy[y].resize(m_width); 63 | m_dIdxdIdy[y].resize(m_width); 64 | for (int x = 0; x < m_width; ++x) { 65 | m_dIdxdIdx[y][x] = m_dIdydIdy[y][x] = m_dIdxdIdy[y][x] = 0.0; 66 | if (!m_mask.empty() && m_mask[y][x] == 0) continue; 67 | 68 | m_dIdxdIdx[y][x] += m_dIdx[y][x] * m_dIdx[y][x]; 69 | m_dIdydIdy[y][x] += m_dIdy[y][x] * m_dIdy[y][x]; 70 | m_dIdxdIdy[y][x] += m_dIdx[y][x] * m_dIdy[y][x]; 71 | } 72 | } 73 | 74 | { 75 | vector >().swap(m_dIdx); 76 | vector >().swap(m_dIdy); 77 | } 78 | 79 | //---------------------------------------------------------------------- 80 | // blur 81 | vector > vvftmp; 82 | vvftmp.resize(m_height); 83 | for (int y = 0; y < m_height; ++y) { 84 | vvftmp[y].resize(m_width); 85 | for (int x = 0; x < m_width; ++x) 86 | vvftmp[y][x] = 0.0; 87 | } 88 | 89 | //---------------------------------------------------------------------- 90 | // m_dIdxdIdx 91 | convolveX(m_dIdxdIdx, m_mask, m_gaussI, vvftmp); 92 | convolveY(m_dIdxdIdx, m_mask, m_gaussI, vvftmp); 93 | 94 | //---------------------------------------------------------------------- 95 | // m_dIdydIdy 96 | convolveX(m_dIdydIdy, m_mask, m_gaussI, vvftmp); 97 | convolveY(m_dIdydIdy, m_mask, m_gaussI, vvftmp); 98 | 99 | //---------------------------------------------------------------------- 100 | // m_dIdxdIdy 101 | convolveX(m_dIdxdIdy, m_mask, m_gaussI, vvftmp); 102 | convolveY(m_dIdxdIdy, m_mask, m_gaussI, vvftmp); 103 | } 104 | 105 | void Charris::preprocess(void) { 106 | vector > vvvftmp; 107 | vvvftmp.resize(m_height); 108 | for (int y = 0; y < m_height; ++y) { 109 | vvvftmp[y].resize(m_width); 110 | for (int x = 0; x < m_width; ++x) 111 | vvvftmp[y][x] = Vec3f(); 112 | } 113 | 114 | m_dIdx = m_image; 115 | 116 | vector dfilter, ifilter; 117 | dfilter.resize(3); 118 | dfilter[0] = -0.5; dfilter[1] = 0; dfilter[2] = 0.5; 119 | ifilter.resize(3); 120 | ifilter[0] = 1.0 / 3.0; ifilter[1] = 1.0 / 3.0; ifilter[2] = 1.0 / 3.0; 121 | 122 | convolveX(m_dIdx, m_mask, dfilter, vvvftmp); 123 | convolveY(m_dIdx, m_mask, ifilter, vvvftmp); 124 | 125 | m_dIdy = m_image; 126 | convolveX(m_dIdy, m_mask, ifilter, vvvftmp); 127 | convolveY(m_dIdy, m_mask, dfilter, vvvftmp); 128 | } 129 | 130 | void Charris::setResponse(void) { 131 | m_response.clear(); 132 | m_response.resize(m_height); 133 | for (int y = 0; y < m_height; ++y) { 134 | m_response[y].resize(m_width); 135 | for (int x = 0; x < m_width; ++x) { 136 | m_response[y][x] = 0.0; 137 | if (!m_mask.empty() && m_mask[y][x] == 0) continue; 138 | 139 | const float D = m_dIdxdIdx[y][x] * m_dIdydIdy[y][x] - m_dIdxdIdy[y][x] * m_dIdxdIdy[y][x]; 140 | const float tr = m_dIdxdIdx[y][x] + m_dIdydIdy[y][x]; 141 | m_response[y][x] = D - 0.06 * tr * tr; 142 | } 143 | } 144 | 145 | //---------------------------------------------------------------------- 146 | // suppress non local max 147 | vector > vvftmp = m_response; 148 | for (int y = 1; y < m_height - 1; ++y) { 149 | for (int x = 1; x < m_width - 1; ++x) { 150 | if (m_response[y][x] < m_response[y][x+1] || 151 | m_response[y][x] < m_response[y][x-1] || 152 | m_response[y][x] < m_response[y+1][x] || 153 | m_response[y][x] < m_response[y-1][x]) 154 | vvftmp[y][x] = 0.0; 155 | } 156 | } 157 | 158 | vvftmp.swap(m_response); 159 | } 160 | 161 | void Charris::run(const std::vector& image, 162 | const std::vector& mask, 163 | const std::vector& edge, 164 | const int width, const int height, 165 | const int gspeedup, const float sigma, 166 | std::multiset & result) { 167 | 168 | cerr << "Harris running ..." << flush; 169 | m_width = width; m_height = height; 170 | m_sigmaD = sigma; m_sigmaI = sigma; 171 | init(image, mask, edge); 172 | setDerivatives(); setResponse(); 173 | 174 | const int factor = 2; 175 | const int maxPointsGrid = factor * factor; 176 | const int gridsize = gspeedup * factor; 177 | 178 | const int w = (m_width + gridsize - 1) / gridsize; 179 | const int h = (m_height + gridsize - 1) / gridsize; 180 | 181 | vector > > resultgrids; 182 | resultgrids.resize(h); 183 | for (int y = 0; y < h; ++y) 184 | resultgrids[y].resize(w); 185 | 186 | const int margin = (int)m_gaussD.size() / 2; 187 | for (int y = margin; y < m_height - margin; ++y) { 188 | for (int x = margin; x < m_width - margin; ++x) { 189 | if (m_response[y][x] == 0.0) 190 | continue; 191 | 192 | const int x0 = min(x / gridsize, w - 1); 193 | const int y0 = min(y / gridsize, h - 1); 194 | 195 | if ((int)resultgrids[y0][x0].size() < maxPointsGrid || 196 | resultgrids[y0][x0].begin()->m_response < m_response[y][x]) { 197 | Cpoint p; 198 | p.m_icoord = Vec3f(x, y, 1.0f); 199 | p.m_response = m_response[y][x]; 200 | p.m_type = 0; 201 | 202 | resultgrids[y0][x0].insert(p); 203 | if (maxPointsGrid < (int)resultgrids[y0][x0].size()) 204 | resultgrids[y0][x0].erase(resultgrids[y0][x0].begin ()); 205 | } 206 | } 207 | } 208 | 209 | for (int y = 0; y < h; ++y) 210 | for (int x = 0; x < w; ++x) { 211 | //const float threshold = setThreshold(resultgrids[y][x]); 212 | multiset::iterator begin = resultgrids[y][x].begin(); 213 | multiset::iterator end = resultgrids[y][x].end(); 214 | while (begin != end) { 215 | //if (threshold <= begin->m_response) 216 | result.insert(*begin); 217 | begin++; 218 | } 219 | } 220 | 221 | cerr << (int)result.size() << " harris done" << endl; 222 | } 223 | -------------------------------------------------------------------------------- /program/base/pmvs/harris.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_HARRIS_H 2 | #define PMVS3_HARRIS_H 3 | 4 | #include 5 | #include 6 | #include "../numeric/vec3.h" 7 | #include "detector.h" 8 | #include "point.h" 9 | 10 | namespace PMVS3 { 11 | 12 | class Charris: public Cdetector { 13 | public: 14 | void run(const std::vector& image, 15 | const std::vector& mask, 16 | const std::vector& edge, 17 | const int width, const int height, 18 | const int gspeedup, const float sigma, 19 | std::multiset & result); 20 | 21 | virtual ~Charris() { 22 | } 23 | 24 | protected: 25 | float m_sigmaD; 26 | float m_sigmaI; 27 | 28 | std::vector m_gaussD; 29 | std::vector m_gaussI; 30 | 31 | std::vector > m_dIdx; 32 | std::vector > m_dIdy; 33 | 34 | std::vector > m_dIdxdIdx; 35 | std::vector > m_dIdydIdy; 36 | std::vector > m_dIdxdIdy; 37 | 38 | std::vector > m_response; 39 | 40 | void init(const std::vector& image, 41 | const std::vector& mask, 42 | const std::vector& edge); 43 | 44 | void setDerivatives(void); 45 | void preprocess(void); 46 | void preprocess2(void); 47 | void setResponse(void); 48 | }; 49 | }; 50 | 51 | #endif // PMVS3_HARRIS_H 52 | -------------------------------------------------------------------------------- /program/base/pmvs/option.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_OPTION_H 2 | #define PMVS3_OPTION_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace PMVS3 { 9 | 10 | struct Soption{ 11 | public: 12 | int m_level; 13 | int m_csize; 14 | float m_threshold; 15 | int m_wsize; 16 | int m_minImageNum; 17 | int m_CPU; 18 | float m_setEdge; 19 | int m_useBound; 20 | int m_useVisData; 21 | int m_sequence; 22 | 23 | float m_maxAngleThreshold; 24 | float m_quadThreshold; 25 | 26 | std::string m_prefix; 27 | std::string m_option; 28 | int m_tflag; 29 | std::vector m_timages; 30 | int m_oflag; 31 | std::vector m_oimages; 32 | 33 | std::map m_dict; 34 | 35 | std::vector m_bindexes; 36 | std::vector > m_visdata; 37 | std::vector > m_visdata2; 38 | 39 | Soption(void); 40 | 41 | void init(const std::string prefix, const std::string option); 42 | 43 | protected: 44 | void initOimages(void); 45 | void initBindexes(const std::string sbimages); 46 | void initVisdata(void); 47 | void initVisdata2(void); 48 | }; 49 | }; 50 | 51 | #endif // PMVS3_OPTION_H 52 | -------------------------------------------------------------------------------- /program/base/pmvs/patch.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../numeric/vec4.h" 3 | #include "patch.h" 4 | 5 | using namespace std; 6 | 7 | std::istream& Patch::operator >>(std::istream& istr, Cpatch& rhs) { 8 | string header; 9 | int itmp; 10 | istr >> header >> rhs.m_coord >> rhs.m_normal >> rhs.m_ncc 11 | >> rhs.m_dscale >> rhs.m_ascale; 12 | 13 | if (header == "PATCHA") { 14 | int type; Vec4f dir; 15 | istr >> type >> dir; 16 | } 17 | 18 | istr >> itmp; 19 | rhs.m_images.resize(itmp); 20 | for (int i = 0; i < itmp; ++i) 21 | istr >> rhs.m_images[i]; 22 | 23 | istr >> itmp; 24 | rhs.m_vimages.resize(itmp); 25 | for (int i = 0; i < itmp; ++i) 26 | istr >> rhs.m_vimages[i]; 27 | 28 | return istr; 29 | } 30 | 31 | std::ostream& Patch::operator <<(std::ostream& ostr, const Cpatch& rhs) { 32 | ostr << "PATCHS" << endl 33 | << rhs.m_coord << endl 34 | << rhs.m_normal << endl 35 | << rhs.m_ncc << ' ' 36 | << rhs.m_dscale << ' ' 37 | << rhs.m_ascale << endl 38 | << (int)rhs.m_images.size() << endl; 39 | for (int i = 0; i < (int)rhs.m_images.size(); ++i) 40 | ostr << rhs.m_images[i] << ' '; 41 | ostr << endl; 42 | 43 | ostr << (int)rhs.m_vimages.size() << endl; 44 | for (int i = 0; i < (int)rhs.m_vimages.size(); ++i) 45 | ostr << rhs.m_vimages[i] << ' '; 46 | ostr << endl; 47 | 48 | return ostr; 49 | } 50 | -------------------------------------------------------------------------------- /program/base/pmvs/patch.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_PATCH_H 2 | #define PMVS3_PATCH_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../numeric/vec4.h" 8 | 9 | #define M_TAU_MAX 10 10 | 11 | namespace Patch { 12 | 13 | class Cpatch { 14 | public: 15 | Cpatch(void) { 16 | m_ncc = -1.0; 17 | m_timages = 0; 18 | m_fix = 0; 19 | // dflag is initialized only once. if failed in one direction, we 20 | // never try that. 21 | m_dflag = 0; 22 | } 23 | 24 | //---------------------------------------------------------------------- 25 | // saved information 26 | // 3D coordinates of the center of the patch 27 | Vec4f m_coord; 28 | // patch outward normal vector 29 | Vec4f m_normal; 30 | 31 | // associated image ids. first image id is the reference one. images 32 | // can be non-targetting image. 33 | std::vector m_images; 34 | std::vector > m_grids; 35 | 36 | // visible images. m_vimages must be targetting images. 37 | std::vector m_vimages; 38 | std::vector > m_vgrids; 39 | 40 | //---------------------------------------------------------------------- 41 | inline float score(const float threshold) const{ 42 | return std::max(0.0f, m_ncc - threshold) * (int)m_images.size(); 43 | } 44 | inline float score2(const float threshold) const{ 45 | return std::max(0.0f, m_ncc - threshold) * m_timages; 46 | } 47 | 48 | // average ncc 49 | float m_ncc; 50 | // number of targetting images in m_images 51 | int m_timages; 52 | 53 | // flat for expansion 54 | // 0: not yet tested 55 | // 1: done 56 | int m_flag; 57 | 58 | // for directional flag 59 | unsigned char m_dflag; 60 | 61 | // fixed patch or not 62 | char m_fix; 63 | 64 | // id number in m_ppatches 65 | int m_id; 66 | 67 | // scaling factor corresponding to one pixel difference 68 | float m_dscale; 69 | float m_ascale; 70 | 71 | float m_tmp; 72 | }; 73 | 74 | typedef boost::shared_ptr Ppatch; 75 | 76 | struct Spatchcmp { 77 | bool operator()(const Ppatch& lhs, const Ppatch& rhs) { 78 | if (lhs.get() < rhs.get()) 79 | return true; 80 | else 81 | return false; 82 | } 83 | }; 84 | 85 | std::istream& operator >>(std::istream& istr, Patch::Cpatch& rhs); 86 | std::ostream& operator <<(std::ostream& ostr, const Patch::Cpatch& rhs); 87 | 88 | }; 89 | 90 | #endif // PMVS3_PATCH_H 91 | -------------------------------------------------------------------------------- /program/base/pmvs/patchOrganizerS.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_PATCHORGANIZERS_H 2 | #define PMVS3_PATCHORGANIZERS_H 3 | 4 | #include "patch.h" 5 | #include 6 | 7 | namespace PMVS3 { 8 | 9 | class CfindMatch; 10 | 11 | class P_compare { 12 | public: 13 | bool operator()(const Patch::Ppatch& lhs, const Patch::Ppatch& rhs) const { 14 | return lhs->m_tmp < rhs->m_tmp; 15 | } 16 | }; 17 | 18 | class CpatchOrganizerS { 19 | public: 20 | CpatchOrganizerS(CfindMatch& findMatch); 21 | 22 | void init(void); 23 | void collectPatches(const int target = 0); 24 | void collectPatches(std::priority_queue, 25 | P_compare>& pqpatches); 26 | 27 | void collectPatches(const int index, 28 | std::priority_queue, 29 | P_compare>& pqpatches); 30 | void collectNonFixPatches(const int index, std::vector& ppatches); 31 | 32 | void writePatches(void); 33 | void writePatches2(const std::string prefix); 34 | 35 | void writePLY(const std::vector& patches, 36 | const std::string filename); 37 | void writePLY(const std::vector& patches, 38 | const std::string filename, 39 | const std::vector& colors); 40 | 41 | void readPatches(void); 42 | 43 | void clearCounts(void); 44 | void clearFlags(void); 45 | 46 | void setGridsImages(Patch::Cpatch& patch, 47 | const std::vector& images) const; 48 | void addPatch(Patch::Ppatch& ppatch); 49 | void removePatch(const Patch::Ppatch& ppatch); 50 | void setGrids(Patch::Ppatch& ppatch) const; 51 | void setGrids(Patch::Cpatch& patch) const; 52 | void setVImagesVGrids(Patch::Ppatch& ppatch); 53 | void setVImagesVGrids(Patch::Cpatch& patch); 54 | void updateDepthMaps(Patch::Ppatch& ppatch); 55 | 56 | int isVisible(const Patch::Cpatch& patch, const int image, 57 | const int& ix, const int& iy, 58 | const float strict, const int lock); 59 | int isVisible0(const Patch::Cpatch& patch, const int image, 60 | int& ix, int& iy, 61 | const float strict, const int lock); 62 | 63 | void findNeighbors(const Patch::Cpatch& patch, 64 | std::vector& neighbors, 65 | const int lock, 66 | const float scale = 1.0f, 67 | const int margin = 1, 68 | const int skipvis = 0); 69 | 70 | void setScales(Patch::Cpatch& patch) const; 71 | 72 | float computeUnit(const Patch::Cpatch& patch) const; 73 | 74 | // change the contents of m_images from images to indexes 75 | void image2index(Patch::Cpatch& patch); 76 | // change the contents of m_images from indexes to images 77 | void index2image(Patch::Cpatch& patch); 78 | 79 | //---------------------------------------------------------------------- 80 | // Widths of grids 81 | std::vector m_gwidths; 82 | std::vector m_gheights; 83 | //---------------------------------------------------------------------- 84 | // image, grid 85 | std::vector > > m_pgrids; 86 | // image, grid 87 | std::vector > > m_vpgrids; 88 | // Closest patch 89 | std::vector > m_dpgrids; 90 | 91 | // all the patches in the current level of m_pgrids 92 | std::vector m_ppatches; 93 | 94 | // Check how many times patch optimization was performed for expansion 95 | std::vector > m_counts; 96 | 97 | static Patch::Ppatch m_MAXDEPTH; 98 | static Patch::Ppatch m_BACKGROUND; 99 | 100 | protected: 101 | CfindMatch& m_fm; 102 | }; 103 | }; 104 | 105 | #endif //PMVS3_PATCHORGANIZERS_H 106 | -------------------------------------------------------------------------------- /program/base/pmvs/point.cc: -------------------------------------------------------------------------------- 1 | #include "point.h" 2 | 3 | using namespace PMVS3; 4 | using namespace std; 5 | 6 | Cpoint::Cpoint(void) { 7 | m_response = -1.0; 8 | m_type = -1; 9 | } 10 | 11 | Cpoint::~Cpoint() { 12 | } 13 | 14 | std::istream& PMVS3::operator >>(std::istream& istr, Cpoint& rhs) { 15 | string header; 16 | istr >> header; 17 | istr >> rhs.m_icoord[0] >> rhs.m_icoord[1] >> rhs.m_response >> rhs.m_type; 18 | rhs.m_icoord[2] = 1.0f; 19 | return istr; 20 | } 21 | 22 | std::ostream& PMVS3::operator <<(std::ostream& ostr, const Cpoint& rhs) { 23 | ostr << "POINT0" << endl 24 | << rhs.m_icoord[0] << ' ' << rhs.m_icoord[1] << ' ' << rhs.m_response << ' ' 25 | << rhs.m_type; 26 | return ostr; 27 | } 28 | -------------------------------------------------------------------------------- /program/base/pmvs/point.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_POINT_H 2 | #define PMVS3_POINT_H 3 | 4 | #include "../numeric/vec4.h" 5 | #include "../numeric/mat3.h" 6 | 7 | namespace PMVS3 { 8 | class Cpoint { 9 | public: 10 | Cpoint(void); 11 | virtual ~Cpoint(); 12 | 13 | Vec3f m_icoord; 14 | float m_response; 15 | 16 | // 0: Harris 17 | // 1: DoG 18 | int m_type; 19 | 20 | // tempporary variable, used to store original imageid in initial match 21 | int m_itmp; 22 | 23 | // 3D coordinate 24 | Vec4f m_coord; 25 | 26 | bool operator < (const Cpoint& rhs) const { 27 | return m_response < rhs.m_response; 28 | } 29 | 30 | friend std::istream& operator >>(std::istream& istr, Cpoint& rhs); 31 | friend std::ostream& operator <<(std::ostream& ostr, const Cpoint& rhs); 32 | }; 33 | 34 | std::istream& operator >>(std::istream& istr, Cpoint& rhs); 35 | std::ostream& operator <<(std::ostream& ostr, const Cpoint& rhs); 36 | }; 37 | 38 | #endif //PMVS3_POINT_H 39 | -------------------------------------------------------------------------------- /program/base/pmvs/refineThread.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_REFINE_THREAD_H 2 | #define PMVS3_REFINE_THREAD_H 3 | 4 | #include "asyncQueue.h" 5 | #include 6 | #include 7 | #include "patch.h" 8 | #include 9 | #include 10 | #include 11 | 12 | namespace PMVS3 { 13 | enum {REFINE_TASK_INCOMPLETE, 14 | REFINE_TASK_IN_PROGRESS, 15 | REFINE_TASK_COMPLETE, 16 | REFINE_ALL_TASKS_COMPLETE, 17 | REFINE_TASK_IGNORE, 18 | REFINE_SUCCESS 19 | }; 20 | 21 | #define REFINE_MAX_TASKS 1024 22 | #define REFINE_QUEUE_LENGTH 1400 23 | 24 | typedef struct _CLImageParams { 25 | cl_float4 projection[3]; 26 | cl_float3 xaxis; 27 | cl_float3 yaxis; 28 | cl_float3 zaxis; 29 | cl_float4 center; 30 | cl_float ipscale; 31 | } CLImageParams; 32 | 33 | typedef struct _CLPatchParams { 34 | cl_float4 center; 35 | cl_float4 ray; 36 | cl_float dscale; 37 | cl_float ascale; 38 | cl_int nIndexes; 39 | cl_int indexes[M_TAU_MAX]; 40 | } CLPatchParams; 41 | 42 | typedef boost::shared_ptr PCLPatchParams; 43 | 44 | class RefineWorkItem { 45 | public: 46 | RefineWorkItem() : id(-1) {}; 47 | Patch::Ppatch patch; 48 | PCLPatchParams patchParams; 49 | cl_float4 encodedVec; 50 | int id; 51 | int taskId; 52 | int status; 53 | int numIterations; 54 | }; 55 | 56 | class CfindMatch; 57 | class Coptim; 58 | 59 | class CrefineThread { 60 | public: 61 | CrefineThread(int numPostProcessThreads, CasyncQueue &postProcessQueue, CfindMatch &findMatch); 62 | ~CrefineThread(); 63 | void init(); 64 | void enqueueWorkItem(RefineWorkItem &workItem); 65 | void clearWorkItems(); 66 | bool isWaiting(); 67 | int totalIterations() {return m_totalIterations;}; 68 | 69 | protected: 70 | CasyncQueue m_workQueue; 71 | std::queue m_idleTaskIds; 72 | std::map m_taskMap; 73 | pthread_t m_refineThread; 74 | pthread_mutex_t m_workQueueLock; 75 | pthread_mutex_t m_workTaskIdLock; 76 | CasyncQueue &m_postProcessQueue; 77 | Coptim &m_optim; 78 | CfindMatch& m_fm; 79 | int m_numPostProcessThreads; 80 | int m_numTasks; 81 | bool m_initialized; 82 | int m_totalIterations; 83 | 84 | //----------------------------------------------------------------- 85 | // OpenCL 86 | cl_context m_clCtx; 87 | cl_device_id m_clDevice; 88 | cl_program m_clProgram; 89 | cl_kernel m_clKernel; 90 | cl_command_queue m_clQueue; 91 | 92 | // CL image array 93 | cl_mem m_clImageArray; 94 | 95 | // CL params 96 | cl_mem m_clImageParams; 97 | cl_mem m_clPatchParams; 98 | cl_mem m_clEncodedVecs; 99 | cl_mem m_clSimplexVecs; 100 | cl_mem m_clSimplexStates; 101 | cl_float4 m_idleVec; 102 | cl_float4 *m_encodedVecs; 103 | cl_int *m_simplexStates; 104 | cl_int m_simplexStateInitAll; 105 | 106 | void initCL(); 107 | static void rgbToRGBA(int width, int height, unsigned char *in, unsigned char *out); 108 | void initCLImageArray(); 109 | void initCLImageParams(); 110 | void initCLPatchParams(); 111 | void destroyCL(); 112 | void refinePatchesGPU(); 113 | 114 | static void *threadLoopTmp(void *args); 115 | void threadLoop(); 116 | int getTaskId(); 117 | void addTask(RefineWorkItem &workItem); 118 | void iterateRefineTasks(); 119 | void checkCompletedTasks(); 120 | void stopPostProcessThreads(); 121 | template 122 | static void strSubstitute(std::string &str, T1 searchStrIn, T2 replaceIn, bool replaceAll = false); 123 | void setTaskBufferIdle(int taskId); 124 | void writeParamsToBuffer(int taskId, CLPatchParams &patchParams); 125 | void writeEncodedVecToBuffer(int taskId, cl_float4 &encodedVec); 126 | void writeSimplexStatesToBuffer(); 127 | void initializeSimplexState(int taskId); 128 | void initializeAllSimplexStates(); 129 | }; 130 | 131 | template 132 | void CrefineThread::strSubstitute(std::string &str, T1 searchStrIn, T2 replaceIn, bool replaceAll) { 133 | size_t startPos; 134 | std::string searchStr(searchStrIn); 135 | std::stringstream ss; 136 | 137 | ss << replaceIn; 138 | 139 | startPos = str.find(searchStr); 140 | while(startPos != std::string::npos) { 141 | str.replace(startPos, searchStr.length(), ss.str()); 142 | if(replaceAll) { 143 | startPos = str.find(searchStr); 144 | } 145 | else { 146 | startPos = std::string::npos; 147 | } 148 | } 149 | } 150 | 151 | } 152 | #endif 153 | -------------------------------------------------------------------------------- /program/base/pmvs/seed.h: -------------------------------------------------------------------------------- 1 | #ifndef PMVS3_SEED_H 2 | #define PMVS3_SEED_H 3 | 4 | #include 5 | #include 6 | #include "patch.h" 7 | #include "point.h" 8 | 9 | #include 10 | 11 | namespace PMVS3 { 12 | class CfindMatch; 13 | typedef boost::shared_ptr Ppoint; 14 | 15 | class Cseed { 16 | public: 17 | Cseed(CfindMatch& findMatch); 18 | virtual ~Cseed() {}; 19 | 20 | void init(const std::vector >& points); 21 | void run(void); 22 | void clear(void); 23 | 24 | protected: 25 | void readPoints(const std::vector >& points); 26 | int canAdd(const int index, const int x, const int y); 27 | 28 | void initialMatch(const int index, const int id); 29 | void collectCells(const int index0, const int index1, 30 | const Cpoint& p0, std::vector& cells); 31 | 32 | void collectCandidates(const int index, const std::vector& indexes, 33 | const Cpoint& point, std::vector& vcp); 34 | 35 | int initialMatchSub(const int index0, const int index1, 36 | const int id, Patch::Cpatch& patch); 37 | 38 | void unproject(const int index0, const int index1, 39 | const Cpoint& p0, const Cpoint& p1, 40 | Vec4f& coord) const; 41 | 42 | //---------------------------------------------------------------------- 43 | CfindMatch& m_fm; 44 | // points in a grid. For each index, grid 45 | std::vector > > m_ppoints; 46 | 47 | //---------------------------------------------------------------------- 48 | // thread related 49 | //---------------------------------------------------------------------- 50 | void initialMatchThread(void); 51 | static void* initialMatchThreadTmp(void* arg); 52 | 53 | // Number of trials 54 | std::vector m_scounts; 55 | // Number of failures in the prep 56 | std::vector m_fcounts0; 57 | // Number of failures in the post processing 58 | std::vector m_fcounts1; 59 | // Number passes 60 | std::vector m_pcounts; 61 | }; 62 | }; 63 | 64 | #endif // PMVS3_SEED_H 65 | -------------------------------------------------------------------------------- /program/base/stann/Copyright.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------- 4 | STANN: A Simple Thread-safe Approximate Nearest Neighbor C++ Library 5 | Version: 0.1 6 | Release Date: Dec 1, 2007 7 | -------------------------------------------------------------------------- 8 | Copyright (c) 2006 2007 2008 Florida State University and 9 | Michael Connor and Piyush Kumar: All Rights Reserved. 10 | 11 | 12 | This program may be freely redistributed under the condition that the 13 | copyright notices (including this file) are not removed, and 14 | no compensation is received. Private, research, and institutional 15 | use is free. You may distribute modified versions of this code UNDER 16 | THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE 17 | SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE 18 | AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR 19 | NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution of this code as 20 | part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT 21 | WITH THE AUTHORS. (If you are not directly supplying this code to a 22 | customer, and you are instead telling them how they can obtain it for 23 | free, then you are not required to make any arrangement with us.) 24 | The ideas that are used to construct this software library are 25 | protected by provisional patent number 60986713. 26 | 27 | 28 | Disclaimer 29 | ---------- 30 | 31 | Florida State University and the authors make no representations about 32 | the suitability or fitness of this software for any purpose. 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 36 | SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, 37 | WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 38 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 39 | 40 | 41 | 42 | Authors 43 | ------- 44 | Michael Connor and Piyush Kumar 45 | Dept of Computer Science 46 | Florida State University 47 | Tallahassee, FL 32306-4532 48 | 49 | Emails: 50 | stann @ compgeom dot com. 51 | 52 | Web Page: 53 | http://compgeom.com/~stann 54 | 55 | -------------------------------------------------------------------------------- /program/base/stann/assert.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: assert.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | #ifndef REVIVER_ASSERT_HPP 16 | #define REVIVER_ASSERT_HPP 17 | 18 | #include 19 | /*! 20 | \file 21 | \brief Implementation of assert functions 22 | This file contains an assert function implementation 23 | */ 24 | 25 | /*! 26 | \brief Assert function 27 | This function prints error messages along with file and line numbers 28 | \param b bool to be checked 29 | \param desc Error message 30 | \param line Line number 31 | \param file File name 32 | \return True is there is no error 33 | */ 34 | 35 | /* 36 | bool MyAssertFunction( bool b, char* desc, int line, char* file){ 37 | if (b) return true; 38 | std::cerr << "\n\nAssertion Failure\n"; 39 | std::cerr << "Description : " << desc << std::endl; 40 | std::cerr << "Filename : " << file << std::endl; 41 | std::cerr << "Line No : " << line << std::endl; 42 | exit(1); 43 | } 44 | 45 | #if defined( _DEBUG ) 46 | #define Assert( exp, description ) MyAssertFunction( (int)(exp), description, __LINE__, __FILE__ ) 47 | #else 48 | #define Assert( exp, description ) 49 | #endif 50 | */ 51 | 52 | #define Assert( exp, description ) 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /program/base/stann/assert.hpp~: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: assert.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | #ifndef REVIVER_ASSERT_HPP 16 | #define REVIVER_ASSERT_HPP 17 | 18 | #include 19 | /*! 20 | \file 21 | \brief Implementation of assert functions 22 | This file contains an assert function implementation 23 | */ 24 | 25 | /*! 26 | \brief Assert function 27 | This function prints error messages along with file and line numbers 28 | \param b bool to be checked 29 | \param desc Error message 30 | \param line Line number 31 | \param file File name 32 | \return True is there is no error 33 | */ 34 | bool MyAssertFunction( bool b, char* desc, int line, char* file){ 35 | if (b) return true; 36 | std::cerr << "\n\nAssertion Failure\n"; 37 | std::cerr << "Description : " << desc << std::endl; 38 | std::cerr << "Filename : " << file << std::endl; 39 | std::cerr << "Line No : " << line << std::endl; 40 | exit(1); 41 | } 42 | 43 | #if defined( _DEBUG ) 44 | #define Assert( exp, description ) MyAssertFunction( (int)(exp), description, __LINE__, __FILE__ ) 45 | #else 46 | #define Assert( exp, description ) 47 | #endif 48 | 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /program/base/stann/bruteNN.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: bruteNN.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | /*! 17 | \file 18 | \brief Brute force nearest neighbor search implementation 19 | This file contains a simple brute force NN algorithm implementation. 20 | It is very innefficient and should be used only for accuracy tests. 21 | */ 22 | #include 23 | 24 | #include "qknn.hpp" 25 | 26 | using namespace std; 27 | 28 | /*! 29 | \brief A Brute force NN search class 30 | This class is a simple brute force algorithm for computing nearest neighbors. 31 | It is very innefficient and should be used only for accuracy tests. 32 | */ 33 | template 34 | class bruteNN 35 | { 36 | public: 37 | /*! 38 | \brief Constructor 39 | Constructs a brute force nearest neighbor search structure out 40 | of the given data points. 41 | \param *points Pointer to list of input points 42 | \param N number of input points 43 | */ 44 | bruteNN(Point *points, long int N); 45 | /*! 46 | \brief Destructor 47 | */ 48 | ~bruteNN(); 49 | /*! 50 | \brief Nearest neighbor search function 51 | 52 | This function returns the nearest k neighbors from the data 53 | structure to the given query point. The return vector contains 54 | the indexes to the answer points in the original data array passed 55 | at construction time. 56 | \param q Query point 57 | \param k number of neighbors to search for 58 | \param nn_idx Vector in which answer is written 59 | */ 60 | void ksearch(Point q, int k, 61 | vector &nn_idx); 62 | /*! 63 | \brief Nearest neighbor search function 64 | 65 | This function returns the nearest k neighbors from the data 66 | structure to the given query point, as well as the squared 67 | distance to the query point. The return vector contains 68 | the indexes to the answer points in the original data array 69 | passed at construction time. 70 | \param q Query point 71 | \param k number of neighbors to search for 72 | \param nn_idx Vector in which answer is written 73 | \param d_index Vector in which square distances are written 74 | */ 75 | void ksearch(Point q, int k, 76 | vector &nn_idx, 77 | vector &d_index); 78 | 79 | private: 80 | 81 | vector points; 82 | }; 83 | 84 | template 85 | bruteNN::bruteNN(Point *p, long int N) 86 | { 87 | points.resize(N); 88 | for(int i=0;i < N;++i) 89 | { 90 | points[i] = p[i]; 91 | } 92 | } 93 | 94 | template 95 | bruteNN::~bruteNN() 96 | { 97 | } 98 | 99 | template 100 | void bruteNN::ksearch(Point q, int k, 101 | vector &nn_idx) 102 | { 103 | qknn que; 104 | double distance; 105 | que.set_size(k); 106 | for(unsigned int i=0;i < points.size();++i) 107 | { 108 | distance = q.sqr_dist(points[i]); 109 | que.update(distance, i); 110 | } 111 | que.answer(nn_idx); 112 | } 113 | 114 | template 115 | void bruteNN::ksearch(Point q, int k, 116 | vector &nn_idx, vector &d_indx) 117 | { 118 | qknn que; 119 | double distance; 120 | for(int i=0;i < points.size();++i) 121 | { 122 | distance = q.sqr_dist(points[i]); 123 | que.update(i, distance); 124 | } 125 | que.answer(nn_idx, d_indx); 126 | } 127 | -------------------------------------------------------------------------------- /program/base/stann/bruteNN.hpp~: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: bruteNN.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | /*! 17 | \file 18 | \brief Brute force nearest neighbor search implementation 19 | This file contains a simple brute force NN algorithm implementation. 20 | It is very innefficient and should be used only for accuracy tests. 21 | */ 22 | #include 23 | 24 | #include 25 | 26 | using namespace std; 27 | 28 | /*! 29 | \brief A Brute force NN search class 30 | This class is a simple brute force algorithm for computing nearest neighbors. 31 | It is very innefficient and should be used only for accuracy tests. 32 | */ 33 | template 34 | class bruteNN 35 | { 36 | public: 37 | /*! 38 | \brief Constructor 39 | Constructs a brute force nearest neighbor search structure out 40 | of the given data points. 41 | \param *points Pointer to list of input points 42 | \param N number of input points 43 | */ 44 | bruteNN(Point *points, long int N); 45 | /*! 46 | \brief Destructor 47 | */ 48 | ~bruteNN(); 49 | /*! 50 | \brief Nearest neighbor search function 51 | 52 | This function returns the nearest k neighbors from the data 53 | structure to the given query point. The return vector contains 54 | the indexes to the answer points in the original data array passed 55 | at construction time. 56 | \param q Query point 57 | \param k number of neighbors to search for 58 | \param nn_idx Vector in which answer is written 59 | */ 60 | void ksearch(Point q, int k, 61 | vector &nn_idx); 62 | /*! 63 | \brief Nearest neighbor search function 64 | 65 | This function returns the nearest k neighbors from the data 66 | structure to the given query point, as well as the squared 67 | distance to the query point. The return vector contains 68 | the indexes to the answer points in the original data array 69 | passed at construction time. 70 | \param q Query point 71 | \param k number of neighbors to search for 72 | \param nn_idx Vector in which answer is written 73 | \param d_index Vector in which square distances are written 74 | */ 75 | void ksearch(Point q, int k, 76 | vector &nn_idx, 77 | vector &d_index); 78 | 79 | private: 80 | 81 | vector points; 82 | }; 83 | 84 | template 85 | bruteNN::bruteNN(Point *p, long int N) 86 | { 87 | points.resize(N); 88 | for(int i=0;i < N;++i) 89 | { 90 | points[i] = p[i]; 91 | } 92 | } 93 | 94 | template 95 | bruteNN::~bruteNN() 96 | { 97 | } 98 | 99 | template 100 | void bruteNN::ksearch(Point q, int k, 101 | vector &nn_idx) 102 | { 103 | qknn que; 104 | double distance; 105 | que.set_size(k); 106 | for(unsigned int i=0;i < points.size();++i) 107 | { 108 | distance = q.sqr_dist(points[i]); 109 | que.update(distance, i); 110 | } 111 | que.answer(nn_idx); 112 | } 113 | 114 | template 115 | void bruteNN::ksearch(Point q, int k, 116 | vector &nn_idx, vector &d_indx) 117 | { 118 | qknn que; 119 | double distance; 120 | for(int i=0;i < points.size();++i) 121 | { 122 | distance = q.sqr_dist(points[i]); 123 | que.update(i, distance); 124 | } 125 | que.answer(nn_idx, d_indx); 126 | } 127 | -------------------------------------------------------------------------------- /program/base/stann/bsearch.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: bsearch.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | #ifndef __SFCNN_BSEARCH__ 16 | #define __SFCNN_BSEARCH__ 17 | 18 | #include 19 | #include "zorder_lt.hpp" 20 | 21 | /*! \file 22 | \brief Binary search functions 23 | This file contains binary search functions for z-order operations. 24 | */ 25 | 26 | //! Binary search function 27 | /*! 28 | This function executes a binary search on a vector of pointers to points 29 | \param A Vector of pointers to search 30 | \param *q Pointer to query point 31 | \param lt A less_than comparetor 32 | \return If found: index of point. Otherwise: index of first smaller point 33 | */ 34 | template 35 | long int BinarySearch(vector &A, Point *q, zorder_lt lt) 36 | { 37 | long int low = 0; 38 | long int high = A.size()-1; 39 | long int middle; 40 | 41 | while(low <= high) 42 | { 43 | middle = (low+high)/2; 44 | if(q == A[middle]) 45 | return middle; 46 | else if(lt(q, A[middle])) 47 | high = middle-1; 48 | else 49 | low = middle+1; 50 | } 51 | return middle; 52 | } 53 | 54 | //! A Binary Search function 55 | /*! 56 | This function conducts a binary search for two points at the same time. 57 | \param A Reference to the vector of points being searched 58 | \param q1 pointer to first point to be searched for 59 | \param q2 pointer to second point to be searched for 60 | \param lt less than comparetor 61 | \param p1 reference to return value for q1 location 62 | \param p2 reference to return value for q2 location 63 | */ 64 | 65 | template 66 | void PairBinarySearch(vector &A, Point q1, 67 | Point q2, zorder_lt lt, int &p1, int &p2) 68 | { 69 | int low_q1=0; 70 | int low_q2=0; 71 | int high_q1 = A.size()-1; 72 | int high_q2 = A.size()-1; 73 | int middle = 0; 74 | int middle_store; 75 | 76 | p1 = -2; 77 | p2 = -2; 78 | 79 | while((low_q1 == low_q2) && (high_q1 == high_q2) && (p1 == -2) && (p2 == -2)) 80 | { 81 | middle = (low_q1+high_q1)/2; 82 | if(q1 == A[middle]) 83 | p1 = middle; 84 | else if(lt(q1, A[middle])) 85 | high_q1 = middle-1; 86 | else 87 | low_q1 = middle+1; 88 | if(q2 == A[middle]) 89 | p2 = middle; 90 | else if(lt(q2, A[middle])) 91 | high_q2 = middle-1; 92 | else 93 | low_q2 = middle+1; 94 | } 95 | middle_store = middle; 96 | while(low_q1 <= high_q1) 97 | { 98 | middle = (low_q1+high_q1)/2; 99 | if(q1 == A[middle]) 100 | break; 101 | else if(lt(q1, A[middle])) 102 | high_q1 = middle-1; 103 | else 104 | low_q1 = middle+1; 105 | } 106 | p1 = middle; 107 | middle = middle_store; 108 | while(low_q2 <= high_q2) 109 | { 110 | middle = (low_q2+high_q2)/2; 111 | if(q2 == A[middle]) 112 | break; 113 | else if(lt(q2, A[middle])) 114 | high_q2 = middle-1; 115 | else 116 | low_q2 = middle+1; 117 | } 118 | p2 = middle; 119 | } 120 | 121 | //! A binary search Function. 122 | /* 123 | This function executes a binary search on a vector of points 124 | \param A Vector of points to search 125 | \param q Query point 126 | \param lt A less_than comparetor 127 | \return If found: index of point. Otherwise: index of first smaller point 128 | */ 129 | template 130 | long int BinarySearch(vector &A, Point q, zorder_lt lt) 131 | { 132 | long int low = 0; 133 | long int high = A.size()-1; 134 | long int middle = 0; 135 | 136 | while(low <= high) 137 | { 138 | middle = (low+high)/2; 139 | if(q == A[middle]) 140 | return middle; 141 | else if(lt(q, A[middle])) 142 | high = middle-1; 143 | else 144 | low = middle+1; 145 | } 146 | return middle; 147 | } 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /program/base/stann/bsearch.hpp~: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: bsearch.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | #ifndef __SFCNN_BSEARCH__ 16 | #define __SFCNN_BSEARCH__ 17 | 18 | #include 19 | #include 20 | 21 | /*! \file 22 | \brief Binary search functions 23 | This file contains binary search functions for z-order operations. 24 | */ 25 | 26 | //! Binary search function 27 | /*! 28 | This function executes a binary search on a vector of pointers to points 29 | \param A Vector of pointers to search 30 | \param *q Pointer to query point 31 | \param lt A less_than comparetor 32 | \return If found: index of point. Otherwise: index of first smaller point 33 | */ 34 | template 35 | long int BinarySearch(vector &A, Point *q, zorder_lt lt) 36 | { 37 | long int low = 0; 38 | long int high = A.size()-1; 39 | long int middle; 40 | 41 | while(low <= high) 42 | { 43 | middle = (low+high)/2; 44 | if(q == A[middle]) 45 | return middle; 46 | else if(lt(q, A[middle])) 47 | high = middle-1; 48 | else 49 | low = middle+1; 50 | } 51 | return middle; 52 | } 53 | 54 | //! A Binary Search function 55 | /*! 56 | This function conducts a binary search for two points at the same time. 57 | \param A Reference to the vector of points being searched 58 | \param q1 pointer to first point to be searched for 59 | \param q2 pointer to second point to be searched for 60 | \param lt less than comparetor 61 | \param p1 reference to return value for q1 location 62 | \param p2 reference to return value for q2 location 63 | */ 64 | 65 | template 66 | void PairBinarySearch(vector &A, Point q1, 67 | Point q2, zorder_lt lt, int &p1, int &p2) 68 | { 69 | int low_q1=0; 70 | int low_q2=0; 71 | int high_q1 = A.size()-1; 72 | int high_q2 = A.size()-1; 73 | int middle = 0; 74 | int middle_store; 75 | 76 | p1 = -2; 77 | p2 = -2; 78 | 79 | while((low_q1 == low_q2) && (high_q1 == high_q2) && (p1 == -2) && (p2 == -2)) 80 | { 81 | middle = (low_q1+high_q1)/2; 82 | if(q1 == A[middle]) 83 | p1 = middle; 84 | else if(lt(q1, A[middle])) 85 | high_q1 = middle-1; 86 | else 87 | low_q1 = middle+1; 88 | if(q2 == A[middle]) 89 | p2 = middle; 90 | else if(lt(q2, A[middle])) 91 | high_q2 = middle-1; 92 | else 93 | low_q2 = middle+1; 94 | } 95 | middle_store = middle; 96 | while(low_q1 <= high_q1) 97 | { 98 | middle = (low_q1+high_q1)/2; 99 | if(q1 == A[middle]) 100 | break; 101 | else if(lt(q1, A[middle])) 102 | high_q1 = middle-1; 103 | else 104 | low_q1 = middle+1; 105 | } 106 | p1 = middle; 107 | middle = middle_store; 108 | while(low_q2 <= high_q2) 109 | { 110 | middle = (low_q2+high_q2)/2; 111 | if(q2 == A[middle]) 112 | break; 113 | else if(lt(q2, A[middle])) 114 | high_q2 = middle-1; 115 | else 116 | low_q2 = middle+1; 117 | } 118 | p2 = middle; 119 | } 120 | 121 | //! A binary search Function. 122 | /* 123 | This function executes a binary search on a vector of points 124 | \param A Vector of points to search 125 | \param q Query point 126 | \param lt A less_than comparetor 127 | \return If found: index of point. Otherwise: index of first smaller point 128 | */ 129 | template 130 | long int BinarySearch(vector &A, Point q, zorder_lt lt) 131 | { 132 | long int low = 0; 133 | long int high = A.size()-1; 134 | long int middle = 0; 135 | 136 | while(low <= high) 137 | { 138 | middle = (low+high)/2; 139 | if(q == A[middle]) 140 | return middle; 141 | else if(lt(q, A[middle])) 142 | high = middle-1; 143 | else 144 | low = middle+1; 145 | } 146 | return middle; 147 | } 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /program/base/stann/pair_iter.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: pair_iter.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | #ifndef __PAIR_ITER__ 18 | #define __PAIR_ITER__ 19 | 20 | #include 21 | using namespace std; 22 | 23 | /*! \file pair_iter.hpp 24 | \brief Implementation of an iterator class designed to traverse 25 | two identical vectors simultaneously */ 26 | 27 | /*! \brief The Mypair class is a utility class for the pair_iter class. 28 | It should not be used outside the pair_iter class */ 29 | template 30 | class Mypair 31 | { 32 | typedef typename iterator_traits::value_type value_type1; 33 | typedef typename iterator_traits::value_type value_type2; 34 | public: 35 | Mypair(Iter1 a, Iter2 b) 36 | { 37 | iter1=a; 38 | iter2=b; 39 | val1 = *a; 40 | val2 = *b; 41 | } 42 | Mypair() 43 | { 44 | //cout << "Mypair constructor2" << endl; 45 | }; 46 | ~Mypair() 47 | { 48 | }; 49 | 50 | bool operator<(Mypair a) const 51 | { 52 | return val1(Mypair a) const 55 | { 56 | return val1>a.val1; 57 | } 58 | bool operator>=(Mypair a) const 59 | { 60 | return val1>=a.val1; 61 | } 62 | bool operator<=(Mypair a) const 63 | { 64 | return val1<=a.val1; 65 | } 66 | bool operator==(Mypair a) const 67 | { 68 | return val1==a.val1; 69 | } 70 | Mypair& operator=(Mypair a) 71 | { 72 | //cout << (first()) << "=" << (a.first()) << endl; 73 | //cout << (second()) << "=" << (a.second()) << endl; 74 | *iter1 = a.val1; 75 | *iter2 = a.val2; 76 | return *this; 77 | } 78 | 79 | friend void swap(Mypair a, Mypair b) 80 | { 81 | a = b; 82 | b = a; 83 | } 84 | Iter1 iter1; 85 | Iter2 iter2; 86 | value_type1 val1; 87 | value_type2 val2; 88 | }; 89 | //! Pair iterator class 90 | /*! 91 | The pair_iter class is designed to traverse two vectors 92 | simultaneously. It was intended to be used in conjunction with 93 | stl::sort to order two vectors based upon the value of the first. 94 | Dereferencing this iterator returns a Mypair object. This class has not been 95 | robustly tested outside the STANN framework, and is not garunteed to work 96 | correctly for other uses. 97 | */ 98 | template 99 | class pair_iter 100 | { 101 | public: 102 | typedef Mypair value_type; 103 | typedef typename iterator_traits::difference_type difference_type; 104 | typedef value_type* pointer; 105 | typedef value_type& reference; 106 | typedef random_access_iterator_tag iterator_category; 107 | 108 | friend pair_iter operator+(int n, pair_iter a) 109 | { 110 | return pair_iter(a.iter1+n, a.iter2+n); 111 | }; 112 | 113 | 114 | //------------------------------------ 115 | //Constructor and Destructor 116 | //------------------------------------ 117 | pair_iter(){}; 118 | 119 | pair_iter(const pair_iter &a) 120 | { 121 | iter1 = a.iter1; 122 | iter2 = a.iter2; 123 | }; 124 | 125 | pair_iter(Iter1 i1, Iter2 i2) 126 | { 127 | //cout << "Constructor1" << endl; 128 | iter1=i1; 129 | iter2=i2; 130 | }; 131 | pair_iter(Iter1 i1, Iter2 i2, Iter1 i1begin, Iter2 i2begin) 132 | { 133 | iter1=i1; 134 | iter2=i2; 135 | } 136 | ~pair_iter(){}; 137 | 138 | //------------------------------------- 139 | //Assignment Operator 140 | //------------------------------------- 141 | pair_iter& operator=(pair_iter a) 142 | { 143 | //cout << "operator=" << endl; 144 | iter1 = a.iter1; 145 | iter2 = a.iter2; 146 | 147 | return *this; 148 | }; 149 | 150 | //-------------------------------------- 151 | //Equality Operators 152 | //-------------------------------------- 153 | bool operator==(pair_iter a) 154 | { 155 | //cout << "operator==" << endl; 156 | return iter1==a.iter1; 157 | }; 158 | 159 | bool operator!=(pair_iter a) 160 | { 161 | //cout << "operator!=" << endl; 162 | return iter1 != a.iter1; 163 | }; 164 | //-------------------------------------- 165 | //Comparrison Operators 166 | //-------------------------------------- 167 | bool operator<(pair_iter a) 168 | { 169 | //cout << "operator<" << endl; 170 | return iter1 < a.iter1; 171 | } 172 | bool operator<=(pair_iter a) 173 | { 174 | //cout << "operator<=" << endl; 175 | return iter1 <= a.iter1; 176 | } 177 | bool operator>(pair_iter a) 178 | { 179 | //cout << "operator>" << endl; 180 | return iter1 > a.iter1; 181 | } 182 | bool operator>=(pair_iter a) 183 | { 184 | //cout << "operator>=" << endl; 185 | return iter1 >= a.iter1; 186 | } 187 | //-------------------------------------- 188 | //Dereference Operator 189 | //-------------------------------------- 190 | value_type operator*() 191 | { 192 | //cout << "operator*" << endl; 193 | return value_type(iter1, iter2); 194 | //return *iter1; 195 | }; 196 | value_type& operator[](int n) 197 | { 198 | //cout << "operator[]" << endl; 199 | Mypair ref_pair; 200 | ref_pair.first=iter1+n; 201 | ref_pair.second=iter2+n; 202 | return ref_pair; 203 | //return *iter1; 204 | } 205 | //--------------------------------------- 206 | //Increment and Decrement Operators 207 | //--------------------------------------- 208 | pair_iter& operator++() 209 | { 210 | //cout << "operator++" << endl; 211 | ++iter1; 212 | ++iter2; 213 | return *this; 214 | } 215 | 216 | pair_iter operator++(int) 217 | { 218 | 219 | //cout << "++operator" << endl; 220 | pair_iter c = *this; 221 | iter1++; 222 | iter2++; 223 | return c; 224 | } 225 | 226 | pair_iter& operator--() 227 | { 228 | //cout << "operator--" << endl; 229 | --iter1; 230 | --iter2; 231 | return *this; 232 | } 233 | pair_iter operator--(int) 234 | { 235 | //cout << "--operator" << endl; 236 | pair_iter c = *this; 237 | iter1--; 238 | iter2--; 239 | return c; 240 | } 241 | //--------------------------------------- 242 | //Iterator arithmetic 243 | //--------------------------------------- 244 | pair_iter& operator+=(int n) 245 | { 246 | //cout << "operator+=" << endl; 247 | iter1+=n; 248 | iter2+=n; 249 | return *this; 250 | } 251 | pair_iter operator+(int n) 252 | { 253 | //cout << "operator+" << endl; 254 | return pair_iter(iter1+n, iter2+n); 255 | } 256 | 257 | pair_iter& operator-=(int n) 258 | { 259 | //cout << "operator-=" << endl; 260 | iter1-=n; 261 | iter2-=n; 262 | return *this; 263 | } 264 | pair_iter operator-(int n) 265 | { 266 | //cout << "operator-" << endl; 267 | return pair_iter(iter1-n, iter2-n); 268 | } 269 | 270 | difference_type operator-(pair_iter a) 271 | { 272 | //cout << "operator-2" << endl; 273 | return iter1-a.iter1; 274 | } 275 | //--------------------------------------- 276 | //Iterator variables 277 | //--------------------------------------- 278 | Iter1 iter1; 279 | Iter2 iter2; 280 | }; 281 | #endif 282 | -------------------------------------------------------------------------------- /program/base/stann/qknn.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: qknn.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | #ifndef __QKNN_INT__ 18 | #define __QKNN_INT__ 19 | #include 20 | #include 21 | #include 22 | using namespace std; 23 | 24 | /*! \file qknn.hpp 25 | \brief Implements priority queue functions for dpoints and point pairs */ 26 | 27 | //! Priority Queue element comparator 28 | /*! This class orders priority queue elements based on the distance 29 | given as the first item in the pair 30 | */ 31 | 32 | class q_intelementCompare { 33 | public: 34 | 35 | //! Less than operator 36 | /*! 37 | Compares two priority queue elements based on thier distance 38 | \param p1 First element to be compared 39 | \param p2 Second element to be compared 40 | \return Returns true if p1 distance is less than p2 distance 41 | */ 42 | bool operator()( const pair p1, 43 | const pair p2 ){ 44 | return p1.first < p2.first; 45 | } 46 | }; 47 | 48 | //! Distance Priority Queue 49 | /*! 50 | Implements a priority queue for pairs of floating point 51 | distances and array indexes. The priority queue is ordered 52 | based on the squared distance stored in the first element 53 | of the pair. 54 | */ 55 | 56 | class qknn 57 | { 58 | private: 59 | int K; 60 | typedef pair q_intelement; 61 | typedef priority_queue, q_intelementCompare> 62 | PQ; 63 | PQ pq; 64 | 65 | public: 66 | 67 | //! Constructor 68 | /*! 69 | Creates an empty priority queue. 70 | */ 71 | qknn(){}; 72 | 73 | //! Largest distance 74 | /*! 75 | Returns the largest distance value stored in the priority queue 76 | \return Largest distance value 77 | */ 78 | double topdist(void) 79 | { 80 | return pq.top().first; 81 | } 82 | 83 | //! Set Size 84 | /*! 85 | Sets the size of the priority queue. This should be set before the 86 | queue is used 87 | \param k The maximum number of elements to be stored in the queue. 88 | */ 89 | void set_size(int k) 90 | { 91 | K = k; 92 | } 93 | 94 | //! Point with largest distance 95 | /*! 96 | Returns the index associated with the largest element in the queue. 97 | \return Index of largest (most distant) element 98 | */ 99 | long int top() 100 | { 101 | return pq.top().second; 102 | } 103 | 104 | //! Update queue 105 | /*! 106 | Updates the queue with the given distance and point 107 | \param dist Distance of point to be added 108 | \param p index of point to be added 109 | \return True if a point was added to the queue 110 | */ 111 | bool update(double dist, long int p) 112 | { 113 | if(size() < K) 114 | { 115 | q_intelement tq(dist, p); 116 | pq.push(tq); 117 | return true; 118 | } 119 | else if(topdist() > dist) 120 | { 121 | pq.pop(); 122 | q_intelement tq(dist, p); 123 | pq.push(tq); 124 | return true; 125 | } 126 | return false; 127 | } 128 | 129 | //! Create answer 130 | /*! 131 | Transforms the queue into a vector of indeces to points and returns it 132 | \param pl Vector which will hold the answer after function completes 133 | */ 134 | void answer(vector& pl) 135 | { 136 | pl.resize(K); 137 | for(int i=pl.size()-1;i >= 0;--i) 138 | { 139 | pl[i] = pq.top().second; 140 | pq.pop(); 141 | } 142 | }; 143 | //! Create answer 144 | /*! 145 | Transforms the queue into a vector of indeces to points and a 146 | vector of squared distances 147 | \param pl Vector which holds the point indeces after function completes 148 | \param pd Vector which holds the squared distances from query point 149 | */ 150 | void answer(vector& pl, vector &pd) 151 | { 152 | pl.resize(K); 153 | pd.resize(K); 154 | for(int i=pl.size()-1;i >= 0; --i) 155 | { 156 | pl[i] = pq.top().second; 157 | pd[i] = pq.top().first; 158 | pq.pop(); 159 | } 160 | } 161 | //! Size function 162 | /*! 163 | Returns the current size of the queue 164 | \return Size 165 | */ 166 | int size(){ return pq.size(); } 167 | }; 168 | 169 | #endif 170 | -------------------------------------------------------------------------------- /program/base/stann/rand.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: rand.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | #ifndef __RAND_HPP 18 | #define __RAND_HPP 19 | /*! \file rand.hpp 20 | \brief Replacements for srand48 and drand48 21 | 22 | The standard c++ does not have srand48 and drand48 built into it. 23 | this header replaces 24 | them using the standard C++ calls available for random numbers. 25 | */ 26 | 27 | #include 28 | 29 | static double __drand48__() 30 | { 31 | /* We don't have drand48. Use rand() to get the bits. We call 32 | rand() three times since RAND_MAX it at least 16 bits. */ 33 | double f = 1.0 / (RAND_MAX + 1.0); 34 | double x = std::rand(); 35 | x = x * f + std::rand(); 36 | x = x * f + std::rand(); 37 | return x * f; 38 | } 39 | 40 | static void __srand48__(long int seedval) 41 | { 42 | std::srand(seedval); 43 | return; 44 | } 45 | 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /program/base/stann/sep_float.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: sep_float.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | #ifndef __SEP_FLOAT__ 18 | #define __SEP_FLOAT__ 19 | 20 | #include 21 | #include 22 | 23 | /*! 24 | \file sep_float.hpp 25 | \brief This class stores a float, double or long double as a 26 | significand exponent pair. It allows basic arithmetic operations as 27 | well as computing the most significant differing bit (used for z-order 28 | calculations) 29 | */ 30 | using namespace std; 31 | 32 | template 33 | class sep_float; 34 | 35 | /* 36 | This class extends some of the numeric_limits functionality for seperated 37 | floating point types. It does not operate in exact accordance with the 38 | standard C++ numeric_limits for two reasons. 39 | 40 | First: It does not implement overloads for all numeric_limits functions, 41 | mainly because they are not all needed for STANN 42 | 43 | Second: numeric_limits::min() returns the largest negative value, 44 | not the smallest represtentable positive value. 45 | */ 46 | 47 | namespace std 48 | { 49 | template<> 50 | class numeric_limits > 51 | { 52 | public: 53 | static const bool is_specialized = true; 54 | static float max() throw() {return numeric_limits::max();} 55 | static float min() throw() {return -numeric_limits::max();} 56 | }; 57 | 58 | template<> 59 | class numeric_limits > 60 | { 61 | public: 62 | static const bool is_specialized = true; 63 | static double max() throw() {return numeric_limits::max();} 64 | static double min() throw() {return -numeric_limits::max();} 65 | 66 | }; 67 | 68 | template<> 69 | class numeric_limits > 70 | { 71 | public: 72 | static const bool is_specialized = true; 73 | static long double max() throw() {return numeric_limits::max();} 74 | static long double min() throw() {return -numeric_limits::max();} 75 | 76 | }; 77 | } 78 | 79 | //! Seperated float significand 80 | /*! 81 | This union stores a seperated float significand. 82 | It allows access to the significand as a floating 83 | point type or as an unsigned long integer 84 | */ 85 | template 86 | union sep_float_sig 87 | { 88 | /*! Union accessor of floating point type */ 89 | T d; 90 | /*! Union accessor as an array of integer types */ 91 | unsigned long int i[0]; 92 | }; 93 | 94 | //! XOR function 95 | /*! 96 | This templated function computes a bitwise XOR of two 97 | sep_float_sig unions, based on the size of the underlying 98 | floating point data type. 99 | \param a First value to be XORed 100 | \param b Second value to be XORed 101 | \param c return value 102 | \param zero A baseline value used to restore the floating point structure after XOR, as far as I know it should always be 0.5 103 | */ 104 | template 105 | void xor_sep_float_sig(T1 &a, T1 &b, T1 &c, const T1 &zero) 106 | { 107 | for(unsigned int i=0;i < sizeof(T1)/sizeof(unsigned long int);++i) 108 | { 109 | c.i[i]=(a.i[i]^b.i[i])|zero.i[i]; 110 | } 111 | } 112 | 113 | /*! sep_float type 114 | \brief This class stores a float, long or double as an integer significand 115 | and an integer exponent. 116 | */ 117 | template 118 | class sep_float 119 | { 120 | /*! sep_float overload of output stream function 121 | \brief This will put the floating point number on the 122 | output stream, not the seperated number 123 | \param os Output stream to be appended to 124 | \param x seperated float to be added to output stream 125 | \return output stream with floating point number appended 126 | */ 127 | friend ostream& operator<<(ostream& os, const sep_float &x) 128 | { 129 | os << ldexp(x.sig.d, x.exp); 130 | return os; 131 | } 132 | /*! msdb function 133 | \brief This function computes the most significant differing 134 | bit of two seperated floating point numbers. The return value is 135 | the exponent of the highest order bit that differs between the two numbers. 136 | Note: The msdb of the two floating point numbers is NOT computed based 137 | on the internal representation of the floating point number. The answer 138 | is computed based on a theoretical integer representation of the numbers. 139 | \param x First value to be compared. 140 | \param y Second value to be compared. 141 | \return Most significant differing bit of x and y 142 | */ 143 | friend int msdb(sep_float x, sep_float y) 144 | { 145 | const sep_float_sig lzero = {0.5}; 146 | 147 | if(x.val == y.val) 148 | return numeric_limits::min(); 149 | else if(x.exp == y.exp) 150 | { 151 | xor_sep_float_sig(x.sig, y.sig, x.sig, lzero); 152 | frexp(x.sig.d-0.5, &y.exp); 153 | return x.exp+y.exp; 154 | } 155 | else if(x.exp > y.exp) 156 | return x.exp; 157 | else 158 | return y.exp; 159 | } 160 | 161 | template 162 | friend sep_float& operator+=(sep_float &y, T &x) 163 | { 164 | y = (y.val+x); 165 | return y; 166 | } 167 | template 168 | friend sep_float& operator-=(sep_float &y, T &x) 169 | { 170 | y = (y.val-x); 171 | return y; 172 | } 173 | public: 174 | typedef FLT flt_type; 175 | sep_float(){;} 176 | sep_float(FLT x) 177 | { 178 | sep_set_val(x); 179 | } 180 | 181 | sep_float(const sep_float &x) 182 | { 183 | sep_float_copy(x); 184 | } 185 | ~sep_float(){;} 186 | sep_float& operator=(const sep_float &x) 187 | { 188 | sep_float_copy(x); 189 | return *this; 190 | } 191 | template 192 | sep_float& operator+=(const T& x) 193 | { 194 | sep_set_val(val+x); 195 | return *this; 196 | } 197 | template 198 | sep_float& operator-=(const T& x) 199 | { 200 | sep_set_val(val-x); 201 | return *this; 202 | } 203 | template 204 | sep_float& operator*=(const T& x) 205 | { 206 | sep_set_val(val*x); 207 | return *this; 208 | } 209 | template 210 | sep_float& operator/=(const T& x) 211 | { 212 | sep_set_val(val/x); 213 | return *this; 214 | } 215 | FLT get_flt() 216 | { 217 | return val; 218 | } 219 | double get_sig() 220 | { 221 | return sig.d; 222 | } 223 | int get_exp() 224 | { 225 | return exp; 226 | } 227 | operator double() 228 | { 229 | return (double)val; 230 | } 231 | private: 232 | void sep_set_val(const FLT &x) 233 | { 234 | val = x; 235 | sig.d = frexp(x, &exp); 236 | } 237 | void sep_float_copy(const sep_float &x) 238 | { 239 | sig.d = x.sig.d; 240 | exp = x.exp; 241 | val = x.val; 242 | } 243 | sep_float_sig sig; 244 | int exp; 245 | FLT val; 246 | }; 247 | 248 | #endif 249 | -------------------------------------------------------------------------------- /program/base/stann/test.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: test.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | #ifndef STANN_TEST 18 | #define STANN_TEST 19 | #include 20 | #include 21 | 22 | #include "bruteNN.hpp" 23 | #include "dpoint.hpp" 24 | #include "rand.hpp" 25 | #include "sfcnn.hpp" 26 | #include "sfcnn_knng.hpp" 27 | 28 | using namespace std; 29 | /*! \file test.hpp 30 | \brief Header file for the test.cpp program.*/ 31 | 32 | template 33 | Point newRandomPoint(T Min, T Max) 34 | { 35 | double d; 36 | Point a; 37 | double max, min; 38 | 39 | max = (double) Max / (double) numeric_limits::max(); 40 | min = (double) Min / (double) numeric_limits::max(); 41 | for(unsigned int i=0;i < Point::__DIM;++i) 42 | { 43 | d = __drand48__(); 44 | d = d*(max-min)-max; 45 | d *= (double) numeric_limits::max(); 46 | d *= -1; 47 | a[i] = (T) d; 48 | } 49 | return a; 50 | } 51 | 52 | template 53 | bool testNN(unsigned int Size, unsigned int k, T min, T max) 54 | { 55 | typedef reviver::dpoint Point; 56 | vector data; 57 | vector query; 58 | vector sfcnn_ans; 59 | vector bf_ans; 60 | 61 | data.resize(Size); 62 | query.resize(Size); 63 | 64 | for(unsigned int i=0;i < data.size();++i) 65 | { 66 | data[i] = newRandomPoint(min, max); 67 | query[i] = newRandomPoint(min, max); 68 | } 69 | 70 | bruteNN BF(&data[0], data.size()); 71 | sfcnn SFC(&data[0], data.size()); 72 | 73 | for(unsigned int i=0;i < data.size();++i) 74 | { 75 | BF.ksearch(query[i], k, bf_ans); 76 | SFC.ksearch(query[i], k, sfcnn_ans); 77 | 78 | for(unsigned int j=0;j < Point::__DIM;++j) 79 | { 80 | if(bf_ans[j] != sfcnn_ans[j]) 81 | { 82 | /* 83 | cerr << "SFCNN:" << endl; 84 | for(unsigned int q=0;q < sfcnn_ans.size();++q) 85 | { 86 | cerr << sfcnn_ans[q] << endl; 87 | } 88 | cerr << "BF:" << endl; 89 | for(unsigned int q=0;q < bf_ans.size();++q) 90 | { 91 | cerr << bf_ans[q] << endl; 92 | } 93 | */ 94 | return false; 95 | } 96 | } 97 | } 98 | return true; 99 | } 100 | 101 | template 102 | bool testKNNG(unsigned int Size, unsigned int k, T min, T max, int num_threads) 103 | { 104 | typedef reviver::dpoint Point; 105 | vector data; 106 | vector bf_ans; 107 | 108 | data.resize(Size); 109 | 110 | for(unsigned int i=0;i < data.size();++i) 111 | { 112 | data[i] = newRandomPoint(min, max); 113 | } 114 | 115 | bruteNN BF(&data[0], data.size()); 116 | sfcnn_knng SFC(&data[0], data.size(), k, num_threads); 117 | 118 | for(unsigned int i=0;i < data.size();++i) 119 | { 120 | BF.ksearch(data[i], k+1, bf_ans); 121 | for(unsigned int j=1;j < k+1;++j) 122 | { 123 | if(bf_ans[j] != SFC[i][j-1]) 124 | { 125 | 126 | cerr << "SFCNN:" << endl; 127 | for(unsigned int q=0;q < SFC[i].size();++q) 128 | { 129 | cerr << SFC[i][q] << endl; 130 | } 131 | cerr << "BF:" << endl; 132 | for(unsigned int q=0;q < bf_ans.size();++q) 133 | { 134 | cerr << bf_ans[q] << endl; 135 | } 136 | 137 | return false; 138 | } 139 | } 140 | } 141 | return true; 142 | } 143 | #endif 144 | -------------------------------------------------------------------------------- /program/base/stann/test.hpp~: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: test.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | #ifndef STANN_TEST 18 | #define STANN_TEST 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | using namespace std; 29 | /*! \file test.hpp 30 | \brief Header file for the test.cpp program.*/ 31 | 32 | template 33 | Point newRandomPoint(T Min, T Max) 34 | { 35 | double d; 36 | Point a; 37 | double max, min; 38 | 39 | max = (double) Max / (double) numeric_limits::max(); 40 | min = (double) Min / (double) numeric_limits::max(); 41 | for(unsigned int i=0;i < Point::__DIM;++i) 42 | { 43 | d = __drand48__(); 44 | d = d*(max-min)-max; 45 | d *= (double) numeric_limits::max(); 46 | d *= -1; 47 | a[i] = (T) d; 48 | } 49 | return a; 50 | } 51 | 52 | template 53 | bool testNN(unsigned int Size, unsigned int k, T min, T max) 54 | { 55 | typedef reviver::dpoint Point; 56 | vector data; 57 | vector query; 58 | vector sfcnn_ans; 59 | vector bf_ans; 60 | 61 | data.resize(Size); 62 | query.resize(Size); 63 | 64 | for(unsigned int i=0;i < data.size();++i) 65 | { 66 | data[i] = newRandomPoint(min, max); 67 | query[i] = newRandomPoint(min, max); 68 | } 69 | 70 | bruteNN BF(&data[0], data.size()); 71 | sfcnn SFC(&data[0], data.size()); 72 | 73 | for(unsigned int i=0;i < data.size();++i) 74 | { 75 | BF.ksearch(query[i], k, bf_ans); 76 | SFC.ksearch(query[i], k, sfcnn_ans); 77 | 78 | for(unsigned int j=0;j < Point::__DIM;++j) 79 | { 80 | if(bf_ans[j] != sfcnn_ans[j]) 81 | { 82 | /* 83 | cerr << "SFCNN:" << endl; 84 | for(unsigned int q=0;q < sfcnn_ans.size();++q) 85 | { 86 | cerr << sfcnn_ans[q] << endl; 87 | } 88 | cerr << "BF:" << endl; 89 | for(unsigned int q=0;q < bf_ans.size();++q) 90 | { 91 | cerr << bf_ans[q] << endl; 92 | } 93 | */ 94 | return false; 95 | } 96 | } 97 | } 98 | return true; 99 | } 100 | 101 | template 102 | bool testKNNG(unsigned int Size, unsigned int k, T min, T max, int num_threads) 103 | { 104 | typedef reviver::dpoint Point; 105 | vector data; 106 | vector bf_ans; 107 | 108 | data.resize(Size); 109 | 110 | for(unsigned int i=0;i < data.size();++i) 111 | { 112 | data[i] = newRandomPoint(min, max); 113 | } 114 | 115 | bruteNN BF(&data[0], data.size()); 116 | sfcnn_knng SFC(&data[0], data.size(), k, num_threads); 117 | 118 | for(unsigned int i=0;i < data.size();++i) 119 | { 120 | BF.ksearch(data[i], k+1, bf_ans); 121 | for(unsigned int j=1;j < k+1;++j) 122 | { 123 | if(bf_ans[j] != SFC[i][j-1]) 124 | { 125 | 126 | cerr << "SFCNN:" << endl; 127 | for(unsigned int q=0;q < SFC[i].size();++q) 128 | { 129 | cerr << SFC[i][q] << endl; 130 | } 131 | cerr << "BF:" << endl; 132 | for(unsigned int q=0;q < bf_ans.size();++q) 133 | { 134 | cerr << bf_ans[q] << endl; 135 | } 136 | 137 | return false; 138 | } 139 | } 140 | } 141 | return true; 142 | } 143 | #endif 144 | -------------------------------------------------------------------------------- /program/base/stann/zorder_lt.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: zorder_lt.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | #ifndef __SFCNN_ZORDER_LT__ 18 | #define __SFCNN_ZORDER_LT__ 19 | 20 | #include "dpoint.hpp" 21 | #include 22 | #include 23 | #include 24 | #include "zorder_type_traits.hpp" 25 | #include "sep_float.hpp" 26 | #include "pair_iter.hpp" 27 | 28 | using namespace std; 29 | 30 | template 31 | class zorder_lt; 32 | template 33 | class zorder_lt_worker; 34 | 35 | //Z Order spec for unsigned integral types 36 | template 37 | class zorder_lt_worker 38 | { 39 | public: 40 | zorder_lt_worker(){;} 41 | ~zorder_lt_worker(){;} 42 | bool operator()(const Point &p, const Point &q) 43 | { 44 | return lt_func(p,q); 45 | } 46 | 47 | double dist_sq_to_quad_box(Point &q, Point &p1, Point &p2) 48 | { 49 | unsigned int j; 50 | int i; 51 | CType x,y; 52 | double z; 53 | z=0; 54 | for(j=x=0;j < Point::__DIM;++j) 55 | { 56 | y = p1[j]^p2[j]; 57 | if(less_msb(x, y)) 58 | { 59 | x = y; 60 | } 61 | } 62 | frexp((float)x, &i); 63 | for(j=0;j < Point::__DIM;++j) 64 | { 65 | x = (((p1)[j])>>i)< y) 70 | z+= pow(((double) q[j]-(double) y), 2.0); 71 | } 72 | //cout << q << endl << p1 << endl << p2 << endl << z << endl; 73 | return z; 74 | } 75 | 76 | 77 | private: 78 | bool lt_func(const Point &p, const Point &q) 79 | { 80 | CType j,x,y,k; 81 | for(j=k=x=0;k < Point::__DIM;++k) 82 | { 83 | y = (p[k])^(q[k]); 84 | if(less_msb(x,y)) 85 | { 86 | j=k; 87 | x=y; 88 | } 89 | } 90 | return p[j] < q[j]; 91 | } 92 | 93 | bool less_msb(CType x, CType y) 94 | { 95 | return (x < y) && (x < (x^y)); 96 | } 97 | }; 98 | 99 | 100 | //Z Order spec for signed integral types 101 | template 102 | class zorder_lt_worker 103 | { 104 | public: 105 | zorder_lt_worker(){;} 106 | ~zorder_lt_worker(){;} 107 | bool operator()(const Point &p, const Point &q) 108 | { 109 | return lt_func(p,q); 110 | } 111 | 112 | double dist_sq_to_quad_box(Point &q, Point &p1, Point &p2) 113 | { 114 | unsigned int j; 115 | int i; 116 | CType x,y; 117 | double z, X, Y; 118 | 119 | x = numeric_limits::min(); 120 | for(j=0;j < Point::__DIM;++j) 121 | { 122 | if((p1[j] < 0) != (p2[j] < 0)) 123 | { 124 | //cout << "Break out" << endl; 125 | //cout << "P1: " << p1 << endl << "P2: " << p2 << endl; 126 | return 0; 127 | } 128 | y = p1[j]^p2[j]; 129 | if(less_msb(x,y)) x = y; 130 | } 131 | frexp((double)x, &i); 132 | //cout << "i: " << i << endl; 133 | //int exp; 134 | for(z=j=0;j < Point::__DIM;++j) 135 | { 136 | X = (p1[j]>>i)<> i) << endl; 139 | //cout << "exp: " << exp << endl; 140 | //cout << "X: " << X << endl; 141 | Y = X+(1 << i); 142 | if(q[j] < X) 143 | z+=pow(((double) X - (double) q[j]), 2.0); 144 | else if(q[j] > Y) 145 | z+=pow(((double) q[j] - (double) Y), 2.0); 146 | } 147 | return z; 148 | } 149 | 150 | private: 151 | bool lt_func(const Point &p, const Point &q) 152 | { 153 | CType j,x,y; 154 | unsigned int k; 155 | x = numeric_limits::min(); 156 | for(j=k=0;k < Point::__DIM;++k) 157 | { 158 | if((p[k] < 0) != (q[k] < 0)) 159 | return p[k] < q[k]; 160 | y = (p[k])^(q[k]); 161 | if(less_msb(x,y)) 162 | { 163 | j=k; 164 | x=y; 165 | } 166 | } 167 | return p[j] < q[j]; 168 | } 169 | 170 | bool less_msb(CType x, CType y) 171 | { 172 | return (x < y) && (x < (x^y)); 173 | } 174 | 175 | }; 176 | 177 | 178 | //Z Order spec for seperated floating point types 179 | template 180 | class zorder_lt_worker 181 | { 182 | public: 183 | zorder_lt_worker() 184 | { 185 | } 186 | ~zorder_lt_worker(){;} 187 | bool operator()(const Point &p, const Point &q) 188 | { 189 | return lt_func(p,q); 190 | } 191 | double dist_sq_to_quad_box(Point &q, Point &p1, Point &p2) 192 | { 193 | unsigned int j; 194 | int x,y; 195 | double box_edge_1, box_edge_2; 196 | double z; 197 | typename CType::flt_type box_dist; 198 | 199 | z = 0; 200 | x = 0; 201 | //cout << "X: " << x << endl; 202 | for(j=0;j < Point::__DIM;++j) 203 | { 204 | if((p1[j].get_flt() < 0) != (p2[j].get_flt() < 0)) 205 | return 0; 206 | y = msdb(p1[j], p2[j]); 207 | if(y > x) 208 | { 209 | x = y; 210 | } 211 | } 212 | box_dist = pow(2.0,x); 213 | for(j=0;j < Point::__DIM;++j) 214 | { 215 | //cout << "p1[j]/2**i: " << floor(p1[j] / box_dist) << endl; 216 | //box_edge_1 = p1[j].get_flt() - fmod(p1[j].get_flt(),box_dist); 217 | box_edge_1 = floor(p1[j] / box_dist) * box_dist; 218 | //cout << "Box1: " << box_edge_1 << endl; 219 | box_edge_2 = box_edge_1+box_dist; 220 | 221 | if(q[j].get_flt() < box_edge_1) 222 | z+=(q[j].get_flt()-box_edge_1)*(q[j].get_flt()-box_edge_1); 223 | else if(q[j].get_flt() > box_edge_2) 224 | z+= (q[j].get_flt()-box_edge_2)*(q[j].get_flt()-box_edge_2); 225 | } 226 | return z; 227 | } 228 | 229 | private: 230 | bool lt_func(const Point &p, const Point &q) 231 | { 232 | int y,x; 233 | unsigned int k,j; 234 | j = 0; 235 | x = 0; 236 | for(k=0;k < Point::__DIM;++k) 237 | { 238 | if((p[k].get_flt() < 0) != (q[k].get_flt() < 0)) 239 | return p[k].get_flt() < q[k].get_flt(); 240 | y = msdb(p[k], q[k]); 241 | if(x < y) 242 | { 243 | j = k; 244 | x = y; 245 | } 246 | } 247 | return p[j] < q[j]; 248 | } 249 | }; 250 | 251 | template 252 | class zorder_lt 253 | { 254 | public: 255 | zorder_lt() 256 | { 257 | zorder_traits::check_type(); 258 | } 259 | ~zorder_lt(){;} 260 | bool operator()(const Point &p, const Point &q) 261 | { 262 | return lt(p, q); 263 | } 264 | bool operator()(const Mypair::iterator,typename vector::iterator> &p, const Mypair::iterator, typename vector::iterator> &q) 265 | { 266 | return lt(p.val1, q.val1); 267 | } 268 | double dist_sq_to_quad_box(Point &q, Point &p1, Point &p2) 269 | { 270 | return lt.dist_sq_to_quad_box(q,p1,p2); 271 | } 272 | private: 273 | zorder_lt_worker::is_signed, typename zorder_traits::is_integral, typename zorder_traits::is_seperated> lt; 274 | }; 275 | #endif 276 | -------------------------------------------------------------------------------- /program/base/stann/zorder_lt.hpp~: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: zorder_lt.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | #ifndef __SFCNN_ZORDER_LT__ 18 | #define __SFCNN_ZORDER_LT__ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | using namespace std; 29 | 30 | template 31 | class zorder_lt; 32 | template 33 | class zorder_lt_worker; 34 | 35 | //Z Order spec for unsigned integral types 36 | template 37 | class zorder_lt_worker 38 | { 39 | public: 40 | zorder_lt_worker(){;} 41 | ~zorder_lt_worker(){;} 42 | bool operator()(const Point &p, const Point &q) 43 | { 44 | return lt_func(p,q); 45 | } 46 | 47 | double dist_sq_to_quad_box(Point &q, Point &p1, Point &p2) 48 | { 49 | unsigned int j; 50 | int i; 51 | CType x,y; 52 | double z; 53 | z=0; 54 | for(j=x=0;j < Point::__DIM;++j) 55 | { 56 | y = p1[j]^p2[j]; 57 | if(less_msb(x, y)) 58 | { 59 | x = y; 60 | } 61 | } 62 | frexp((float)x, &i); 63 | for(j=0;j < Point::__DIM;++j) 64 | { 65 | x = (((p1)[j])>>i)< y) 70 | z+= pow(((double) q[j]-(double) y), 2.0); 71 | } 72 | //cout << q << endl << p1 << endl << p2 << endl << z << endl; 73 | return z; 74 | } 75 | 76 | 77 | private: 78 | bool lt_func(const Point &p, const Point &q) 79 | { 80 | CType j,x,y,k; 81 | for(j=k=x=0;k < Point::__DIM;++k) 82 | { 83 | y = (p[k])^(q[k]); 84 | if(less_msb(x,y)) 85 | { 86 | j=k; 87 | x=y; 88 | } 89 | } 90 | return p[j] < q[j]; 91 | } 92 | 93 | bool less_msb(CType x, CType y) 94 | { 95 | return (x < y) && (x < (x^y)); 96 | } 97 | }; 98 | 99 | 100 | //Z Order spec for signed integral types 101 | template 102 | class zorder_lt_worker 103 | { 104 | public: 105 | zorder_lt_worker(){;} 106 | ~zorder_lt_worker(){;} 107 | bool operator()(const Point &p, const Point &q) 108 | { 109 | return lt_func(p,q); 110 | } 111 | 112 | double dist_sq_to_quad_box(Point &q, Point &p1, Point &p2) 113 | { 114 | unsigned int j; 115 | int i; 116 | CType x,y; 117 | double z, X, Y; 118 | 119 | x = numeric_limits::min(); 120 | for(j=0;j < Point::__DIM;++j) 121 | { 122 | if((p1[j] < 0) != (p2[j] < 0)) 123 | { 124 | //cout << "Break out" << endl; 125 | //cout << "P1: " << p1 << endl << "P2: " << p2 << endl; 126 | return 0; 127 | } 128 | y = p1[j]^p2[j]; 129 | if(less_msb(x,y)) x = y; 130 | } 131 | frexp((double)x, &i); 132 | //cout << "i: " << i << endl; 133 | //int exp; 134 | for(z=j=0;j < Point::__DIM;++j) 135 | { 136 | X = (p1[j]>>i)<> i) << endl; 139 | //cout << "exp: " << exp << endl; 140 | //cout << "X: " << X << endl; 141 | Y = X+(1 << i); 142 | if(q[j] < X) 143 | z+=pow(((double) X - (double) q[j]), 2.0); 144 | else if(q[j] > Y) 145 | z+=pow(((double) q[j] - (double) Y), 2.0); 146 | } 147 | return z; 148 | } 149 | 150 | private: 151 | bool lt_func(const Point &p, const Point &q) 152 | { 153 | CType j,x,y; 154 | unsigned int k; 155 | x = numeric_limits::min(); 156 | for(j=k=0;k < Point::__DIM;++k) 157 | { 158 | if((p[k] < 0) != (q[k] < 0)) 159 | return p[k] < q[k]; 160 | y = (p[k])^(q[k]); 161 | if(less_msb(x,y)) 162 | { 163 | j=k; 164 | x=y; 165 | } 166 | } 167 | return p[j] < q[j]; 168 | } 169 | 170 | bool less_msb(CType x, CType y) 171 | { 172 | return (x < y) && (x < (x^y)); 173 | } 174 | 175 | }; 176 | 177 | 178 | //Z Order spec for seperated floating point types 179 | template 180 | class zorder_lt_worker 181 | { 182 | public: 183 | zorder_lt_worker() 184 | { 185 | } 186 | ~zorder_lt_worker(){;} 187 | bool operator()(const Point &p, const Point &q) 188 | { 189 | return lt_func(p,q); 190 | } 191 | double dist_sq_to_quad_box(Point &q, Point &p1, Point &p2) 192 | { 193 | unsigned int j; 194 | int x,y; 195 | double box_edge_1, box_edge_2; 196 | double z; 197 | typename CType::flt_type box_dist; 198 | 199 | z = 0; 200 | x = 0; 201 | //cout << "X: " << x << endl; 202 | for(j=0;j < Point::__DIM;++j) 203 | { 204 | if((p1[j].get_flt() < 0) != (p2[j].get_flt() < 0)) 205 | return 0; 206 | y = msdb(p1[j], p2[j]); 207 | if(y > x) 208 | { 209 | x = y; 210 | } 211 | } 212 | box_dist = pow(2.0,x); 213 | for(j=0;j < Point::__DIM;++j) 214 | { 215 | //cout << "p1[j]/2**i: " << floor(p1[j] / box_dist) << endl; 216 | //box_edge_1 = p1[j].get_flt() - fmod(p1[j].get_flt(),box_dist); 217 | box_edge_1 = floor(p1[j] / box_dist) * box_dist; 218 | //cout << "Box1: " << box_edge_1 << endl; 219 | box_edge_2 = box_edge_1+box_dist; 220 | 221 | if(q[j].get_flt() < box_edge_1) 222 | z+=(q[j].get_flt()-box_edge_1)*(q[j].get_flt()-box_edge_1); 223 | else if(q[j].get_flt() > box_edge_2) 224 | z+= (q[j].get_flt()-box_edge_2)*(q[j].get_flt()-box_edge_2); 225 | } 226 | return z; 227 | } 228 | 229 | private: 230 | bool lt_func(const Point &p, const Point &q) 231 | { 232 | int y,x; 233 | unsigned int k,j; 234 | j = 0; 235 | x = 0; 236 | for(k=0;k < Point::__DIM;++k) 237 | { 238 | if((p[k].get_flt() < 0) != (q[k].get_flt() < 0)) 239 | return p[k].get_flt() < q[k].get_flt(); 240 | y = msdb(p[k], q[k]); 241 | if(x < y) 242 | { 243 | j = k; 244 | x = y; 245 | } 246 | } 247 | return p[j] < q[j]; 248 | } 249 | }; 250 | 251 | template 252 | class zorder_lt 253 | { 254 | public: 255 | zorder_lt() 256 | { 257 | zorder_traits::check_type(); 258 | } 259 | ~zorder_lt(){;} 260 | bool operator()(const Point &p, const Point &q) 261 | { 262 | return lt(p, q); 263 | } 264 | bool operator()(const Mypair::iterator,typename vector::iterator> &p, const Mypair::iterator, typename vector::iterator> &q) 265 | { 266 | return lt(p.val1, q.val1); 267 | } 268 | double dist_sq_to_quad_box(Point &q, Point &p1, Point &p2) 269 | { 270 | return lt.dist_sq_to_quad_box(q,p1,p2); 271 | } 272 | private: 273 | zorder_lt_worker::is_signed, typename zorder_traits::is_integral, typename zorder_traits::is_seperated> lt; 274 | }; 275 | #endif 276 | -------------------------------------------------------------------------------- /program/base/stann/zorder_type_traits.hpp: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: zorder_type_traits.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | 18 | 19 | #ifndef __ZORDER_TYPE_TRAITS__ 20 | #define __ZORDER_TYPE_TRAITS__ 21 | 22 | #include 23 | #include "sep_float.hpp" 24 | using namespace std; 25 | 26 | struct zorder_t {}; 27 | struct zorder_f {}; 28 | 29 | template 30 | class zorder_traits 31 | { 32 | public: 33 | static void check_type() 34 | { 35 | //cerr << "Error: Type traits not defined." << endl; 36 | //cerr << "Please ensure the appropriate type is added to zorder_traits.hpp" << endl; 37 | //cerr << "and contact author for update." << endl; 38 | //exit(1); 39 | } 40 | typedef zorder_t is_signed; 41 | typedef zorder_t is_integral; 42 | typedef int unsigned_type; 43 | typedef unsigned int signed_type; 44 | }; 45 | 46 | template<> 47 | class zorder_traits 48 | { 49 | public: 50 | static void check_type(){}; 51 | typedef zorder_t is_signed; 52 | typedef zorder_t is_integral; 53 | typedef zorder_f is_seperated; 54 | typedef unsigned int unsigned_type; 55 | typedef int signed_type; 56 | }; 57 | 58 | template<> 59 | class zorder_traits 60 | { 61 | public: 62 | static void check_type(){}; 63 | typedef zorder_f is_signed; 64 | typedef zorder_t is_integral; 65 | typedef zorder_f is_seperated; 66 | typedef unsigned int unsigned_type; 67 | typedef int signed_type; 68 | }; 69 | 70 | template<> 71 | class zorder_traits 72 | { 73 | public: 74 | static void check_type(){}; 75 | typedef zorder_t is_signed; 76 | typedef zorder_t is_integral; 77 | typedef zorder_f is_seperated; 78 | typedef unsigned char unsigned_type; 79 | typedef char signed_type; 80 | }; 81 | 82 | template<> 83 | class zorder_traits 84 | { 85 | public: 86 | static void check_type(){}; 87 | typedef zorder_f is_signed; 88 | typedef zorder_t is_integral; 89 | typedef zorder_f is_seperated; 90 | typedef unsigned char unsigned_type; 91 | typedef char signed_type; 92 | }; 93 | 94 | template<> 95 | class zorder_traits 96 | { 97 | public: 98 | static void check_type(){}; 99 | typedef zorder_t is_signed; 100 | typedef zorder_t is_integral; 101 | typedef zorder_f is_seperated; 102 | typedef unsigned short unsigned_type; 103 | typedef short signed_type; 104 | }; 105 | 106 | template<> 107 | class zorder_traits 108 | { 109 | public: 110 | static void check_type(){}; 111 | typedef zorder_f is_signed; 112 | typedef zorder_t is_integral; 113 | typedef zorder_f is_seperated; 114 | typedef unsigned short unsigned_type; 115 | typedef unsigned short signed_type; 116 | }; 117 | 118 | template<> 119 | class zorder_traits 120 | { 121 | public: 122 | static void check_type(){}; 123 | typedef zorder_t is_signed; 124 | typedef zorder_t is_integral; 125 | typedef zorder_f is_seperated; 126 | typedef long unsigned int unsigned_type; 127 | typedef long int signed_type; 128 | }; 129 | 130 | template<> 131 | class zorder_traits 132 | { 133 | public: 134 | static void check_type(){}; 135 | typedef zorder_f is_signed; 136 | typedef zorder_t is_integral; 137 | typedef zorder_f is_seperated; 138 | typedef long unsigned int unsigned_type; 139 | typedef long unsigned int signed_type; 140 | }; 141 | 142 | template<> 143 | class zorder_traits 144 | { 145 | public: 146 | static void check_type(){}; 147 | typedef zorder_t is_signed; 148 | typedef zorder_f is_integral; 149 | typedef zorder_f is_seperated; 150 | typedef float unsigned_type; 151 | typedef float signed_type; 152 | }; 153 | 154 | template<> 155 | class zorder_traits 156 | { 157 | public: 158 | static void check_type(){}; 159 | typedef zorder_t is_signed; 160 | typedef zorder_f is_integral; 161 | typedef zorder_f is_seperated; 162 | typedef double unsigned_type; 163 | typedef double signed_type; 164 | }; 165 | 166 | template<> 167 | class zorder_traits 168 | { 169 | public: 170 | static void check_type(){}; 171 | typedef zorder_t is_signed; 172 | typedef zorder_f is_integral; 173 | typedef zorder_f is_seperated; 174 | typedef long double unsigned_type; 175 | typedef long double signed_type; 176 | }; 177 | 178 | template<> 179 | class zorder_traits > 180 | { 181 | public: 182 | static void check_type(){}; 183 | typedef zorder_t is_signed; 184 | typedef zorder_f is_integral; 185 | typedef zorder_t is_seperated; 186 | }; 187 | 188 | template<> 189 | class zorder_traits > 190 | { 191 | public: 192 | static void check_type(){}; 193 | typedef zorder_t is_signed; 194 | typedef zorder_f is_integral; 195 | typedef zorder_t is_seperated; 196 | }; 197 | 198 | template<> 199 | class zorder_traits > 200 | { 201 | public: 202 | static void check_type(){}; 203 | typedef zorder_t is_signed; 204 | typedef zorder_f is_integral; 205 | typedef zorder_t is_seperated; 206 | }; 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /program/base/stann/zorder_type_traits.hpp~: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* Header: zorder_type_traits.hpp */ 4 | /* */ 5 | /* Accompanies STANN Version 0.5 Beta */ 6 | /* Aug 05, 2008 */ 7 | /* */ 8 | /* Copyright 2007, 2008 */ 9 | /* Michael Connor and Piyush Kumar */ 10 | /* Florida State University */ 11 | /* Tallahassee FL, 32306-4532 */ 12 | /* */ 13 | /*****************************************************************************/ 14 | 15 | 16 | 17 | 18 | 19 | #ifndef __ZORDER_TYPE_TRAITS__ 20 | #define __ZORDER_TYPE_TRAITS__ 21 | 22 | #include 23 | #include 24 | using namespace std; 25 | 26 | struct zorder_t {}; 27 | struct zorder_f {}; 28 | 29 | template 30 | class zorder_traits 31 | { 32 | public: 33 | static void check_type() 34 | { 35 | //cerr << "Error: Type traits not defined." << endl; 36 | //cerr << "Please ensure the appropriate type is added to zorder_traits.hpp" << endl; 37 | //cerr << "and contact author for update." << endl; 38 | //exit(1); 39 | } 40 | typedef zorder_t is_signed; 41 | typedef zorder_t is_integral; 42 | typedef int unsigned_type; 43 | typedef unsigned int signed_type; 44 | }; 45 | 46 | template<> 47 | class zorder_traits 48 | { 49 | public: 50 | static void check_type(){}; 51 | typedef zorder_t is_signed; 52 | typedef zorder_t is_integral; 53 | typedef zorder_f is_seperated; 54 | typedef unsigned int unsigned_type; 55 | typedef int signed_type; 56 | }; 57 | 58 | template<> 59 | class zorder_traits 60 | { 61 | public: 62 | static void check_type(){}; 63 | typedef zorder_f is_signed; 64 | typedef zorder_t is_integral; 65 | typedef zorder_f is_seperated; 66 | typedef unsigned int unsigned_type; 67 | typedef int signed_type; 68 | }; 69 | 70 | template<> 71 | class zorder_traits 72 | { 73 | public: 74 | static void check_type(){}; 75 | typedef zorder_t is_signed; 76 | typedef zorder_t is_integral; 77 | typedef zorder_f is_seperated; 78 | typedef unsigned char unsigned_type; 79 | typedef char signed_type; 80 | }; 81 | 82 | template<> 83 | class zorder_traits 84 | { 85 | public: 86 | static void check_type(){}; 87 | typedef zorder_f is_signed; 88 | typedef zorder_t is_integral; 89 | typedef zorder_f is_seperated; 90 | typedef unsigned char unsigned_type; 91 | typedef char signed_type; 92 | }; 93 | 94 | template<> 95 | class zorder_traits 96 | { 97 | public: 98 | static void check_type(){}; 99 | typedef zorder_t is_signed; 100 | typedef zorder_t is_integral; 101 | typedef zorder_f is_seperated; 102 | typedef unsigned short unsigned_type; 103 | typedef short signed_type; 104 | }; 105 | 106 | template<> 107 | class zorder_traits 108 | { 109 | public: 110 | static void check_type(){}; 111 | typedef zorder_f is_signed; 112 | typedef zorder_t is_integral; 113 | typedef zorder_f is_seperated; 114 | typedef unsigned short unsigned_type; 115 | typedef unsigned short signed_type; 116 | }; 117 | 118 | template<> 119 | class zorder_traits 120 | { 121 | public: 122 | static void check_type(){}; 123 | typedef zorder_t is_signed; 124 | typedef zorder_t is_integral; 125 | typedef zorder_f is_seperated; 126 | typedef long unsigned int unsigned_type; 127 | typedef long int signed_type; 128 | }; 129 | 130 | template<> 131 | class zorder_traits 132 | { 133 | public: 134 | static void check_type(){}; 135 | typedef zorder_f is_signed; 136 | typedef zorder_t is_integral; 137 | typedef zorder_f is_seperated; 138 | typedef long unsigned int unsigned_type; 139 | typedef long unsigned int signed_type; 140 | }; 141 | 142 | template<> 143 | class zorder_traits 144 | { 145 | public: 146 | static void check_type(){}; 147 | typedef zorder_t is_signed; 148 | typedef zorder_f is_integral; 149 | typedef zorder_f is_seperated; 150 | typedef float unsigned_type; 151 | typedef float signed_type; 152 | }; 153 | 154 | template<> 155 | class zorder_traits 156 | { 157 | public: 158 | static void check_type(){}; 159 | typedef zorder_t is_signed; 160 | typedef zorder_f is_integral; 161 | typedef zorder_f is_seperated; 162 | typedef double unsigned_type; 163 | typedef double signed_type; 164 | }; 165 | 166 | template<> 167 | class zorder_traits 168 | { 169 | public: 170 | static void check_type(){}; 171 | typedef zorder_t is_signed; 172 | typedef zorder_f is_integral; 173 | typedef zorder_f is_seperated; 174 | typedef long double unsigned_type; 175 | typedef long double signed_type; 176 | }; 177 | 178 | template<> 179 | class zorder_traits > 180 | { 181 | public: 182 | static void check_type(){}; 183 | typedef zorder_t is_signed; 184 | typedef zorder_f is_integral; 185 | typedef zorder_t is_seperated; 186 | }; 187 | 188 | template<> 189 | class zorder_traits > 190 | { 191 | public: 192 | static void check_type(){}; 193 | typedef zorder_t is_signed; 194 | typedef zorder_f is_integral; 195 | typedef zorder_t is_seperated; 196 | }; 197 | 198 | template<> 199 | class zorder_traits > 200 | { 201 | public: 202 | static void check_type(){}; 203 | typedef zorder_t is_signed; 204 | typedef zorder_f is_integral; 205 | typedef zorder_t is_seperated; 206 | }; 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /program/main/Makefile: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | # 3 | # The following 2 commands to compile pmvs2. 4 | # > make depend 5 | # > make 6 | # 7 | ###################################################################### 8 | CXX = g++ 9 | 10 | #Your INCLUDE path (e.g., -I/usr/include) 11 | YOUR_INCLUDE_PATH =-I/usr/local/include 12 | 13 | #Your metis directory (contains header files under graclus1.2/metisLib/) 14 | YOUR_INCLUDE_METIS_PATH = -I/home/jkevin/src/graclus1.2/metisLib 15 | 16 | #Your LDLIBRARY path (e.g., -L/usr/lib) 17 | YOUR_LDLIB_PATH = -L/usr/local/lib -L/home/jkevin/src/graclus1.2 18 | 19 | ###################################################################### 20 | CXXFLAGS_PMVS = -O2 -Wall -Wno-deprecated ${YOUR_INCLUDE_PATH} 21 | 22 | CXXFLAGS_CMVS = -O2 -Wall -Wno-deprecated -DNUMBITS=64 \ 23 | ${YOUR_INCLUDE_PATH} ${YOUR_INCLUDE_METIS_PATH} \ 24 | -fopenmp -DNUMBITS=64 ${OPENMP_FLAG} 25 | 26 | 27 | LDFLAGS_PMVS = ${YOUR_LDLIB_PATH} -lXext -lX11 -ljpeg -lm -lpthread \ 28 | -llapack -lgsl -lgslcblas -lOpenCL 29 | 30 | LDFLAGS_CMVS = ${YOUR_LDLIB_PATH} -lXext -lX11 -ljpeg -lm -lpthread \ 31 | -llapack -fopenmp -lmultilevel -lmetis -lm 32 | 33 | ###################################################################### 34 | BASE_IMAGE = camera.o image.o photo.o photoSetS.o 35 | BASE_PMVS = detectFeatures.o detector.o dog.o expand.o filter.o \ 36 | findMatch.o harris.o optim.o option.o patch.o patchOrganizerS.o \ 37 | point.o seed.o refineThread.o 38 | BASE_NUMERIC = mylapack.o 39 | BASE_CMVS = bundle.o graclus.o 40 | 41 | ###################################################################### 42 | all: pmvs2 cmvs genOption 43 | 44 | 45 | pmvs2: pmvs2.o ${BASE_IMAGE} ${BASE_PMVS} ${BASE_NUMERIC} 46 | ${CXX} ${LDFLAGS_PMVS} -o $@ $^ ${LDFLAGS_PMVS} 47 | 48 | cmvs: cmvs.o patch.o ${BASE_IMAGE} ${BASE_CMVS} 49 | ${CXX} ${LDFLAGS_CMVS} -o $@ $^ ${LDFLAGS_CMVS} 50 | 51 | genOption: genOption.cc 52 | ${CXX} -o $@ $^ 53 | 54 | 55 | pmvs2.o : pmvs2.cc 56 | $(CXX) -c $(CXXFLAGS_PMVS) $< 57 | 58 | cmvs.o: cmvs.cc 59 | $(CXX) -c $(CXXFLAGS_CMVS) $< 60 | 61 | %.o : ../base/pmvs/%.cc 62 | $(CXX) -c $(CXXFLAGS_PMVS) $< 63 | 64 | %.o : ../base/image/%.cc 65 | $(CXX) -c $(CXXFLAGS_PMVS) $< 66 | 67 | %.o : ../base/numeric/%.cc 68 | $(CXX) -c $(CXXFLAGS_PMVS) $< 69 | 70 | %.o : ../base/cmvs/%.cc 71 | $(CXX) -c $(CXXFLAGS_CMVS) $< 72 | 73 | ###################################################################### 74 | # general commands 75 | clean: 76 | /bin/rm -f core core.* *.o ${TARGET} 77 | 78 | install: 79 | mkdir -p /usr/share/pmvs-gpu 80 | cp ../base/pmvs/refinePatch.cl /usr/share/pmvs-gpu 81 | 82 | depend: 83 | rm -f Dependencies 84 | for SOURCEFILE in `ls *.cc ../base/*/*.cc ../base/*/*.c ../base/*/*.C ../base/*/*.f`; do \ 85 | echo $$SOURCEFILE; \ 86 | $(CXX) -MM $(CXXFLAGS) $$SOURCEFILE >> Dependencies; \ 87 | done 88 | 89 | -include Dependencies 90 | -------------------------------------------------------------------------------- /program/main/cmvs.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../base/cmvs/bundle.h" 5 | 6 | using namespace std; 7 | 8 | int main(int argc, char* argv[]) { 9 | if (argc < 2) { 10 | cerr << "Usage: " << argv[0] << " prefix maximage[=100] CPU[=4]" << endl 11 | << endl 12 | << "You should choose maximage based on the amount of memory in your machine." << endl 13 | << "CPU should be the number of (virtual) CPUs or cores in your machine." << endl 14 | << "If you want more control of the program, look into the comments inside program/main/cmvs.cc" << endl; 15 | exit (1); 16 | } 17 | 18 | int maximage = 100; 19 | if (3 <= argc) 20 | maximage = atoi(argv[2]); 21 | 22 | int CPU = 4; 23 | if (4 <= argc) 24 | CPU = atoi(argv[3]); 25 | 26 | //---------------------------------------------------------------------- 27 | // If you want more control of the program, you can also change the 28 | // following two parameters. 29 | // scoreRatioThreshold, and coverageThreshold correspond to 30 | // \\lambda and \\delta in our CVPR 2010 paper. 31 | // Please refer to the paper for their definitions. The following are 32 | // brief explanations. 33 | // 34 | // CMVS tries to make sure that multi-view stereo (MVS) 35 | // reconstruction accuracy will be more than a certain threshold at 36 | // Structure-from-Motion (SfM) points. scoreRatioThreshold is this 37 | // threshold on the reconstruction accuracy [0, 1.0]. CMVS makes 38 | // sure that the ratio of "satisfied" SfM points is more than 39 | // coverageThreshold [0 1.0]. 40 | // 41 | // Intuitively, increasing thsse parameters lead to more images and 42 | // clusters in the output. 43 | const float scoreRatioThreshold = 0.7f; 44 | const float coverageThreshold = 0.7f; 45 | 46 | 47 | const int iNumForScore = 4; 48 | const int pnumThreshold = 0; 49 | CMVS::Cbundle bundle; 50 | bundle.run(argv[1], maximage, iNumForScore, 51 | scoreRatioThreshold, coverageThreshold, 52 | pnumThreshold, CPU); 53 | } 54 | -------------------------------------------------------------------------------- /program/main/genOption.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | int main(int argc, char* argv[]) { 10 | if (argc < 2) { 11 | cerr << "Usage: " << argv[0] 12 | << " prefix level[=1] csize[=2] threshold[=0.7] wsize[=7]" 13 | << " minImageNum[=3] CPU[=8]" << endl 14 | << endl 15 | << "Parameters are for PMVS2 option files." << endl 16 | << "Please refer to the following URL for the definitions:" << endl 17 | << "http://grail.cs.washington.edu/software/pmvs/documentation.html" << endl; 18 | exit (1); 19 | } 20 | 21 | int level = 1; 22 | if (3 <= argc) 23 | level = atoi(argv[2]); 24 | 25 | int csize = 2; 26 | if (4 <= argc) 27 | csize = atoi(argv[3]); 28 | 29 | float threshold = 0.7; 30 | if (5 <= argc) 31 | threshold = atof(argv[4]); 32 | 33 | int wsize = 7; 34 | if (6 <= argc) 35 | wsize = atoi(argv[5]); 36 | 37 | int minImageNum = 3; 38 | if (7 <= argc) 39 | minImageNum = atoi(argv[6]); 40 | 41 | int CPU = 8; 42 | if (8 <= argc) 43 | CPU = atoi(argv[7]); 44 | 45 | const int setEdge = 0; 46 | const int useBound = 0; 47 | const int useVisData = 1; 48 | const int sequence = -1; 49 | 50 | ifstream ifstr; 51 | char ske[1024]; 52 | sprintf(ske, "%sske.dat", argv[1]); 53 | ifstr.open(ske); 54 | 55 | string header; 56 | int inum, cnum; 57 | ifstr >> header >> inum >> cnum; 58 | 59 | ofstream script; 60 | char pmvsfile[1024]; 61 | sprintf(pmvsfile, "%spmvs.sh", argv[1]); 62 | script.open(pmvsfile); 63 | 64 | for (int c = 0; c < cnum; ++c) { 65 | ofstream ofstr; 66 | char buffer[1024]; 67 | sprintf(buffer, "%soption-%04d", argv[1], c); 68 | ofstr.open(buffer); 69 | 70 | sprintf(buffer, "pmvs2 pmvs/ option-%04d", c); 71 | script << buffer << endl; 72 | 73 | ofstr << "# generated by genOption. mode 1. cluster: " << c << endl 74 | << "level " << level << endl 75 | << "csize " << csize << endl 76 | << "threshold " << threshold << endl 77 | << "wsize " << wsize << endl 78 | << "minImageNum " << minImageNum << endl 79 | << "CPU " << CPU << endl 80 | << "setEdge " << setEdge << endl 81 | << "useBound " << useBound << endl 82 | << "useVisData " << useVisData << endl 83 | << "sequence " << sequence << endl 84 | << "maxAngle 10" << endl 85 | << "quad 2.0" << endl; 86 | 87 | int timagenum, oimagenum; 88 | ifstr >> timagenum >> oimagenum; 89 | 90 | vector timages, oimages; 91 | timages.resize(timagenum); 92 | oimages.resize(oimagenum); 93 | for (int i = 0; i < timagenum; ++i) 94 | ifstr >> timages[i]; 95 | for (int i = 0; i < oimagenum; ++i) 96 | ifstr >> oimages[i]; 97 | 98 | ofstr << "timages " << timagenum << ' '; 99 | for (int i = 0; i < timagenum; ++i) 100 | ofstr << timages[i] << ' '; 101 | ofstr << endl; 102 | ofstr << "oimages " << oimagenum << ' '; 103 | for (int i = 0; i < oimagenum; ++i) 104 | ofstr << oimages[i] << ' '; 105 | ofstr << endl; 106 | ofstr.close(); 107 | } 108 | ifstr.close(); 109 | script << endl; 110 | script.close(); 111 | } 112 | -------------------------------------------------------------------------------- /program/main/pmvs2.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../base/pmvs/findMatch.h" 4 | #include "../base/pmvs/option.h" 5 | 6 | using namespace PMVS3; 7 | using namespace std; 8 | 9 | int main(int argc, char* argv[]) { 10 | if (argc < 3) { 11 | cerr << "Usage: " << argv[0] << " prefix option_file" << endl 12 | << endl 13 | << "--------------------------------------------------" << endl 14 | << "level 1 csize 2" << endl 15 | << "threshold 0.7 wsize 7" << endl 16 | << "minImageNum 3 CPU 4" << endl 17 | << "useVisData 0 sequence -1" << endl 18 | << "quad 2.5 maxAngle 10.0" << endl 19 | << "--------------------------------------------------" << endl 20 | << "2 ways to specify targetting images" << endl 21 | << "timages 5 1 3 5 7 9 (enumeration)" << endl 22 | << " -1 0 24 (range specification)" << endl 23 | << "--------------------------------------------------" << endl 24 | << "4 ways to specify other images" << endl 25 | << "oimages 5 0 2 4 6 8 (enumeration)" << endl 26 | << " -1 24 48 (range specification)" << endl; 27 | exit (1); 28 | } 29 | 30 | PMVS3::Soption option; 31 | option.init(argv[1], argv[2]); 32 | 33 | PMVS3::CfindMatch findMatch; 34 | findMatch.init(option); 35 | findMatch.run(); 36 | 37 | char buffer[1024]; 38 | sprintf(buffer, "%smodels/%s", argv[1], argv[2]); 39 | findMatch.write(buffer); 40 | } 41 | -------------------------------------------------------------------------------- /program/main/run0.sh: -------------------------------------------------------------------------------- 1 | ./matchp ../../data/hall/ option.txt 2 | -------------------------------------------------------------------------------- /program/main/run1.sh: -------------------------------------------------------------------------------- 1 | ./matchp ../../data/hall/ option.txt-0000 2 | ./matchp ../../data/hall/ option.txt-0001 3 | -------------------------------------------------------------------------------- /program/main/run2.sh: -------------------------------------------------------------------------------- 1 | ./matchp ../../data/hall/ option-highres.txt 2 | --------------------------------------------------------------------------------