parent
72b2d2e155
commit
2d2a6d1e02
@ -0,0 +1,56 @@
|
||||
## Introduction
|
||||
|
||||
This project is a generic framework for globally consistent alignment of images captured from approximately planar
|
||||
scenes via topology analysis. Specifically, it can resist the perspective distortion meanwhile preserving the local
|
||||
alignment accuracy. To guanrantee the alignment accuracy, global topological relations of images are searched firstly,
|
||||
and then a global optimization on alignment parameters are performed.
|
||||
|
||||
This C++ implemented algorithm is described in
|
||||
"[Globally Consistent Alignment for Planar Mosaicking via Topology Analysis](http://menghanxia.github.io/papers/2017_Planar_Alignment_pr.pdf)", Pattern Recognition (PR), Jan. 2017.
|
||||
Notice: This program is free for personal, non-profit and academic use.
|
||||
All right reserved to CVRS: http://cvrs.whu.edu.cn/.
|
||||
If you have any question, please contact: menghanxyz@gmail.com (Menghan Xia)
|
||||
|
||||
Here is an example for demonstration below (image topological graph and alignment result):
|
||||
|
||||
<img src="docs/demo.png" width="900px"/>
|
||||
|
||||
## Usage
|
||||
### Dependent Libarary [compulsory]:
|
||||
OpenCV 2.4.9 is recommended.
|
||||
|
||||
### 1. Project Configure:
|
||||
This procedure is developed on *Visual Studio 2010* under *Windows 8.1* system environment,
|
||||
where the source code is organized with CMakeLists. So, before opening it in Visual Studio,
|
||||
you need to configure the project with *CMake*.
|
||||
|
||||
### 2. Running and Test:
|
||||
2.1 Default folders in "*data*":
|
||||
- "*Images*" : put your source images in it.
|
||||
- "*Cache*" (optional) : used to store those intermediate results (feature points files, matching point files, topological matrix, etc) that
|
||||
are required by the final alignmnet optimization.
|
||||
|
||||
2.2 Running parameter settings:
|
||||
- Set your reference image for alignment: 【Variable '*refNo*'】 [line 16] in [main.cpp](./source/Src/Mosaic/main.cpp).
|
||||
e.g. refNo=-1 means that the program will automatically selects a reference via topological analysis.
|
||||
- Set whether your image set is sequential order or not: 【Variable '*isSeqData*'】 [line 38] in [main.cpp](./source/Src/Mosaic/main.cpp)
|
||||
- Set whether the image keypoints available in [*Cache*](./data/Cache): 【Variable '*loadKeyPts*'】 [line 39] in [main.cpp](./source/Src/Mosaic/main.cpp)
|
||||
- Set whether the inter-image overlap relations available in [*Cache*](./data/Cache): 【Variable '*loadTopology*'】 [line 40] in [main.cpp](./source/Src/Mosaic/main.cpp)
|
||||
|
||||
Besides, to use our preset working directory successfully, do not forget to UPDATE the path variable
|
||||
'*baseDir*' as **the absolute path** of your directory "*data*" in the source file [source/Src/Utils/util.h](./source/Src/Utils/util.h) [line 16]
|
||||
|
||||
So far, you can run the procedure and check the alignment/stitching results now.
|
||||
|
||||
## Citation
|
||||
If any part of our paper and code is helpful to your work, please generously cite with:
|
||||
```
|
||||
@article{DBLP:journals/pr/XiaYXLZ17,
|
||||
author = {Menghan Xia and Jian Yao and Renping Xie and Li Li and Wei Zhang},
|
||||
title = {Globally consistent alignment for planar mosaicking via topology analysis},
|
||||
journal = {Pattern Recognit.},
|
||||
volume = {66},
|
||||
pages = {239--252},
|
||||
year = {2017}
|
||||
}
|
||||
```
|
@ -0,0 +1,61 @@
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
||||
1500 1001
|
@ -0,0 +1 @@
|
||||
surf feature points
|
@ -0,0 +1,2 @@
|
||||
matched surf features
|
||||
x1 y1 x2 y2
|
@ -0,0 +1,61 @@
|
||||
0 710 373 73 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 38 60 83 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
710 0 961 267 59 17 0 0 0 0 0 0 0 0 0 0 0 0 0 15 25 64 69 54 46 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
373 961 0 537 138 38 0 0 0 0 0 0 0 0 0 0 0 0 0 25 50 66 67 72 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
73 267 537 0 487 102 28 0 0 0 0 0 0 0 0 0 12 0 23 53 45 57 45 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
22 59 138 487 0 526 177 51 28 0 0 0 0 0 0 0 13 19 29 48 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 17 38 102 526 0 706 187 92 37 0 0 0 0 0 16 19 33 48 52 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 28 177 706 0 576 190 68 0 0 0 0 14 23 30 29 37 33 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 51 187 576 0 787 157 54 25 19 28 25 33 22 41 43 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 28 92 190 787 0 754 143 48 22 29 27 30 20 23 32 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 37 68 157 754 0 711 134 39 33 38 36 16 12 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 54 143 711 0 759 43 36 28 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 25 48 134 759 0 32 34 36 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 19 22 39 43 32 0 1178 364 189 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 35 67 83 85 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 28 29 33 36 34 1178 0 903 389 90 48 15 0 0 0 0 0 0 0 0 0 0 0 0 22 58 91 101 98 74 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 14 25 27 38 28 36 364 903 0 1152 305 94 59 10 0 0 0 0 0 0 0 0 0 0 0 30 77 111 101 95 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 16 23 33 30 36 31 35 189 389 1152 0 668 296 116 45 0 0 0 0 0 0 0 0 0 0 0 57 109 154 108 103 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 12 13 19 30 22 20 16 0 0 48 90 305 668 0 825 275 110 31 0 0 0 0 0 0 0 0 12 14 43 63 60 47 42 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 19 33 29 41 23 12 0 0 0 48 94 296 825 0 975 298 81 0 0 0 0 0 0 12 13 15 20 63 51 49 26 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 23 29 48 37 43 32 14 0 0 0 15 59 116 275 975 0 1018 232 44 0 0 0 0 19 18 26 39 44 51 54 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 15 25 53 48 52 33 15 10 0 0 0 0 0 10 45 110 298 1018 0 742 131 57 0 0 0 31 29 30 37 47 37 26 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 25 50 45 25 20 18 0 0 0 0 0 0 0 0 0 31 81 232 742 0 813 304 137 0 25 53 40 42 37 37 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
38 64 66 57 0 0 0 0 0 0 0 0 0 0 0 0 0 0 44 131 813 0 712 225 116 42 53 55 31 19 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
60 69 67 45 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 57 304 712 0 745 273 51 69 53 29 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
83 54 72 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 137 225 745 0 1118 50 58 52 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
52 46 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 116 273 1118 0 32 27 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 25 42 51 50 32 0 713 262 48 16 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 46 57 49 16 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 19 31 53 53 69 58 27 713 0 707 142 59 30 0 0 0 0 0 0 0 0 0 0 0 0 0 11 17 31 36 25 28 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 18 29 40 55 53 52 16 262 707 0 692 171 80 30 12 0 0 0 0 0 0 0 0 0 0 13 16 27 31 22 30 23 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 26 30 42 31 29 23 0 48 142 692 0 859 209 92 40 0 0 0 0 0 0 0 0 0 20 17 31 31 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 15 39 37 37 19 16 0 0 16 59 171 859 0 676 219 59 15 0 0 0 0 0 0 0 13 26 26 39 33 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 20 44 47 37 23 0 0 0 18 30 80 209 676 0 714 156 65 0 0 0 0 0 0 16 26 37 32 40 29 18 10 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 22 30 57 43 63 51 37 18 0 0 0 0 0 0 30 92 219 714 0 959 262 70 26 0 0 0 0 29 38 45 41 29 29 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 35 58 77 109 63 51 54 26 0 0 0 0 0 0 0 12 40 59 156 959 0 965 242 118 41 10 10 21 53 36 25 24 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 67 91 111 154 60 49 44 14 0 0 0 0 0 0 0 0 0 15 65 262 965 0 729 300 147 0 22 27 49 46 32 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 83 101 101 108 47 26 0 0 0 0 0 0 0 0 0 0 0 0 0 70 242 729 0 867 244 0 0 0 21 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 85 98 95 103 42 10 0 0 0 0 0 0 0 0 0 0 0 0 0 26 118 300 867 0 714 14 0 17 13 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 68 74 70 83 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 147 244 714 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 0 0 14 17 0 941 269 57 29 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 24 31
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 22 0 0 0 941 0 1061 194 72 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 27 39 40
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 27 0 17 0 269 1061 0 632 161 116 15 0 0 0 0 0 0 0 0 0 0 0 0 17 24 32 38 33
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 29 53 49 21 13 0 57 194 632 0 951 285 79 16 0 0 0 0 0 0 0 0 0 0 14 26 44 38 41 16
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 26 38 36 46 25 10 0 29 72 161 951 0 890 156 36 24 0 0 0 0 0 0 0 0 0 15 34 38 32 30 12
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 26 37 45 25 32 0 0 0 23 32 116 285 890 0 669 163 82 15 0 0 0 0 0 0 17 10 13 31 34 28 18 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 17 26 32 41 24 13 0 0 0 0 0 15 79 156 669 0 772 186 48 0 0 0 0 0 13 24 27 25 13 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 16 31 39 40 29 17 0 0 0 0 0 0 0 16 36 163 772 0 707 194 35 0 0 0 12 13 33 29 15 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 27 31 33 29 29 0 0 0 0 0 0 0 0 0 24 82 186 707 0 700 147 54 0 21 22 19 22 25 11 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 31 31 23 14 18 11 0 0 0 0 0 0 0 0 0 0 15 48 194 700 0 786 263 106 28 34 41 26 12 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 46 36 22 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 35 147 786 0 1069 454 42 53 44 18 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 57 25 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 54 263 1069 0 1211 47 46 30 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 28 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 106 454 1211 0 49 29 13 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 28 42 47 49 0 1075 252 105 11 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 22 34 53 46 29 1075 0 1094 248 41 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 13 19 41 44 30 13 252 1094 0 706 109 30 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 24 33 22 26 18 0 0 105 248 706 0 654 114 82 19 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 27 29 25 12 0 0 0 11 41 109 654 0 659 266 91 14 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 15 13 25 15 11 0 0 0 0 0 0 30 114 659 0 934 271 71 12 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 26 34 31 13 0 0 0 0 0 0 0 0 0 82 266 934 0 1013 225 61 18
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 15 24 44 38 34 0 0 0 0 0 0 0 0 0 0 19 91 271 1013 0 866 232 54
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 27 32 38 32 28 0 0 0 0 0 0 0 0 0 0 0 14 71 225 866 0 699 234
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 39 38 41 30 18 0 0 0 0 0 0 0 0 0 0 0 0 12 61 232 699 0 978
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 31 40 33 16 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 54 234 978 0
|
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 26 MiB |
@ -0,0 +1,89 @@
|
||||
PROJECT(AutoMosaic)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
|
||||
|
||||
SET(CMAKE_COLOR_MAKEFILE ON)
|
||||
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# Allow advanced users to generate Makefiles printing detailed commands
|
||||
MARK_AS_ADVANCED(CMAKE_VERBOSE_MAKEFILE)
|
||||
|
||||
# Path to additional CMake modules
|
||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules ${CMAKE_MODULE_PATH})
|
||||
SET(CMAKE_DEBUG_POSTFIX "d")
|
||||
|
||||
#large address aware option setting
|
||||
IF(${MINGW})
|
||||
SET(LARGEADDRESSAWARE "--large-address-aware")
|
||||
ELSE(${MINGW})
|
||||
IF (WIN32)
|
||||
SET(LARGEADDRESSAWARE "/LARGEADDRESSAWARE")
|
||||
ELSE (WIN32)
|
||||
SET(LARGEADDRESSAWARE " ")
|
||||
ENDIF (WIN32)
|
||||
ENDIF (${MINGW})
|
||||
|
||||
IF (WIN32)
|
||||
SET(APP_OPT "WIN32")
|
||||
ELSE (WIN32)
|
||||
IF (APPLE)
|
||||
#SET(APP_OPT "MACOSX_BUNDLE")
|
||||
SET(APP_OPT "EXCLUDE_FROM_ALL")
|
||||
ELSE (APPLE)
|
||||
SET(APP_OPT " ")
|
||||
ENDIF (APPLE)
|
||||
ENDIF (WIN32)
|
||||
|
||||
# OpenMP
|
||||
FIND_PACKAGE(OpenMP)
|
||||
IF(OPENMP_FOUND)
|
||||
OPTION(WITH_OPENMP "Whether to use parallel processing capabilities of OPENMP. ON/OFF" ON)
|
||||
ENDIF(OPENMP_FOUND)
|
||||
|
||||
IF(OPENMP_FOUND AND WITH_OPENMP)
|
||||
MESSAGE(STATUS "With OpenMP ")
|
||||
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAX_OPENMP_NUM_THREADS=${PROCESSOR_COUNT} -DOPENMP_NUM_THREADS=${PROCESSOR_COUNT} ${OpenMP_CXX_FLAGS} -DOPENMP")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMAX_OPENMP_NUM_THREADS=${PROCESSOR_COUNT} -DOPENMP_NUM_THREADS=${PROCESSOR_COUNT} ${OpenMP_CXX_FLAGS} ${OpenMP_C_FLAGS} -DOPENMP")
|
||||
ELSE(OPENMP_FOUND AND WITH_OPENMP)
|
||||
MESSAGE(STATUS "Without OpenMP")
|
||||
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAX_OPENMP_NUM_THREADS=1 -DOPENMP_NUM_THREADS=1")
|
||||
SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMAX_OPENMP_NUM_THREADS=1 -DOPENMP_NUM_THREADS=1")
|
||||
ENDIF(OPENMP_FOUND AND WITH_OPENMP)
|
||||
|
||||
# OpenCV
|
||||
FIND_PACKAGE(OpenCV REQUIRED)
|
||||
|
||||
# Boost
|
||||
#SET(Boost_USE_STATIC_LIBS OFF)
|
||||
#SET(Boost_USE_MULTITHREAD ON)
|
||||
#FIND_PACKAGE(Boost REQUIRED COMPONENTS filesystem thread)
|
||||
#MESSAGE(STATUS "Boost_LIBS: ${Boost_LIBRARIES}")
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Src)
|
||||
|
||||
# include header files of libs
|
||||
INCLUDE_DIRECTORIES(${OPENCV_INCLUDE_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/GeneralLibs/LM2.5/include)
|
||||
#INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
|
||||
|
||||
# link libs
|
||||
LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
|
||||
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/bin)
|
||||
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/GeneralLibs/LM2.5/x64libs)
|
||||
|
||||
# Setup output directories
|
||||
SET(LIBRARY_OUTPUT_PATH
|
||||
${PROJECT_BINARY_DIR}/bin
|
||||
CACHE
|
||||
PATH
|
||||
"Single directory for all libraries")
|
||||
|
||||
SET(EXECUTABLE_OUTPUT_PATH
|
||||
${PROJECT_BINARY_DIR}/bin
|
||||
CACHE
|
||||
PATH
|
||||
"Single directory for all executables")
|
||||
|
||||
ADD_SUBDIRECTORY(Src)
|
||||
#ADD_SUBDIRECTORY(GeneralLibs)
|
@ -0,0 +1,160 @@
|
||||
/* CLAPACK 3.0 BLAS wrapper macros
|
||||
* Feb 5, 2000
|
||||
*/
|
||||
|
||||
#ifndef __BLASWRAP_H
|
||||
#define __BLASWRAP_H
|
||||
|
||||
#ifndef NO_BLAS_WRAP
|
||||
|
||||
/* BLAS1 routines */
|
||||
#define srotg_ f2c_srotg
|
||||
#define drotg_ f2c_drotg
|
||||
#define srotmg_ f2c_srotmg
|
||||
#define drotmg_ f2c_drotmg
|
||||
#define srot_ f2c_srot
|
||||
#define drot_ f2c_drot
|
||||
#define srotm_ f2c_srotm
|
||||
#define drotm_ f2c_drotm
|
||||
#define csrot_ f2c_csrot
|
||||
#define zdrot_ f2c_zdrot
|
||||
#define sswap_ f2c_sswap
|
||||
#define dswap_ f2c_dswap
|
||||
#define cswap_ f2c_cswap
|
||||
#define zswap_ f2c_zswap
|
||||
#define sscal_ f2c_sscal
|
||||
#define dscal_ f2c_dscal
|
||||
#define cscal_ f2c_cscal
|
||||
#define zscal_ f2c_zscal
|
||||
#define csscal_ f2c_csscal
|
||||
#define zdscal_ f2c_zdscal
|
||||
#define scopy_ f2c_scopy
|
||||
#define dcopy_ f2c_dcopy
|
||||
#define ccopy_ f2c_ccopy
|
||||
#define zcopy_ f2c_zcopy
|
||||
#define saxpy_ f2c_saxpy
|
||||
#define daxpy_ f2c_daxpy
|
||||
#define caxpy_ f2c_caxpy
|
||||
#define zaxpy_ f2c_zaxpy
|
||||
#define sdot_ f2c_sdot
|
||||
#define ddot_ f2c_ddot
|
||||
#define cdotu_ f2c_cdotu
|
||||
#define zdotu_ f2c_zdotu
|
||||
#define cdotc_ f2c_cdotc
|
||||
#define zdotc_ f2c_zdotc
|
||||
#define snrm2_ f2c_snrm2
|
||||
#define dnrm2_ f2c_dnrm2
|
||||
#define scnrm2_ f2c_scnrm2
|
||||
#define dznrm2_ f2c_dznrm2
|
||||
#define sasum_ f2c_sasum
|
||||
#define dasum_ f2c_dasum
|
||||
#define scasum_ f2c_scasum
|
||||
#define dzasum_ f2c_dzasum
|
||||
#define isamax_ f2c_isamax
|
||||
#define idamax_ f2c_idamax
|
||||
#define icamax_ f2c_icamax
|
||||
#define izamax_ f2c_izamax
|
||||
|
||||
/* BLAS2 routines */
|
||||
#define sgemv_ f2c_sgemv
|
||||
#define dgemv_ f2c_dgemv
|
||||
#define cgemv_ f2c_cgemv
|
||||
#define zgemv_ f2c_zgemv
|
||||
#define sgbmv_ f2c_sgbmv
|
||||
#define dgbmv_ f2c_dgbmv
|
||||
#define cgbmv_ f2c_cgbmv
|
||||
#define zgbmv_ f2c_zgbmv
|
||||
#define chemv_ f2c_chemv
|
||||
#define zhemv_ f2c_zhemv
|
||||
#define chbmv_ f2c_chbmv
|
||||
#define zhbmv_ f2c_zhbmv
|
||||
#define chpmv_ f2c_chpmv
|
||||
#define zhpmv_ f2c_zhpmv
|
||||
#define ssymv_ f2c_ssymv
|
||||
#define dsymv_ f2c_dsymv
|
||||
#define ssbmv_ f2c_ssbmv
|
||||
#define dsbmv_ f2c_dsbmv
|
||||
#define sspmv_ f2c_sspmv
|
||||
#define dspmv_ f2c_dspmv
|
||||
#define strmv_ f2c_strmv
|
||||
#define dtrmv_ f2c_dtrmv
|
||||
#define ctrmv_ f2c_ctrmv
|
||||
#define ztrmv_ f2c_ztrmv
|
||||
#define stbmv_ f2c_stbmv
|
||||
#define dtbmv_ f2c_dtbmv
|
||||
#define ctbmv_ f2c_ctbmv
|
||||
#define ztbmv_ f2c_ztbmv
|
||||
#define stpmv_ f2c_stpmv
|
||||
#define dtpmv_ f2c_dtpmv
|
||||
#define ctpmv_ f2c_ctpmv
|
||||
#define ztpmv_ f2c_ztpmv
|
||||
#define strsv_ f2c_strsv
|
||||
#define dtrsv_ f2c_dtrsv
|
||||
#define ctrsv_ f2c_ctrsv
|
||||
#define ztrsv_ f2c_ztrsv
|
||||
#define stbsv_ f2c_stbsv
|
||||
#define dtbsv_ f2c_dtbsv
|
||||
#define ctbsv_ f2c_ctbsv
|
||||
#define ztbsv_ f2c_ztbsv
|
||||
#define stpsv_ f2c_stpsv
|
||||
#define dtpsv_ f2c_dtpsv
|
||||
#define ctpsv_ f2c_ctpsv
|
||||
#define ztpsv_ f2c_ztpsv
|
||||
#define sger_ f2c_sger
|
||||
#define dger_ f2c_dger
|
||||
#define cgeru_ f2c_cgeru
|
||||
#define zgeru_ f2c_zgeru
|
||||
#define cgerc_ f2c_cgerc
|
||||
#define zgerc_ f2c_zgerc
|
||||
#define cher_ f2c_cher
|
||||
#define zher_ f2c_zher
|
||||
#define chpr_ f2c_chpr
|
||||
#define zhpr_ f2c_zhpr
|
||||
#define cher2_ f2c_cher2
|
||||
#define zher2_ f2c_zher2
|
||||
#define chpr2_ f2c_chpr2
|
||||
#define zhpr2_ f2c_zhpr2
|
||||
#define ssyr_ f2c_ssyr
|
||||
#define dsyr_ f2c_dsyr
|
||||
#define sspr_ f2c_sspr
|
||||
#define dspr_ f2c_dspr
|
||||
#define ssyr2_ f2c_ssyr2
|
||||
#define dsyr2_ f2c_dsyr2
|
||||
#define sspr2_ f2c_sspr2
|
||||
#define dspr2_ f2c_dspr2
|
||||
|
||||
/* BLAS3 routines */
|
||||
#define sgemm_ f2c_sgemm
|
||||
#define dgemm_ f2c_dgemm
|
||||
#define cgemm_ f2c_cgemm
|
||||
#define zgemm_ f2c_zgemm
|
||||
#define ssymm_ f2c_ssymm
|
||||
#define dsymm_ f2c_dsymm
|
||||
#define csymm_ f2c_csymm
|
||||
#define zsymm_ f2c_zsymm
|
||||
#define chemm_ f2c_chemm
|
||||
#define zhemm_ f2c_zhemm
|
||||
#define ssyrk_ f2c_ssyrk
|
||||
#define dsyrk_ f2c_dsyrk
|
||||
#define csyrk_ f2c_csyrk
|
||||
#define zsyrk_ f2c_zsyrk
|
||||
#define cherk_ f2c_cherk
|
||||
#define zherk_ f2c_zherk
|
||||
#define ssyr2k_ f2c_ssyr2k
|
||||
#define dsyr2k_ f2c_dsyr2k
|
||||
#define csyr2k_ f2c_csyr2k
|
||||
#define zsyr2k_ f2c_zsyr2k
|
||||
#define cher2k_ f2c_cher2k
|
||||
#define zher2k_ f2c_zher2k
|
||||
#define strmm_ f2c_strmm
|
||||
#define dtrmm_ f2c_dtrmm
|
||||
#define ctrmm_ f2c_ctrmm
|
||||
#define ztrmm_ f2c_ztrmm
|
||||
#define strsm_ f2c_strsm
|
||||
#define dtrsm_ f2c_dtrsm
|
||||
#define ctrsm_ f2c_ctrsm
|
||||
#define ztrsm_ f2c_ztrsm
|
||||
|
||||
#endif /* NO_BLAS_WRAP */
|
||||
|
||||
#endif /* __BLASWRAP_H */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,45 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Levenberg - Marquardt non-linear minimization algorithm
|
||||
// Copyright (C) 2004 Manolis Lourakis (lourakis at ics forth gr)
|
||||
// Institute of Computer Science, Foundation for Research & Technology - Hellas
|
||||
// Heraklion, Crete, Greece.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _COMPILER_H_
|
||||
#define _COMPILER_H_
|
||||
|
||||
/* note: intel's icc defines both __ICC & __INTEL_COMPILER.
|
||||
* Also, some compilers other than gcc define __GNUC__,
|
||||
* therefore gcc should be checked last
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline // MSVC
|
||||
#elif !defined(__ICC) && !defined(__INTEL_COMPILER) && !defined(__GNUC__)
|
||||
#define inline // other than MSVC, ICC, GCC: define empty
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define LM_FINITE _finite // MSVC
|
||||
#elif defined(__ICC) || defined(__INTEL_COMPILER) || defined(__GNUC__)
|
||||
#define LM_FINITE finite // ICC, GCC
|
||||
#else
|
||||
#define LM_FINITE finite // other than MSVC, ICC, GCC, let's hope this will work
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER // avoid deprecation warnings in VS2005
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#endif /* _COMPILER_H_ */
|
@ -0,0 +1,223 @@
|
||||
/* f2c.h -- Standard Fortran to C header file */
|
||||
|
||||
/** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
|
||||
|
||||
- From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */
|
||||
|
||||
#ifndef F2C_INCLUDE
|
||||
#define F2C_INCLUDE
|
||||
|
||||
typedef long int integer;
|
||||
typedef unsigned long int uinteger;
|
||||
typedef char *address;
|
||||
typedef short int shortint;
|
||||
typedef float real;
|
||||
typedef double doublereal;
|
||||
typedef struct { real r, i; } complex;
|
||||
typedef struct { doublereal r, i; } doublecomplex;
|
||||
typedef long int logical;
|
||||
typedef short int shortlogical;
|
||||
typedef char logical1;
|
||||
typedef char integer1;
|
||||
#ifdef INTEGER_STAR_8 /* Adjust for integer*8. */
|
||||
typedef long long longint; /* system-dependent */
|
||||
typedef unsigned long long ulongint; /* system-dependent */
|
||||
#define qbit_clear(a,b) ((a) & ~((ulongint)1 << (b)))
|
||||
#define qbit_set(a,b) ((a) | ((ulongint)1 << (b)))
|
||||
#endif
|
||||
|
||||
#define TRUE_ (1)
|
||||
#define FALSE_ (0)
|
||||
|
||||
/* Extern is for use with -E */
|
||||
#ifndef Extern
|
||||
#define Extern extern
|
||||
#endif
|
||||
|
||||
/* I/O stuff */
|
||||
|
||||
#ifdef f2c_i2
|
||||
/* for -i2 */
|
||||
typedef short flag;
|
||||
typedef short ftnlen;
|
||||
typedef short ftnint;
|
||||
#else
|
||||
typedef long int flag;
|
||||
typedef long int ftnlen;
|
||||
typedef long int ftnint;
|
||||
#endif
|
||||
|
||||
/*external read, write*/
|
||||
typedef struct
|
||||
{ flag cierr;
|
||||
ftnint ciunit;
|
||||
flag ciend;
|
||||
char *cifmt;
|
||||
ftnint cirec;
|
||||
} cilist;
|
||||
|
||||
/*internal read, write*/
|
||||
typedef struct
|
||||
{ flag icierr;
|
||||
char *iciunit;
|
||||
flag iciend;
|
||||
char *icifmt;
|
||||
ftnint icirlen;
|
||||
ftnint icirnum;
|
||||
} icilist;
|
||||
|
||||
/*open*/
|
||||
typedef struct
|
||||
{ flag oerr;
|
||||
ftnint ounit;
|
||||
char *ofnm;
|
||||
ftnlen ofnmlen;
|
||||
char *osta;
|
||||
char *oacc;
|
||||
char *ofm;
|
||||
ftnint orl;
|
||||
char *oblnk;
|
||||
} olist;
|
||||
|
||||
/*close*/
|
||||
typedef struct
|
||||
{ flag cerr;
|
||||
ftnint cunit;
|
||||
char *csta;
|
||||
} cllist;
|
||||
|
||||
/*rewind, backspace, endfile*/
|
||||
typedef struct
|
||||
{ flag aerr;
|
||||
ftnint aunit;
|
||||
} alist;
|
||||
|
||||
/* inquire */
|
||||
typedef struct
|
||||
{ flag inerr;
|
||||
ftnint inunit;
|
||||
char *infile;
|
||||
ftnlen infilen;
|
||||
ftnint *inex; /*parameters in standard's order*/
|
||||
ftnint *inopen;
|
||||
ftnint *innum;
|
||||
ftnint *innamed;
|
||||
char *inname;
|
||||
ftnlen innamlen;
|
||||
char *inacc;
|
||||
ftnlen inacclen;
|
||||
char *inseq;
|
||||
ftnlen inseqlen;
|
||||
char *indir;
|
||||
ftnlen indirlen;
|
||||
char *infmt;
|
||||
ftnlen infmtlen;
|
||||
char *inform;
|
||||
ftnint informlen;
|
||||
char *inunf;
|
||||
ftnlen inunflen;
|
||||
ftnint *inrecl;
|
||||
ftnint *innrec;
|
||||
char *inblank;
|
||||
ftnlen inblanklen;
|
||||
} inlist;
|
||||
|
||||
#define VOID void
|
||||
|
||||
union Multitype { /* for multiple entry points */
|
||||
integer1 g;
|
||||
shortint h;
|
||||
integer i;
|
||||
/* longint j; */
|
||||
real r;
|
||||
doublereal d;
|
||||
complex c;
|
||||
doublecomplex z;
|
||||
};
|
||||
|
||||
typedef union Multitype Multitype;
|
||||
|
||||
/*typedef long int Long;*/ /* No longer used; formerly in Namelist */
|
||||
|
||||
struct Vardesc { /* for Namelist */
|
||||
char *name;
|
||||
char *addr;
|
||||
ftnlen *dims;
|
||||
int type;
|
||||
};
|
||||
typedef struct Vardesc Vardesc;
|
||||
|
||||
struct Namelist {
|
||||
char *name;
|
||||
Vardesc **vars;
|
||||
int nvars;
|
||||
};
|
||||
typedef struct Namelist Namelist;
|
||||
|
||||
#define abs(x) ((x) >= 0 ? (x) : -(x))
|
||||
#define dabs(x) (doublereal)abs(x)
|
||||
#define min(a,b) ((a) <= (b) ? (a) : (b))
|
||||
#define max(a,b) ((a) >= (b) ? (a) : (b))
|
||||
#define dmin(a,b) (doublereal)min(a,b)
|
||||
#define dmax(a,b) (doublereal)max(a,b)
|
||||
#define bit_test(a,b) ((a) >> (b) & 1)
|
||||
#define bit_clear(a,b) ((a) & ~((uinteger)1 << (b)))
|
||||
#define bit_set(a,b) ((a) | ((uinteger)1 << (b)))
|
||||
|
||||
/* procedure parameter types for -A and -C++ */
|
||||
|
||||
#define F2C_proc_par_types 1
|
||||
#ifdef __cplusplus
|
||||
typedef int /* Unknown procedure type */ (*U_fp)(...);
|
||||
typedef shortint (*J_fp)(...);
|
||||
typedef integer (*I_fp)(...);
|
||||
typedef real (*R_fp)(...);
|
||||
typedef doublereal (*D_fp)(...), (*E_fp)(...);
|
||||
typedef /* Complex */ VOID (*C_fp)(...);
|
||||
typedef /* Double Complex */ VOID (*Z_fp)(...);
|
||||
typedef logical (*L_fp)(...);
|
||||
typedef shortlogical (*K_fp)(...);
|
||||
typedef /* Character */ VOID (*H_fp)(...);
|
||||
typedef /* Subroutine */ int (*S_fp)(...);
|
||||
#else
|
||||
typedef int /* Unknown procedure type */ (*U_fp)();
|
||||
typedef shortint (*J_fp)();
|
||||
typedef integer (*I_fp)();
|
||||
typedef real (*R_fp)();
|
||||
typedef doublereal (*D_fp)(), (*E_fp)();
|
||||
typedef /* Complex */ VOID (*C_fp)();
|
||||
typedef /* Double Complex */ VOID (*Z_fp)();
|
||||
typedef logical (*L_fp)();
|
||||
typedef shortlogical (*K_fp)();
|
||||
typedef /* Character */ VOID (*H_fp)();
|
||||
typedef /* Subroutine */ int (*S_fp)();
|
||||
#endif
|
||||
/* E_fp is for real functions when -R is not specified */
|
||||
typedef VOID C_f; /* complex function */
|
||||
typedef VOID H_f; /* character function */
|
||||
typedef VOID Z_f; /* double complex function */
|
||||
typedef doublereal E_f; /* real function with -R not specified */
|
||||
|
||||
/* undef any lower-case symbols that your C compiler predefines, e.g.: */
|
||||
|
||||
#ifndef Skip_f2c_Undefs
|
||||
#undef cray
|
||||
#undef gcos
|
||||
#undef mc68010
|
||||
#undef mc68020
|
||||
#undef mips
|
||||
#undef pdp11
|
||||
#undef sgi
|
||||
#undef sparc
|
||||
#undef sun
|
||||
#undef sun2
|
||||
#undef sun3
|
||||
#undef sun4
|
||||
#undef u370
|
||||
#undef u3b
|
||||
#undef u3b2
|
||||
#undef u3b5
|
||||
#undef unix
|
||||
#undef vax
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,370 @@
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Prototypes and definitions for the Levenberg - Marquardt minimization algorithm
|
||||
// Copyright (C) 2004 Manolis Lourakis (lourakis at ics forth gr)
|
||||
// Institute of Computer Science, Foundation for Research & Technology - Hellas
|
||||
// Heraklion, Crete, Greece.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
#ifndef _LEVMAR_H_
|
||||
#define _LEVMAR_H_
|
||||
|
||||
|
||||
/************************************* Start of configuration options *************************************/
|
||||
|
||||
/* specify whether to use LAPACK or not. The first option is strongly recommended */
|
||||
#define HAVE_LAPACK /* use LAPACK */
|
||||
/* #undef HAVE_LAPACK */ /* uncomment this to force not using LAPACK */
|
||||
|
||||
/* to avoid the overhead of repeated mallocs(), routines in Axb.c can be instructed to
|
||||
* retain working memory between calls. Such a choice, however, renders these routines
|
||||
* non-reentrant and is not safe in a shared memory multiprocessing environment.
|
||||
* Bellow, this option is turned on only when not compiling with OpenMP.
|
||||
*/
|
||||
#if !defined(_OPENMP)
|
||||
#define LINSOLVERS_RETAIN_MEMORY /* comment this if you don't want routines in Axb.c retain working memory between calls */
|
||||
#endif
|
||||
|
||||
/* determine the precision variants to be build. Default settings build
|
||||
* both the single and double precision routines
|
||||
*/
|
||||
#define LM_DBL_PREC /* comment this if you don't want the double precision routines to be compiled */
|
||||
#define LM_SNGL_PREC /* comment this if you don't want the single precision routines to be compiled */
|
||||
|
||||
/****************** End of configuration options, no changes necessary beyond this point ******************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define FABS(x) (((x)>=0.0)? (x) : -(x))
|
||||
|
||||
/* work arrays size for ?levmar_der and ?levmar_dif functions.
|
||||
* should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
|
||||
*/
|
||||
#define LM_DER_WORKSZ(npar, nmeas) (2*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar))
|
||||
#define LM_DIF_WORKSZ(npar, nmeas) (4*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar))
|
||||
|
||||
/* work arrays size for ?levmar_bc_der and ?levmar_bc_dif functions.
|
||||
* should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
|
||||
*/
|
||||
#define LM_BC_DER_WORKSZ(npar, nmeas) (2*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar))
|
||||
#define LM_BC_DIF_WORKSZ(npar, nmeas) LM_BC_DER_WORKSZ((npar), (nmeas)) /* LEVMAR_BC_DIF currently implemented using LEVMAR_BC_DER()! */
|
||||
|
||||
/* work arrays size for ?levmar_lec_der and ?levmar_lec_dif functions.
|
||||
* should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
|
||||
*/
|
||||
#define LM_LEC_DER_WORKSZ(npar, nmeas, nconstr) LM_DER_WORKSZ((npar)-(nconstr), (nmeas))
|
||||
#define LM_LEC_DIF_WORKSZ(npar, nmeas, nconstr) LM_DIF_WORKSZ((npar)-(nconstr), (nmeas))
|
||||
|
||||
/* work arrays size for ?levmar_blec_der and ?levmar_blec_dif functions.
|
||||
* should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
|
||||
*/
|
||||
#define LM_BLEC_DER_WORKSZ(npar, nmeas, nconstr) LM_LEC_DER_WORKSZ((npar), (nmeas)+(npar), (nconstr))
|
||||
#define LM_BLEC_DIF_WORKSZ(npar, nmeas, nconstr) LM_LEC_DIF_WORKSZ((npar), (nmeas)+(npar), (nconstr))
|
||||
|
||||
/* work arrays size for ?levmar_bleic_der and ?levmar_bleic_dif functions.
|
||||
* should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes
|
||||
*/
|
||||
#define LM_BLEIC_DER_WORKSZ(npar, nmeas, nconstr1, nconstr2) LM_BLEC_DER_WORKSZ((npar)+(nconstr2), (nmeas)+(nconstr2), (nconstr1)+(nconstr2))
|
||||
#define LM_BLEIC_DIF_WORKSZ(npar, nmeas, nconstr1, nconstr2) LM_BLEC_DIF_WORKSZ((npar)+(nconstr2), (nmeas)+(nconstr2), (nconstr1)+(nconstr2))
|
||||
|
||||
#define LM_OPTS_SZ 5 /* max(4, 5) */
|
||||
#define LM_INFO_SZ 10
|
||||
#define LM_ERROR -1
|
||||
#define LM_INIT_MU 1E-03
|
||||
#define LM_STOP_THRESH 1E-17
|
||||
#define LM_DIFF_DELTA 1E-06
|
||||
#define LM_VERSION "2.5 (December 2009)"
|
||||
|
||||
#ifdef LM_DBL_PREC
|
||||
/* double precision LM, with & without Jacobian */
|
||||
/* unconstrained minimization */
|
||||
extern int dlevmar_der(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, int itmax, double *opts,
|
||||
double *info, double *work, double *covar, void *adata);
|
||||
|
||||
extern int dlevmar_dif(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, int itmax, double *opts,
|
||||
double *info, double *work, double *covar, void *adata);
|
||||
|
||||
/* box-constrained minimization */
|
||||
extern int dlevmar_bc_der(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *lb, double *ub,
|
||||
int itmax, double *opts, double *info, double *work, double *covar, void *adata);
|
||||
|
||||
extern int dlevmar_bc_dif(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *lb, double *ub,
|
||||
int itmax, double *opts, double *info, double *work, double *covar, void *adata);
|
||||
|
||||
#ifdef HAVE_LAPACK
|
||||
/* linear equation constrained minimization */
|
||||
extern int dlevmar_lec_der(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *A, double *b, int k,
|
||||
int itmax, double *opts, double *info, double *work, double *covar, void *adata);
|
||||
|
||||
extern int dlevmar_lec_dif(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *A, double *b, int k,
|
||||
int itmax, double *opts, double *info, double *work, double *covar, void *adata);
|
||||
|
||||
/* box & linear equation constrained minimization */
|
||||
extern int dlevmar_blec_der(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k, double *wghts,
|
||||
int itmax, double *opts, double *info, double *work, double *covar, void *adata);
|
||||
|
||||
extern int dlevmar_blec_dif(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k, double *wghts,
|
||||
int itmax, double *opts, double *info, double *work, double *covar, void *adata);
|
||||
|
||||
/* box, linear equations & inequalities constrained minimization */
|
||||
extern int dlevmar_bleic_der(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *lb, double *ub,
|
||||
double *A, double *b, int k1, double *C, double *d, int k2,
|
||||
int itmax, double *opts, double *info, double *work, double *covar, void *adata);
|
||||
|
||||
extern int dlevmar_bleic_dif(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *lb, double *ub,
|
||||
double *A, double *b, int k1, double *C, double *d, int k2,
|
||||
int itmax, double *opts, double *info, double *work, double *covar, void *adata);
|
||||
|
||||
/* box & linear inequality constraints */
|
||||
extern int dlevmar_blic_der(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *lb, double *ub, double *C, double *d, int k2,
|
||||
int itmax, double opts[4], double info[LM_INFO_SZ], double *work, double *covar, void *adata);
|
||||
|
||||
extern int dlevmar_blic_dif(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *lb, double *ub, double *C, double *d, int k2,
|
||||
int itmax, double opts[5], double info[LM_INFO_SZ], double *work, double *covar, void *adata);
|
||||
|
||||
/* linear equation & inequality constraints */
|
||||
extern int dlevmar_leic_der(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *A, double *b, int k1, double *C, double *d, int k2,
|
||||
int itmax, double opts[4], double info[LM_INFO_SZ], double *work, double *covar, void *adata);
|
||||
|
||||
extern int dlevmar_leic_dif(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *A, double *b, int k1, double *C, double *d, int k2,
|
||||
int itmax, double opts[5], double info[LM_INFO_SZ], double *work, double *covar, void *adata);
|
||||
|
||||
/* linear inequality constraints */
|
||||
extern int dlevmar_lic_der(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *C, double *d, int k2,
|
||||
int itmax, double opts[4], double info[LM_INFO_SZ], double *work, double *covar, void *adata);
|
||||
|
||||
extern int dlevmar_lic_dif(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *x, int m, int n, double *C, double *d, int k2,
|
||||
int itmax, double opts[5], double info[LM_INFO_SZ], double *work, double *covar, void *adata);
|
||||
#endif /* HAVE_LAPACK */
|
||||
|
||||
#endif /* LM_DBL_PREC */
|
||||
|
||||
|
||||
#ifdef LM_SNGL_PREC
|
||||
/* single precision LM, with & without Jacobian */
|
||||
/* unconstrained minimization */
|
||||
extern int slevmar_der(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, int itmax, float *opts,
|
||||
float *info, float *work, float *covar, void *adata);
|
||||
|
||||
extern int slevmar_dif(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, int itmax, float *opts,
|
||||
float *info, float *work, float *covar, void *adata);
|
||||
|
||||
/* box-constrained minimization */
|
||||
extern int slevmar_bc_der(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *lb, float *ub,
|
||||
int itmax, float *opts, float *info, float *work, float *covar, void *adata);
|
||||
|
||||
extern int slevmar_bc_dif(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *lb, float *ub,
|
||||
int itmax, float *opts, float *info, float *work, float *covar, void *adata);
|
||||
|
||||
#ifdef HAVE_LAPACK
|
||||
/* linear equation constrained minimization */
|
||||
extern int slevmar_lec_der(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *A, float *b, int k,
|
||||
int itmax, float *opts, float *info, float *work, float *covar, void *adata);
|
||||
|
||||
extern int slevmar_lec_dif(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *A, float *b, int k,
|
||||
int itmax, float *opts, float *info, float *work, float *covar, void *adata);
|
||||
|
||||
/* box & linear equation constrained minimization */
|
||||
extern int slevmar_blec_der(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *lb, float *ub, float *A, float *b, int k, float *wghts,
|
||||
int itmax, float *opts, float *info, float *work, float *covar, void *adata);
|
||||
|
||||
extern int slevmar_blec_dif(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *lb, float *ub, float *A, float *b, int k, float *wghts,
|
||||
int itmax, float *opts, float *info, float *work, float *covar, void *adata);
|
||||
|
||||
/* box, linear equations & inequalities constrained minimization */
|
||||
extern int slevmar_bleic_der(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *lb, float *ub,
|
||||
float *A, float *b, int k1, float *C, float *d, int k2,
|
||||
int itmax, float *opts, float *info, float *work, float *covar, void *adata);
|
||||
|
||||
extern int slevmar_bleic_dif(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *lb, float *ub,
|
||||
float *A, float *b, int k1, float *C, float *d, int k2,
|
||||
int itmax, float *opts, float *info, float *work, float *covar, void *adata);
|
||||
|
||||
/* box & linear inequality constraints */
|
||||
extern int slevmar_blic_der(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *lb, float *ub, float *C, float *d, int k2,
|
||||
int itmax, float opts[4], float info[LM_INFO_SZ], float *work, float *covar, void *adata);
|
||||
|
||||
extern int slevmar_blic_dif(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *lb, float *ub, float *C, float *d, int k2,
|
||||
int itmax, float opts[5], float info[LM_INFO_SZ], float *work, float *covar, void *adata);
|
||||
|
||||
/* linear equality & inequality constraints */
|
||||
extern int slevmar_leic_der(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *A, float *b, int k1, float *C, float *d, int k2,
|
||||
int itmax, float opts[4], float info[LM_INFO_SZ], float *work, float *covar, void *adata);
|
||||
|
||||
extern int slevmar_leic_dif(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *A, float *b, int k1, float *C, float *d, int k2,
|
||||
int itmax, float opts[5], float info[LM_INFO_SZ], float *work, float *covar, void *adata);
|
||||
|
||||
/* linear inequality constraints */
|
||||
extern int slevmar_lic_der(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *C, float *d, int k2,
|
||||
int itmax, float opts[4], float info[LM_INFO_SZ], float *work, float *covar, void *adata);
|
||||
|
||||
extern int slevmar_lic_dif(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *x, int m, int n, float *C, float *d, int k2,
|
||||
int itmax, float opts[5], float info[LM_INFO_SZ], float *work, float *covar, void *adata);
|
||||
#endif /* HAVE_LAPACK */
|
||||
|
||||
#endif /* LM_SNGL_PREC */
|
||||
|
||||
/* linear system solvers */
|
||||
#ifdef HAVE_LAPACK
|
||||
|
||||
#ifdef LM_DBL_PREC
|
||||
extern int dAx_eq_b_QR(double *A, double *B, double *x, int m);
|
||||
extern int dAx_eq_b_QRLS(double *A, double *B, double *x, int m, int n);
|
||||
extern int dAx_eq_b_Chol(double *A, double *B, double *x, int m);
|
||||
extern int dAx_eq_b_LU(double *A, double *B, double *x, int m);
|
||||
extern int dAx_eq_b_SVD(double *A, double *B, double *x, int m);
|
||||
extern int dAx_eq_b_BK(double *A, double *B, double *x, int m);
|
||||
#endif /* LM_DBL_PREC */
|
||||
|
||||
#ifdef LM_SNGL_PREC
|
||||
extern int sAx_eq_b_QR(float *A, float *B, float *x, int m);
|
||||
extern int sAx_eq_b_QRLS(float *A, float *B, float *x, int m, int n);
|
||||
extern int sAx_eq_b_Chol(float *A, float *B, float *x, int m);
|
||||
extern int sAx_eq_b_LU(float *A, float *B, float *x, int m);
|
||||
extern int sAx_eq_b_SVD(float *A, float *B, float *x, int m);
|
||||
extern int sAx_eq_b_BK(float *A, float *B, float *x, int m);
|
||||
#endif /* LM_SNGL_PREC */
|
||||
|
||||
#else /* no LAPACK */
|
||||
|
||||
#ifdef LM_DBL_PREC
|
||||
extern int dAx_eq_b_LU_noLapack(double *A, double *B, double *x, int n);
|
||||
#endif /* LM_DBL_PREC */
|
||||
|
||||
#ifdef LM_SNGL_PREC
|
||||
extern int sAx_eq_b_LU_noLapack(float *A, float *B, float *x, int n);
|
||||
#endif /* LM_SNGL_PREC */
|
||||
|
||||
#endif /* HAVE_LAPACK */
|
||||
|
||||
/* Jacobian verification, double & single precision */
|
||||
#ifdef LM_DBL_PREC
|
||||
extern void dlevmar_chkjac(
|
||||
void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
void (*jacf)(double *p, double *j, int m, int n, void *adata),
|
||||
double *p, int m, int n, void *adata, double *err);
|
||||
#endif /* LM_DBL_PREC */
|
||||
|
||||
#ifdef LM_SNGL_PREC
|
||||
extern void slevmar_chkjac(
|
||||
void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
void (*jacf)(float *p, float *j, int m, int n, void *adata),
|
||||
float *p, int m, int n, void *adata, float *err);
|
||||
#endif /* LM_SNGL_PREC */
|
||||
|
||||
/* standard deviation, coefficient of determination (R2) & Pearson's correlation coefficient for best-fit parameters */
|
||||
#ifdef LM_DBL_PREC
|
||||
extern double dlevmar_stddev( double *covar, int m, int i);
|
||||
extern double dlevmar_corcoef(double *covar, int m, int i, int j);
|
||||
extern double dlevmar_R2(void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, void *adata);
|
||||
|
||||
#endif /* LM_DBL_PREC */
|
||||
|
||||
#ifdef LM_SNGL_PREC
|
||||
extern float slevmar_stddev( float *covar, int m, int i);
|
||||
extern float slevmar_corcoef(float *covar, int m, int i, int j);
|
||||
extern float slevmar_R2(void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, void *adata);
|
||||
#endif /* LM_SNGL_PREC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LEVMAR_H_ */
|
@ -0,0 +1 @@
|
||||
levmar.h
|
@ -0,0 +1,106 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Levenberg - Marquardt non-linear minimization algorithm
|
||||
// Copyright (C) 2004 Manolis Lourakis (lourakis at ics forth gr)
|
||||
// Institute of Computer Science, Foundation for Research & Technology - Hellas
|
||||
// Heraklion, Crete, Greece.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MISC_H_
|
||||
#define _MISC_H_
|
||||
|
||||
/* common suffix for LAPACK subroutines. Define empty in case of no prefix. */
|
||||
#define LM_LAPACK_SUFFIX _
|
||||
//#define LM_LAPACK_SUFFIX // define empty
|
||||
|
||||
/* common prefix for BLAS subroutines. Leave undefined in case of no prefix.
|
||||
* You might also need to modify LM_BLAS_PREFIX below
|
||||
*/
|
||||
/* f2c'd BLAS */
|
||||
//#define LM_BLAS_PREFIX f2c_
|
||||
/* C BLAS */
|
||||
//#define LM_BLAS_PREFIX cblas_
|
||||
|
||||
/* common suffix for BLAS subroutines */
|
||||
//#define LM_BLAS_SUFFIX // define empty if a f2c_ or cblas_ prefix was defined for LM_BLAS_PREFIX above
|
||||
#define LM_BLAS_SUFFIX _ // use this in case of no BLAS prefix
|
||||
|
||||
|
||||
#define LCAT_(a, b) #a b
|
||||
#define LCAT(a, b) LCAT_(a, b) // force substitution
|
||||
#define RCAT_(a, b) a #b
|
||||
#define RCAT(a, b) RCAT_(a, b) // force substitution
|
||||
|
||||
#define LM_MK_LAPACK_NAME(s) LM_ADD_PREFIX(LM_CAT_(s, LM_LAPACK_SUFFIX))
|
||||
|
||||
|
||||
#define __BLOCKSZ__ 32 /* block size for cache-friendly matrix-matrix multiply. It should be
|
||||
* such that __BLOCKSZ__^2*sizeof(LM_REAL) is smaller than the CPU (L1)
|
||||
* data cache size. Notice that a value of 32 when LM_REAL=double assumes
|
||||
* an 8Kb L1 data cache (32*32*8=8K). This is a concervative choice since
|
||||
* newer Pentium 4s have a L1 data cache of size 16K, capable of holding
|
||||
* up to 45x45 double blocks.
|
||||
*/
|
||||
#define __BLOCKSZ__SQ (__BLOCKSZ__)*(__BLOCKSZ__)
|
||||
|
||||
/* add a prefix in front of a token */
|
||||
#define LM_CAT__(a, b) a ## b
|
||||
#define LM_CAT_(a, b) LM_CAT__(a, b) // force substitution
|
||||
#define LM_ADD_PREFIX(s) LM_CAT_(LM_PREFIX, s)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* blocking-based matrix multiply */
|
||||
extern void slevmar_trans_mat_mat_mult(float *a, float *b, int n, int m);
|
||||
extern void dlevmar_trans_mat_mat_mult(double *a, double *b, int n, int m);
|
||||
|
||||
/* forward finite differences */
|
||||
extern void slevmar_fdif_forw_jac_approx(void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *hx, float *hxx, float delta,
|
||||
float *jac, int m, int n, void *adata);
|
||||
extern void dlevmar_fdif_forw_jac_approx(void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *hx, double *hxx, double delta,
|
||||
double *jac, int m, int n, void *adata);
|
||||
|
||||
/* central finite differences */
|
||||
extern void slevmar_fdif_cent_jac_approx(void (*func)(float *p, float *hx, int m, int n, void *adata),
|
||||
float *p, float *hxm, float *hxp, float delta,
|
||||
float *jac, int m, int n, void *adata);
|
||||
extern void dlevmar_fdif_cent_jac_approx(void (*func)(double *p, double *hx, int m, int n, void *adata),
|
||||
double *p, double *hxm, double *hxp, double delta,
|
||||
double *jac, int m, int n, void *adata);
|
||||
|
||||
/* e=x-y and ||e|| */
|
||||
extern float slevmar_L2nrmxmy(float *e, float *x, float *y, int n);
|
||||
extern double dlevmar_L2nrmxmy(double *e, double *x, double *y, int n);
|
||||
|
||||
/* covariance of LS fit */
|
||||
extern int slevmar_covar(float *JtJ, float *C, float sumsq, int m, int n);
|
||||
extern int dlevmar_covar(double *JtJ, double *C, double sumsq, int m, int n);
|
||||
|
||||
/* box constraints consistency check */
|
||||
extern int slevmar_box_check(float *lb, float *ub, int m);
|
||||
extern int dlevmar_box_check(double *lb, double *ub, int m);
|
||||
|
||||
/* Cholesky */
|
||||
extern int slevmar_chol(float *C, float *W, int m);
|
||||
extern int dlevmar_chol(double *C, double *W, int m);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MISC_H_ */
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
ADD_SUBDIRECTORY(Mosaic)
|
||||
ADD_SUBDIRECTORY(Utils)
|
@ -0,0 +1,29 @@
|
||||
PROJECT( Mosaic )
|
||||
STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_CAPITALIZED)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
|
||||
ADD_DEFINITIONS(-DUNICODE)
|
||||
|
||||
#Use MFC in a Shared DLL
|
||||
ADD_DEFINITIONS(-D_AFXDLL)
|
||||
SET(CMAKE_MFC_FLAG 2)
|
||||
|
||||
FILE(GLOB_RECURSE HDRS_FILES *.h *.hpp)
|
||||
FILE(GLOB_RECURSE SRCS_FILES *.cpp)
|
||||
FILE(GLOB_RECURSE UI_FILES *.ui)
|
||||
FILE(GLOB CD_FILES *.cd)
|
||||
|
||||
SET(FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${SRCS_FILES} ${UI_FILES} ${HDRS_FILES} PARENT_SCOPE)
|
||||
|
||||
SOURCE_GROUP("UI Files" FILES ${UI_FILES})
|
||||
SOURCE_GROUP("Generated Files" FILES ${MOC_SRCS} ${UI_HDRS} ${RSC_SRCS})
|
||||
SOURCE_GROUP("Class Diagrams" FILES ${CD_FILES} )
|
||||
#SOURCE_GROUP("Resources" FILES ${RSCS} )
|
||||
|
||||
ADD_EXECUTABLE(${PROJECT_NAME} ${HDRS_FILES} ${SRCS_FILES} ${UI_HDRS} ${UI_FILES} ${RSC_SRCS} ${MOC_SRCS} ${CD_FILES})
|
||||
ADD_DEPENDENCIES(${PROJECT_NAME} Utils)
|
||||
SET_SOURCE_FILES_PROPERTIES(${CD_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) # DO NOT COMPILE CS FILES
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${QT_LIBRARIES} ${OpenCV_LIBS} Utils libf2cd.lib BLASd.lib clapackd.lib tmglibd.lib levmar.lib)
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:libcmt.lib")
|
||||
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES FOLDER SRC)
|
||||
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,109 @@
|
||||
#pragma once
|
||||
#include "featureMatch.h"
|
||||
#include "graphPro.h"
|
||||
#include "topology.h"
|
||||
#include "levmar.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#define PENALTY_COEFF 0.10 //! set for LM only
|
||||
#define Lambada 0.12 //! set for BA only
|
||||
#define OPT_GROUP_NUM 30
|
||||
#define BKGRNDPIX 255
|
||||
#define Need_Mask 1
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
using namespace Utils;
|
||||
|
||||
struct Match_Net
|
||||
{
|
||||
int imgNo; //! image no. start from 0
|
||||
vector<int> relatedImgs; //! the position index of overlap-image in visitOrder
|
||||
vector<vector<Point2d> > PointSet;
|
||||
};
|
||||
|
||||
struct LMData
|
||||
{
|
||||
vector<Match_Net> *matchPtr;
|
||||
vector<Mat_<double> > *modelPtr;
|
||||
vector<TreeNode> visitOrder;
|
||||
int sIndex;
|
||||
int eIndex;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
//! Notification : imgIndex/imgNo start from 0
|
||||
|
||||
class ImageAligner
|
||||
{
|
||||
public:
|
||||
ImageAligner(vector<string> filePathList)
|
||||
{
|
||||
_filePathList = filePathList;
|
||||
_imgNum = filePathList.size();
|
||||
_refImgNo = 0;
|
||||
};
|
||||
~ImageAligner(){};
|
||||
|
||||
public:
|
||||
//*** functions for sorting the topological relationship of images ***//
|
||||
void sortImageOrder(int referNo, bool shallLoad, bool isInorder);
|
||||
void divideImageGroups();
|
||||
bool loadMatchPts(int imgIndex1, int imgIndex2, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2);
|
||||
|
||||
public:
|
||||
//*** functions for building and optimizing the alignment ***//
|
||||
void imageStitcherbyGroup(int referNo);
|
||||
void imageStitcherbySolos(int referNo);
|
||||
void fillImageMatchNet();
|
||||
//! initial alignment by affine model
|
||||
void solveGroupModels(int sIndex, int eIndex);
|
||||
//! initial alignment by similarity transformation model
|
||||
void solveGroupModelsS(int sIndex, int eIndex);
|
||||
//! initial alignment by affine model
|
||||
void solveSingleModel(int imgIndex);
|
||||
int findVisitIndex(int imgNo);
|
||||
//! alignment refinement to homographic model : LM Optimization
|
||||
void RefineAligningModels(int sIndex, int eIndex);
|
||||
void buildIniSolution(double* X, int sIndex, int eIndex);
|
||||
static void OptimizationFunction(double* X, double* d, int m, int n, void* data);
|
||||
//! alignment refinement to homographic model : Least Square Optimization
|
||||
void bundleAdjustingA(int sIndex, int eIndex); //! method 1 : big matrix
|
||||
void bundleAdjustinga(int sIndex, int eIndex); //! method 1 : normalize by point
|
||||
void bundleAdjusting(int sIndex, int eIndex); //! method 2 : normalize by point
|
||||
void buildIniSolution(double* X, double* initX, int sIndex, int eIndex);
|
||||
|
||||
double CalWarpDeviation(vector<Point2d> pointSet1, vector<Point2d> pointSet2, Mat_<double> cvtMat, vector<double> weightList);
|
||||
//! detect potential overlapping relationships based on the new position (only used in the refinement)
|
||||
void recheckTopology(int sIndex, int eIndex);
|
||||
|
||||
//! display or output functions
|
||||
Rect setImageSize(vector<Point2d> &nodePts);
|
||||
void saveMosaicImage(); //! aligning in added order
|
||||
void saveMosaicImageP(); //! aligning in image no. order
|
||||
void outputPrecise();
|
||||
void loadHomographies();
|
||||
void saveModelParams();
|
||||
void drawTopologyNet();
|
||||
void labelGroupNodes();
|
||||
void drawSimilarMatrix();
|
||||
|
||||
private:
|
||||
PointMatcher *_matcher;
|
||||
Mat_<int> _similarityMat;
|
||||
int _refImgNo;
|
||||
int _imgNum;
|
||||
int _alignedNum;
|
||||
vector<int> _groupCusorList;
|
||||
vector<TreeNode> _visitOrder; //! aligning order according this stack
|
||||
vector<Quadra> _projCoordSet; //! same order with "_visitOrder"
|
||||
vector<Match_Net> _matchNetList; //! matching relation of each image (order agree with image no.)
|
||||
vector<Mat_<double> > _alignModelList; //! aligning model parameters of each image (order agree with '_visitOrder')
|
||||
vector<Mat_<double> > _initModelList;
|
||||
|
||||
vector<double> reliabilityList; //! record the mean square error of the initial affine model of each image
|
||||
vector<string> _filePathList;
|
||||
vector<Size> _imgSizeList; //! order agree with image no.
|
||||
};
|
@ -0,0 +1,484 @@
|
||||
#include "featureMatch.h"
|
||||
|
||||
void PointMatcher::featureExtractor(bool extraPoints)
|
||||
{
|
||||
int i, j;
|
||||
if (!extraPoints)
|
||||
{
|
||||
for (i = 0; i < _imgNum; i ++)
|
||||
{
|
||||
int imgIndex = i;
|
||||
char saveName[1024];
|
||||
sprintf(saveName, "Cache/keyPtfile/keys%d", imgIndex);
|
||||
string saveName_ = Utils::baseDir + string(saveName);
|
||||
_keysFileList.push_back(saveName_);
|
||||
}
|
||||
loadImgSizeList();
|
||||
return;
|
||||
}
|
||||
SurfFeatureDetector detector(400);
|
||||
SurfDescriptorExtractor extractor;
|
||||
for (i = 0; i < _imgNum; i ++)
|
||||
{
|
||||
string imgPath = _imgNameList[i];
|
||||
Mat image = imread(imgPath);
|
||||
Size imgSize(image.cols, image.rows);
|
||||
_imgSizeList.push_back(imgSize);
|
||||
|
||||
vector<KeyPoint> keyPts;
|
||||
Mat descriptors;
|
||||
detector.detect(image, keyPts);
|
||||
extractor.compute(image, keyPts, descriptors);
|
||||
|
||||
int imgIndex = i;
|
||||
char saveName[1024];
|
||||
sprintf(saveName, "Cache/keyPtfile/keys%d", imgIndex);
|
||||
string saveName_ = Utils::baseDir + string(saveName);
|
||||
_keysFileList.push_back(saveName_);
|
||||
savefeatures(keyPts, descriptors, saveName_);
|
||||
cout<<imgIndex<<" keyPoint file saved!"<<endl;
|
||||
}
|
||||
saveImgSizeList();
|
||||
}
|
||||
|
||||
|
||||
void PointMatcher::savefeatures(vector<KeyPoint> keyPts, Mat descriptors, string saveName)
|
||||
{
|
||||
FILE *fout;
|
||||
fout = fopen(saveName.c_str(), "w");
|
||||
|
||||
int PtNum = keyPts.size();
|
||||
fprintf(fout, "%d\n", PtNum);
|
||||
unsigned i, j;
|
||||
// int n0 = 0, n1 = 0, n2 = 0, n3 = 0;
|
||||
for (i = 0; i < PtNum; i ++)
|
||||
{
|
||||
Point2d point = keyPts[i].pt;
|
||||
int octave = keyPts[i].octave;
|
||||
fprintf(fout, "%.8lf %.8lf %d\n", point.x, point.y, octave);
|
||||
//if (octave == 0)
|
||||
//{
|
||||
// n0 ++;
|
||||
//}
|
||||
//else if (octave == 1)
|
||||
//{
|
||||
// n1 ++;
|
||||
//}
|
||||
//else if (octave == 2)
|
||||
//{
|
||||
// n2 ++;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// n3 ++;
|
||||
//}
|
||||
}
|
||||
//int nn = n0+n1+n2+n3;
|
||||
//cout<<n0*1.0/nn<<" "<<n1*1.0/nn<<" "<<n2*1.0/nn<<" "<<n3*1.0/nn<<" from "<<nn<<endl;
|
||||
for (i = 0; i < PtNum; i ++) //write feature descriptor data
|
||||
{
|
||||
for (j = 0; j < featureDimension; j ++)
|
||||
{
|
||||
float temp = descriptors.at<float>(i,j);
|
||||
fprintf(fout, "%.8f ", temp);
|
||||
}
|
||||
fprintf(fout, "\n");
|
||||
}
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
|
||||
void PointMatcher::readfeatures(int imgIndex, vector<Point2d> &keyPts, Mat &descriptors, double ratio)
|
||||
{
|
||||
string fileName = _keysFileList[imgIndex];
|
||||
FILE *fin = fopen(fileName.c_str(), "r");
|
||||
int PtNum = 0;
|
||||
fscanf(fin, "%d", &PtNum);
|
||||
|
||||
int step = int(1/ratio);
|
||||
int realNum = 0;
|
||||
unsigned i, j;
|
||||
for (i = 0; i < PtNum; i ++)
|
||||
{
|
||||
Point2d point;
|
||||
int octave = 0;
|
||||
fscanf(fin, "%lf%lf%d", &point.x, &point.y, &octave);
|
||||
if (i%step == 0)
|
||||
{
|
||||
keyPts.push_back(point);
|
||||
realNum++;
|
||||
}
|
||||
}
|
||||
descriptors = Mat(realNum, featureDimension, CV_32FC1, Scalar(0));
|
||||
int cnt = 0;
|
||||
for (i = 0; i < PtNum; i ++) //write feature descriptor data
|
||||
{
|
||||
if (i%step != 0)
|
||||
{
|
||||
for (j = 0; j < featureDimension; j ++)
|
||||
{
|
||||
float temp;
|
||||
fscanf(fin, "%f", &temp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < featureDimension; j ++)
|
||||
{
|
||||
float temp;
|
||||
fscanf(fin, "%f", &temp);
|
||||
descriptors.at<float>(cnt,j) = temp;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
fclose(fin);
|
||||
}
|
||||
|
||||
|
||||
void PointMatcher::loadImgSizeList()
|
||||
{
|
||||
string filePath = Utils::baseDir + "Cache/imgSizeList.txt";
|
||||
FILE *fin = fopen(filePath.c_str(), "r");
|
||||
if (fin == nullptr)
|
||||
{
|
||||
cout<<"No image size file!\n";
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < _imgNum; i ++)
|
||||
{
|
||||
int width, height;
|
||||
fscanf(fin, "%d %d\n", &width, &height);
|
||||
_imgSizeList.push_back(Size(width,height));
|
||||
}
|
||||
fclose(fin);
|
||||
}
|
||||
|
||||
|
||||
void PointMatcher::saveImgSizeList()
|
||||
{
|
||||
string savePath = Utils::baseDir + "Cache/imgSizeList.txt";
|
||||
FILE *fout = fopen(savePath.c_str(), "w");
|
||||
for (int i = 0; i < _imgNum; i ++)
|
||||
{
|
||||
int width = _imgSizeList[i].width, height = _imgSizeList[i].height;
|
||||
fprintf(fout, "%d %d\n", width, height);
|
||||
}
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
|
||||
bool PointMatcher::featureMatcher(int imgIndex1, int imgIndex2, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2)
|
||||
{
|
||||
pointSet1.clear();
|
||||
pointSet2.clear();
|
||||
vector<Point2d> keyPts1, keyPts2;
|
||||
Mat descriptors1, descriptors2;
|
||||
readfeatures(imgIndex1, keyPts1, descriptors1, 1.0);
|
||||
readfeatures(imgIndex2, keyPts2, descriptors2, 1.0);
|
||||
|
||||
// Matching descriptor vectors using FLANN matcher
|
||||
vector<DMatch> m_Matches;
|
||||
FlannBasedMatcher matcher;
|
||||
vector<vector<DMatch>> knnmatches;
|
||||
int num1 = keyPts1.size(), num2 = keyPts2.size();
|
||||
int kn = min(min(num1, num2), 5);
|
||||
matcher.knnMatch(descriptors1, descriptors2, knnmatches, kn);
|
||||
int i, j;
|
||||
double minimaDsit = 99999;
|
||||
for (i = 0; i < knnmatches.size(); i ++)
|
||||
{
|
||||
double dist = knnmatches[i][1].distance;
|
||||
if (dist < minimaDsit)
|
||||
{
|
||||
minimaDsit = dist;
|
||||
}
|
||||
}
|
||||
double fitedThreshold = minimaDsit * 5;
|
||||
int keypointsize = knnmatches.size();
|
||||
for (i = 0; i < keypointsize; i ++)
|
||||
{
|
||||
const DMatch nearDist1 = knnmatches[i][0];
|
||||
const DMatch nearDist2 = knnmatches[i][1];
|
||||
double distanceRatio = nearDist1.distance / nearDist2.distance;
|
||||
if (nearDist1.distance < fitedThreshold && distanceRatio < 0.7)
|
||||
{
|
||||
m_Matches.push_back(nearDist1);
|
||||
}
|
||||
}
|
||||
|
||||
vector<Point2d> iniPts1, iniPts2;
|
||||
for (i = 0; i < m_Matches.size(); i ++) //get initial match pairs
|
||||
{
|
||||
int queryIndex = m_Matches[i].queryIdx;
|
||||
int trainIndex = m_Matches[i].trainIdx;
|
||||
Point2d tempPt1 = keyPts1[queryIndex];
|
||||
Point2d tempPt2 = keyPts2[trainIndex];
|
||||
iniPts1.push_back(tempPt1);
|
||||
iniPts2.push_back(tempPt2);
|
||||
}
|
||||
if (iniPts1.size() < 10)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<uchar> status;
|
||||
//! utilize epi-polar geometry constraints to delete missing matches
|
||||
Mat Fmatrix = findFundamentalMat(iniPts1, iniPts2, CV_RANSAC, 1.5, 0.99, status);
|
||||
for (i = 0; i < status.size(); i ++)
|
||||
{
|
||||
if (status[i] == 1)
|
||||
{
|
||||
pointSet1.push_back(iniPts1[i]);
|
||||
pointSet2.push_back(iniPts2[i]);
|
||||
}
|
||||
}
|
||||
if (pointSet1.size() < 10)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Mat homoMat = findHomography(iniPts2, iniPts1, CV_RANSAC, 2.5); //! Pt1 = homoMat*Pt2
|
||||
vector<Point2d> goodPts1, goodPts2;
|
||||
for (i = 0; i < pointSet1.size(); i ++) //mean value
|
||||
{
|
||||
Point2d warpedPt;
|
||||
Utils::pointTransform(homoMat, pointSet2[i], warpedPt);
|
||||
double dist = 0;
|
||||
dist = sqrt((warpedPt.x-pointSet1[i].x)*(warpedPt.x-pointSet1[i].x) + (warpedPt.y-pointSet1[i].y)*(warpedPt.y-pointSet1[i].y));
|
||||
if (dist < 3.0)
|
||||
{
|
||||
goodPts1.push_back(pointSet1[i]);
|
||||
goodPts2.push_back(pointSet2[i]);
|
||||
}
|
||||
}
|
||||
pointSet1 = goodPts1;
|
||||
pointSet2 = goodPts2;
|
||||
if (pointSet1.size() < 10) //! modify as 20
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// cout<<"Image "<<imgIndex1<<" and image "<<imgIndex2<<" matched "<<pointSet1.size()<<" points"<<endl;
|
||||
|
||||
////! chouxi
|
||||
//int step = max(1,int(pointSet1.size()/30));
|
||||
//vector<Point2d> set1, set2;
|
||||
//for (int i = 0; i < pointSet1.size(); i += step)
|
||||
//{
|
||||
// set1.push_back(pointSet1[i]);
|
||||
// set2.push_back(pointSet2[i]);
|
||||
//}
|
||||
//saveMatchPts(imgIndex1, imgIndex2, set1, set2);
|
||||
//drawMatches(imgIndex1, imgIndex2, set1, set2);
|
||||
saveMatchPts(imgIndex1, imgIndex2, pointSet1, pointSet2);
|
||||
// drawMatches(imgIndex1, imgIndex2, pointSet1, pointSet2);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PointMatcher::saveMatchPts(int imgIndex1, int imgIndex2, vector<Point2d> pointSet1, vector<Point2d> pointSet2)
|
||||
{
|
||||
bool exchanged = false;
|
||||
if (imgIndex1 > imgIndex2) //set a consistent standard: smaller index in the left
|
||||
{
|
||||
int temp = imgIndex2;
|
||||
imgIndex2 = imgIndex1;
|
||||
imgIndex1 = temp;
|
||||
exchanged = true;
|
||||
}
|
||||
char saveName[1024];
|
||||
sprintf(saveName, "Cache/matchPtfile/match%d&%d.txt", imgIndex1, imgIndex2);
|
||||
string savePath = Utils::baseDir + string(saveName);
|
||||
FILE *fout = fopen(savePath.c_str(), "w");
|
||||
int PtNum = pointSet1.size();
|
||||
fprintf(fout, "%d\n", PtNum);
|
||||
if (!exchanged)
|
||||
{
|
||||
for (int i = 0; i < PtNum; i ++)
|
||||
{
|
||||
double x1 = pointSet1[i].x, y1 = pointSet1[i].y;
|
||||
double x2 = pointSet2[i].x, y2 = pointSet2[i].y;
|
||||
fprintf(fout, "%lf %lf %lf %lf\n", x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < PtNum; i ++)
|
||||
{
|
||||
double x1 = pointSet1[i].x, y1 = pointSet1[i].y;
|
||||
double x2 = pointSet2[i].x, y2 = pointSet2[i].y;
|
||||
fprintf(fout, "%lf %lf %lf %lf\n", x2, y2, x1, y1);
|
||||
}
|
||||
}
|
||||
fclose(fout);
|
||||
// cout<<"Matched Points of image "<<imgIndex1<<" & image "<<imgIndex2<<" saved!"<<endl;
|
||||
}
|
||||
|
||||
|
||||
bool PointMatcher::loadMatchPts(int imgIndex1, int imgIndex2, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2)
|
||||
{
|
||||
bool exchanged = false;
|
||||
if (imgIndex1 > imgIndex2) //set a consistent standard: smaller index in the left
|
||||
{
|
||||
int temp = imgIndex2;
|
||||
imgIndex2 = imgIndex1;
|
||||
imgIndex1 = temp;
|
||||
exchanged = true;
|
||||
}
|
||||
char fileName[1024];
|
||||
sprintf(fileName, "Cache/matchPtfile/match%d&%d.txt", imgIndex1, imgIndex2);
|
||||
string filePath = Utils::baseDir + string(fileName);
|
||||
FILE *fin = fopen(filePath.c_str(), "r");
|
||||
if (fin == nullptr)
|
||||
{
|
||||
cout<<"invalid matching file of image "<<imgIndex1<<" & image "<<imgIndex2<<endl;
|
||||
return false;
|
||||
}
|
||||
int PtNum = 0;
|
||||
fscanf(fin, "%d", &PtNum);
|
||||
if (!exchanged)
|
||||
{
|
||||
for (int i = 0; i < PtNum; i ++)
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
fscanf(fin, "%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
|
||||
Point2d point1(x1,y1), point2(x2,y2);
|
||||
pointSet1.push_back(point1);
|
||||
pointSet2.push_back(point2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < PtNum; i ++)
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
fscanf(fin, "%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
|
||||
Point2d point1(x1,y1), point2(x2,y2);
|
||||
pointSet1.push_back(point2);
|
||||
pointSet2.push_back(point1);
|
||||
}
|
||||
}
|
||||
fclose(fin);
|
||||
cout<<"Loaded "<<pointSet1.size()<<" points between image "<<imgIndex1<<" and image "<<imgIndex2<<endl;
|
||||
}
|
||||
|
||||
|
||||
bool PointMatcher::tentativeMatcher(int imgIndex1, int imgIndex2)
|
||||
{
|
||||
vector<Point2d> keyPts1, keyPts2;
|
||||
Mat descriptors1, descriptors2;
|
||||
readfeatures(imgIndex1, keyPts1, descriptors1, 0.3);
|
||||
readfeatures(imgIndex2, keyPts2, descriptors2, 0.3);
|
||||
|
||||
// Matching descriptor vectors using FLANN matcher
|
||||
vector<DMatch> m_Matches;
|
||||
FlannBasedMatcher matcher;
|
||||
vector<vector<DMatch>> knnmatches;
|
||||
int num1 = keyPts1.size(), num2 = keyPts2.size();
|
||||
int kn = min(min(num1, num2), 5);
|
||||
matcher.knnMatch(descriptors1, descriptors2, knnmatches, kn);
|
||||
int i, j;
|
||||
double minimaDsit = 99999;
|
||||
for (i = 0; i < knnmatches.size(); i ++)
|
||||
{
|
||||
double dist = knnmatches[i][0].distance;
|
||||
if (dist < minimaDsit)
|
||||
{
|
||||
minimaDsit = dist;
|
||||
}
|
||||
}
|
||||
double fitedThreshold = minimaDsit * 5;
|
||||
int keypointsize = knnmatches.size();
|
||||
for (i = 0; i < keypointsize; i ++)
|
||||
{
|
||||
const DMatch nearDist1 = knnmatches[i][0];
|
||||
const DMatch nearDist2 = knnmatches[i][1];
|
||||
double distanceRatio = nearDist1.distance / nearDist2.distance;
|
||||
if (nearDist1.distance < fitedThreshold && distanceRatio < 0.7)
|
||||
{
|
||||
m_Matches.push_back(nearDist1);
|
||||
}
|
||||
}
|
||||
vector<Point2d> iniPts1, iniPts2;
|
||||
for (i = 0; i < m_Matches.size(); i ++) //get initial match pairs
|
||||
{
|
||||
int queryIndex = m_Matches[i].queryIdx;
|
||||
int trainIndex = m_Matches[i].trainIdx;
|
||||
Point2d tempPt1 = keyPts1[queryIndex];
|
||||
Point2d tempPt2 = keyPts2[trainIndex];
|
||||
iniPts1.push_back(tempPt1);
|
||||
iniPts2.push_back(tempPt2);
|
||||
}
|
||||
if (iniPts1.size() < 15)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Mat_<double> homoMat = findHomography(iniPts1, iniPts2, CV_RANSAC, 5.0); //initial solution : from image2 to image1
|
||||
vector<Point2d> goodPts1, goodPts2;
|
||||
for (i = 0; i < iniPts1.size(); i ++) //mean value
|
||||
{
|
||||
Point2d warpedPt;
|
||||
pointConvert(homoMat, iniPts2[i], warpedPt);
|
||||
double dist = 0;
|
||||
dist = sqrt((warpedPt.x-iniPts1[i].x)*(warpedPt.x-iniPts1[i].x) + (warpedPt.y-iniPts1[i].y)*(warpedPt.y-iniPts1[i].y));
|
||||
if (dist < 5.0)
|
||||
{
|
||||
goodPts1.push_back(iniPts1[i]);
|
||||
goodPts2.push_back(iniPts2[i]);
|
||||
}
|
||||
}
|
||||
if (goodPts1.size() < 5)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PointMatcher::pointConvert(Mat_<double> homoMat, Point2d src, Point2d &dst)
|
||||
{
|
||||
Mat_<double> srcX = (Mat_<double>(3,1)<< src.x, src.y, 1);
|
||||
Mat_<double> dstX = homoMat * srcX;
|
||||
dst = Point2d(dstX(0)/dstX(2), dstX(1)/dstX(2));
|
||||
}
|
||||
|
||||
|
||||
void PointMatcher::drawMatches(int imgIndex1, int imgIndex2, vector<Point2d> pointSet1, vector<Point2d> pointSet2)
|
||||
{
|
||||
int i, j;
|
||||
string fileName1 = _imgNameList[imgIndex1];
|
||||
string fileName2 = _imgNameList[imgIndex2];
|
||||
Mat image1 = imread(fileName1);
|
||||
Mat image2 = imread(fileName2);
|
||||
int w = 8;
|
||||
CvFont font;
|
||||
double hScale = 1;
|
||||
double vScale = 1;
|
||||
cvInitFont(&font,CV_FONT_HERSHEY_PLAIN, hScale,vScale,0,1); //¶¨Òå±ê¼Ç×ÖÌå
|
||||
for (i = 0; i < pointSet1.size(); i ++)
|
||||
{
|
||||
Point2d tempPt1 = pointSet1[i];
|
||||
circle(image1, tempPt1, 3, Scalar(0,0,255), -1);
|
||||
|
||||
Point2d tempPt2 = pointSet2[i];
|
||||
circle(image2, tempPt2, 3, Scalar(0,0,255), -1);
|
||||
|
||||
/* char text[100];
|
||||
sprintf(text,"%d", i);
|
||||
Point2d dotPt(3, 3);
|
||||
cv::putText(image1, text, tempPt1+dotPt, 2, 1, Scalar(0,0,0));
|
||||
cv::putText(image2, text, tempPt2+dotPt, 2, 1, Scalar(0,0,0));*/
|
||||
line(image1, tempPt1, tempPt2, Scalar(0,255,0), 1);
|
||||
line(image2, tempPt2, tempPt1, Scalar(0,255,0), 1);
|
||||
}
|
||||
char name1[512], name2[512];
|
||||
static int no = 0;
|
||||
sprintf(name1, "match%d_0.jpg", no);
|
||||
sprintf(name2, "match%d_1.jpg", no);
|
||||
no ++;
|
||||
string filePath1 = Utils::baseDir + "Cache/match_map/" + string(name1);
|
||||
string filePath2 = Utils::baseDir + "Cache/match_map/" + string(name2);
|
||||
imwrite(filePath1, image1);
|
||||
imwrite(filePath2, image2);
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include "Utils/util.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include <opencv2/calib3d/calib3d.hpp>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
// ============== NOTIFICATION =============== //
|
||||
//! image no. is encoded from 0, 2, ..., n-1. //
|
||||
//! //
|
||||
// =========================================== //
|
||||
|
||||
class PointMatcher
|
||||
{
|
||||
public:
|
||||
PointMatcher(vector<string> imgNameList, bool extraPoints)
|
||||
{
|
||||
featureDimension = 64;
|
||||
_imgNameList = imgNameList;
|
||||
_imgNum = imgNameList.size();
|
||||
featureExtractor(extraPoints);
|
||||
};
|
||||
|
||||
public:
|
||||
void featureExtractor(bool extraPoints);
|
||||
void readfeatures(int imgIndex, vector<Point2d> &keyPts, Mat &descriptors, double ratio);
|
||||
void savefeatures(vector<KeyPoint> keyPts, Mat descriptors, string saveName);
|
||||
void loadImgSizeList();
|
||||
void saveImgSizeList();
|
||||
|
||||
bool tentativeMatcher(int imgIndex1, int imgIndex2);
|
||||
bool featureMatcher(int imgIndex1, int imgIndex2, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2); //! all the imgIndex start from 1
|
||||
void saveMatchPts(int imgIndex1, int imgIndex2, vector<Point2d> pointSet1, vector<Point2d> pointSet2);
|
||||
bool loadMatchPts(int imgIndex1, int imgIndex2, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2);
|
||||
|
||||
void pointConvert(Mat_<double> homoMat, Point2d src, Point2d &dst);
|
||||
void drawMatches(int imgIndex1, int imgIndex2, vector<Point2d> pointSet1, vector<Point2d> pointSet2);
|
||||
|
||||
public:
|
||||
vector<Size> _imgSizeList;
|
||||
vector<string> _imgNameList;
|
||||
|
||||
private:
|
||||
int _imgNum;
|
||||
int featureDimension;
|
||||
vector<string> _keysFileList;
|
||||
};
|
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "Utils/util.h"
|
||||
#include <iostream>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
using namespace Utils;
|
||||
|
||||
// ===================== NOTIFICATION ====================== //
|
||||
//! node is encoded from 0, 2, ..., n-1. //
|
||||
//! cost graph: all cost must be a positive value, and cost //
|
||||
//! of the non-overlap pair is specially set as -1. //
|
||||
// ========================================================= //
|
||||
|
||||
class Graph
|
||||
{
|
||||
public:
|
||||
Graph()
|
||||
{
|
||||
|
||||
};
|
||||
~Graph(){};
|
||||
|
||||
//! single-source shortest path algorithm
|
||||
static vector<TreeNode> DijkstraForPath(Mat_<double> graph, int rootNo);
|
||||
//! shortest path algorithm for all node pairs
|
||||
static vector<TreeNode> FloydForPath(Mat_<double> graph);
|
||||
//! minimum spanning tree
|
||||
static Mat_<int> extractMSTree(Mat_<double> graph);
|
||||
|
||||
//! tool functions
|
||||
static vector<TreeNode> traverseBreadthFirst(Mat_<int> path, int rootNo);
|
||||
static void appendix(Mat_<double> dist, int root);
|
||||
};
|
@ -0,0 +1,75 @@
|
||||
#include "featureMatch.h"
|
||||
#include "alignment.h"
|
||||
#include "Utils/util.h"
|
||||
#include <time.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <windows.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void DOMCheckbyRigid();
|
||||
|
||||
void main()
|
||||
{
|
||||
clock_t start_time, end_time;
|
||||
start_time = clock();
|
||||
|
||||
string imagePath = Utils::baseDir + "Images/classic1";
|
||||
vector<string> imgPathList = Utils::get_filelist(imagePath);
|
||||
// for (int i = 0; i < imgPathList.size(); i ++)
|
||||
// {
|
||||
// if ((i%31)%2 != 0)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
// Mat img = imread(imgPathList[i]);
|
||||
//// cout<<imgPathList[i]<<endl;
|
||||
// char name[512];
|
||||
// sprintf(name, "E:/bar/img%02d_%02d.jpg",i/31+1,i%31+1);
|
||||
//// cout<<name<<endl;
|
||||
// string fileName = name;
|
||||
// imwrite(fileName, img);
|
||||
// }
|
||||
// return;
|
||||
ImageAligner imgAligner(imgPathList);
|
||||
//! define these arguments below according to your case
|
||||
int referNo = -1; //! which image (the default no is defined as the name sorted) is used as the global reference
|
||||
bool isSeqData = false; //! is the input images are overlapped sequentially as the name sorted
|
||||
bool loadKeypts = false; //! is keypoint file of each image available
|
||||
bool loadTopology = false; //! is topology similarity file available
|
||||
// imgAligner.imageStitcherbySolos(referNo, isSeqData, loadKeypts, loadTopology);
|
||||
imgAligner.imageStitcherbyGroup(referNo, isSeqData, loadKeypts, loadTopology);
|
||||
end_time=clock();
|
||||
cout<<"All done! consumed "<<(end_time-start_time)/CLOCKS_PER_SEC<<" seconds! "<<endl;
|
||||
}
|
||||
|
||||
|
||||
void DOMCheckbyRigid()
|
||||
{
|
||||
vector<Point2d> pts1, pts2;
|
||||
Utils::loadMatchPts(0, 1, pts1, pts2);
|
||||
Mat_<double> A = Mat(2*21, 4, CV_64FC1, Scalar(0));
|
||||
Mat_<double> L = Mat(2*21, 1, CV_64FC1, Scalar(0));
|
||||
for (int k = 0; k < pts1.size(); k ++)
|
||||
{
|
||||
int rn = k;
|
||||
Point2d pt1 = pts2[k], pt2 = pts1[k];
|
||||
A(2*rn,0) = pt1.x; A(2*rn,1) = -pt1.y; A(2*rn,2) = 1;
|
||||
A(2*rn+1,0) = pt1.y; A(2*rn+1,1) = pt1.x; A(2*rn+1,3) = 1;
|
||||
L(2*rn) = pt2.x;
|
||||
L(2*rn+1) = pt2.y;
|
||||
}
|
||||
Mat_<double> X = (A.t()*A).inv()*(A.t()*L);
|
||||
Mat_<double> simiModel = (Mat_<double>(3,3) << X(0) , -X(1), X(2),
|
||||
X(1), X(0), X(3),
|
||||
0, 0, 1);
|
||||
FILE *fp = fopen("E:/adf.txt", "w");
|
||||
for (int k = 0; k < pts2.size(); k ++)
|
||||
{
|
||||
Point2d tar = Utils::pointTransform(simiModel, pts2[k]);
|
||||
fprintf(fp, "%lf %lf\n", tar.x, tar.y);
|
||||
}
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
#include "Utils/util.h"
|
||||
#include "featureMatch.h"
|
||||
#include "graphPro.h"
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include <opencv2/calib3d/calib3d.hpp>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include "opencv2/nonfree/nonfree.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#define Target_Octave 1 //! select subset of features for building similarity table
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
struct BiNode
|
||||
{
|
||||
int preNo;
|
||||
int curNo;
|
||||
};
|
||||
|
||||
struct Quadra
|
||||
{
|
||||
Point2d centroid;
|
||||
Size imgSize;
|
||||
// Point2d nodes[4];
|
||||
Point2d RME;
|
||||
};
|
||||
|
||||
struct Keys
|
||||
{
|
||||
vector<Point2d> pts;
|
||||
Mat descriptors;
|
||||
};
|
||||
|
||||
// ============== NOTIFICATION =============== //
|
||||
//! node is encoded from 0, 2, ..., n-1. //
|
||||
//! cost graph: cost of non-overlap pair is -1 //
|
||||
// =========================================== //
|
||||
|
||||
#define Load_Matches 0 //! just for debugging
|
||||
|
||||
class TopoFinder
|
||||
{
|
||||
public:
|
||||
TopoFinder(PointMatcher *matcher)
|
||||
{
|
||||
_Ptmatcher = matcher;
|
||||
_imgNum = _Ptmatcher->_imgSizeList.size();
|
||||
_shotNum = _attempNum = 0;
|
||||
_totalTime = _matchTime = 0;
|
||||
_isInOrder = false;
|
||||
};
|
||||
~TopoFinder(){};
|
||||
|
||||
public:
|
||||
//! return the topology depicted as a cost/weight table
|
||||
Mat_<double> findTopology(bool shallLoad, bool isInOrder);
|
||||
Mat_<int> loadSimilarityMat();
|
||||
void saveSimilarityMat(const Mat_<int> &similarityMat);
|
||||
//! similarity value : number of matched features between image pair
|
||||
Mat_<int> detectSimilarityOnGlobal();
|
||||
Mat_<int> detectSimilarityByGuiding();
|
||||
void searchMainChain();
|
||||
void buildMainChain();
|
||||
//! detect potential overlaps and recalculate aligning model
|
||||
void detectPotentialOverlap(int curIndex, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2);
|
||||
//! vocabulary tree -> association/guiding table
|
||||
Mat_<double> getGuidingTable(); //! not implemented
|
||||
Mat_<double> getGuidingTableP(); //! select features extracted from the top octave
|
||||
|
||||
int findNodeIndex(int imgNo);
|
||||
//! X1 = Model * X2
|
||||
Mat_<double> findFastAffine(vector<Point2d> pointSet1, vector<Point2d> pointSet2);
|
||||
void loadKeyFiles();
|
||||
bool featureMatcher(int imgIndex1, int imgIndex2, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2);
|
||||
int calSimilarNum(int imgIndex1, int imgIndex2);
|
||||
//! temperate functions
|
||||
void drawTopoNet();
|
||||
Rect TsetImageSize();
|
||||
void TsaveMosaicImage();
|
||||
void drawTreeLevel();
|
||||
|
||||
private:
|
||||
int _imgNum;
|
||||
Mat_<int> _similarityMat;
|
||||
Mat_<uchar> _attempMap; //! only for unordered mode : 1 means attempted already
|
||||
bool _isInOrder;
|
||||
|
||||
vector<TreeNode> _visitOrder0; //! the alignment order
|
||||
vector<Mat_<double> > _affineMatList; //! same order with "_visitOrder0"
|
||||
vector<Mat_<double> > _covMatrixList;
|
||||
vector<Quadra> _projCoordSet; //! same order with "_visitOrder0"
|
||||
PointMatcher *_Ptmatcher;
|
||||
vector<Keys> _keyList; //! same with image no.
|
||||
vector<vector<int> > _subKeyIndexList; //! subset for building similarity table
|
||||
//! variables for efficiency analysis
|
||||
int _attempNum, _shotNum;
|
||||
int _totalTime, _matchTime;
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
PROJECT(Utils)
|
||||
STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_CAPITALIZED)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
|
||||
ADD_DEFINITIONS(-DUNICODE)
|
||||
|
||||
#Use MFC in a Shared DLL
|
||||
ADD_DEFINITIONS(-D_AFXDLL)
|
||||
SET(CMAKE_MFC_FLAG 2)
|
||||
|
||||
FILE(GLOB_RECURSE HDRS_FILES *.h *.hpp)
|
||||
FILE(GLOB_RECURSE SRCS_FILES *.cpp)
|
||||
FILE(GLOB_RECURSE UI_FILES *.ui)
|
||||
FILE(GLOB CD_FILES *.cd)
|
||||
|
||||
|
||||
SET(FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${SRCS_FILES} ${UI_FILES} ${HDRS_FILES} PARENT_SCOPE)
|
||||
|
||||
SOURCE_GROUP("UI Files" FILES ${UI_FILES})
|
||||
SOURCE_GROUP("Generated Files" FILES ${MOC_SRCS} ${UI_HDRS} ${RSC_SRCS})
|
||||
SOURCE_GROUP("Class Diagrams" FILES ${CD_FILES} )
|
||||
#SOURCE_GROUP("Resources" FILES ${RSCS} )
|
||||
|
||||
ADD_LIBRARY(${PROJECT_NAME} STATIC ${HDRS_FILES} ${SRCS_FILES} ${UI_HDRS} ${UI_FILES} ${RSC_SRCS} ${MOC_SRCS} ${CD_FILES})
|
||||
#ADD_DEPENDENCIES(${PROJECT_NAME})
|
||||
SET_SOURCE_FILES_PROPERTIES(${CD_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) # DO NOT COMPILE CS FILES
|
||||
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS} libf2cd.lib BLASd.lib clapackd.lib tmglibd.lib levmar.lib)
|
||||
|
||||
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES FOLDER SRC)
|
||||
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
|
@ -0,0 +1,215 @@
|
||||
#include "util.h"
|
||||
|
||||
vector<string> Utils::get_filelist(string foldname)
|
||||
{
|
||||
string mainPath = foldname;
|
||||
foldname += "/*.*";
|
||||
const char * mystr=foldname.c_str();
|
||||
vector<string> flist;
|
||||
string lineStr;
|
||||
vector<string> extendName;
|
||||
extendName.push_back("jpg");
|
||||
extendName.push_back("png");
|
||||
extendName.push_back("tif");
|
||||
extendName.push_back("JPG");
|
||||
extendName.push_back("bmp");
|
||||
|
||||
HANDLE file;
|
||||
WIN32_FIND_DATA fileData;
|
||||
char line[1024];
|
||||
wchar_t fn[1000];
|
||||
mbstowcs(fn,mystr,999);
|
||||
file = FindFirstFile(fn, &fileData);
|
||||
FindNextFile(file, &fileData);
|
||||
while(FindNextFile(file, &fileData))
|
||||
{
|
||||
wcstombs(line,(const wchar_t*)fileData.cFileName,259);
|
||||
lineStr = line;
|
||||
for (int i = 0; i < 5; i ++) //排除非图像文件
|
||||
{
|
||||
if (lineStr.find(extendName[i]) < 999)
|
||||
{
|
||||
lineStr = mainPath + "/" + lineStr;
|
||||
flist.push_back(lineStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cout<<"loaded "<<flist.size()<<" files"<<endl;
|
||||
return flist;
|
||||
}
|
||||
|
||||
|
||||
Mat Utils::grayToPesudoColor(Mat grayMap)
|
||||
{
|
||||
//! 红 255, 0, 0 -> 255
|
||||
//! 橙 255, 127, 0 -> 204
|
||||
//! 黄 255, 255, 0 -> 153
|
||||
//! 绿 0, 255, 0 -> 102
|
||||
//! 青 0, 255, 255 -> 51
|
||||
//! 蓝 0, 0, 255 -> 0
|
||||
int row = grayMap.rows, col = grayMap.cols;
|
||||
Mat colorMap(row, col, CV_8UC3, Scalar(0,0,0));
|
||||
uchar *dataPtr = (uchar*)grayMap.data;
|
||||
uchar *dataPtrT = (uchar*)colorMap.data;
|
||||
for (int i = 0; i < row; i ++)
|
||||
{
|
||||
for (int j = 0; j < col; j ++)
|
||||
{
|
||||
int pix = dataPtr[i*col+j];
|
||||
int B = 0, G = 0, R = 0;
|
||||
if (pix <= 51)
|
||||
{
|
||||
B = 255;
|
||||
G = pix*5;
|
||||
R = 0;
|
||||
}
|
||||
else if (pix <= 102)
|
||||
{
|
||||
pix-=51;
|
||||
B = 255-pix*5;
|
||||
G = 255;
|
||||
R = 0;
|
||||
}
|
||||
else if (pix <= 153)
|
||||
{
|
||||
pix-=102;
|
||||
B = 0;
|
||||
G = 255;
|
||||
R = pix*5;
|
||||
}
|
||||
else if (pix <= 204)
|
||||
{
|
||||
pix-=153;
|
||||
B = 0;
|
||||
G = 255-uchar(128.0*pix/51.0+0.5);
|
||||
R = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
pix-=204;
|
||||
B = 0;
|
||||
G = 127-uchar(127.0*pix/51.0+0.5);
|
||||
R = 255;
|
||||
}
|
||||
dataPtrT[3*(i*col+j)+0] = B;
|
||||
dataPtrT[3*(i*col+j)+1] = G;
|
||||
dataPtrT[3*(i*col+j)+2] = R;
|
||||
//colorMap.at<Vec3b>(i,j)[0] = B;
|
||||
//colorMap.at<Vec3b>(i,j)[1] = G;
|
||||
//colorMap.at<Vec3b>(i,j)[2] = R;
|
||||
}
|
||||
}
|
||||
return colorMap;
|
||||
}
|
||||
|
||||
|
||||
bool Utils::loadMatchPts(int imgIndex1, int imgIndex2, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2)
|
||||
{
|
||||
bool exchanged = false;
|
||||
if (imgIndex1 > imgIndex2) //set a consistent standard: smaller index in the left
|
||||
{
|
||||
int temp = imgIndex2;
|
||||
imgIndex2 = imgIndex1;
|
||||
imgIndex1 = temp;
|
||||
exchanged = true;
|
||||
}
|
||||
char fileName[1024];
|
||||
sprintf(fileName, "Cache/matchPtfile/match%d&%d.txt", imgIndex1, imgIndex2);
|
||||
string filePath = Utils::baseDir + string(fileName);
|
||||
FILE *fin = fopen(filePath.c_str(), "r");
|
||||
if (fin == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int PtNum = 0;
|
||||
fscanf(fin, "%d", &PtNum);
|
||||
if (!exchanged)
|
||||
{
|
||||
for (int i = 0; i < PtNum; i ++)
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
fscanf(fin, "%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
|
||||
Point2d point1(x1,y1), point2(x2,y2);
|
||||
pointSet1.push_back(point1);
|
||||
pointSet2.push_back(point2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < PtNum; i ++)
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
fscanf(fin, "%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
|
||||
Point2d point1(x1,y1), point2(x2,y2);
|
||||
pointSet1.push_back(point2);
|
||||
pointSet2.push_back(point1);
|
||||
}
|
||||
}
|
||||
fclose(fin);
|
||||
// cout<<"Loaded "<<pointSet1.size()<<" points between image "<<imgIndex1<<" and image "<<imgIndex2<<endl;
|
||||
}
|
||||
|
||||
|
||||
Mat_<double> Utils::buildCostGraph(const Mat_<int> &similarMat)
|
||||
{
|
||||
int nodeNum = similarMat.rows;
|
||||
//! considering the precise and robustness, we take logarithm as the weight function
|
||||
Mat_<double> costGraph = Mat(nodeNum, nodeNum, CV_64FC1, Scalar(-1));
|
||||
for (int i = 0; i < nodeNum-1; i ++)
|
||||
{
|
||||
for (int j = i+1; j < nodeNum; j ++)
|
||||
{
|
||||
int num = similarMat(i,j);
|
||||
if (num == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
double cost = 6/log(num+50.0);
|
||||
costGraph(i,j) = cost;
|
||||
costGraph(j,i) = cost;
|
||||
}
|
||||
}
|
||||
return costGraph;
|
||||
}
|
||||
|
||||
|
||||
Point2d Utils::pointTransform(Mat_<double> homoMat, Point2d srcPt)
|
||||
{
|
||||
Mat_<double> srcX = (Mat_<double>(3,1)<< srcPt.x, srcPt.y, 1);
|
||||
Mat_<double> dstX = homoMat * srcX;
|
||||
Point2d dstPt = Point2d(dstX(0)/dstX(2), dstX(1)/dstX(2));
|
||||
return dstPt;
|
||||
}
|
||||
|
||||
|
||||
void Utils::pointTransform(Mat_<double> homoMat, Point2d srcPt, Point2d &dstPt)
|
||||
{
|
||||
Mat_<double> srcX = (Mat_<double>(3,1)<< srcPt.x, srcPt.y, 1);
|
||||
Mat_<double> dstX = homoMat * srcX;
|
||||
dstPt = Point2d(dstX(0)/dstX(2), dstX(1)/dstX(2));
|
||||
}
|
||||
|
||||
|
||||
void Utils::pointTransform(Mat_<double> homoMat, vector<Point2d> &pointSet)
|
||||
{
|
||||
for (int i = 0; i < pointSet.size(); i ++)
|
||||
{
|
||||
Mat_<double> srcX = (Mat_<double>(3,1)<< pointSet[i].x, pointSet[i].y, 1);
|
||||
Mat_<double> dstX = homoMat * srcX;
|
||||
Point2d dstPt = Point2d(dstX(0)/dstX(2), dstX(1)/dstX(2));
|
||||
pointSet[i] = dstPt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double Utils::calPointDist(Point2d point1, Point2d point2)
|
||||
{
|
||||
return sqrt((point1.x-point2.x)*(point1.x-point2.x) + (point1.y-point2.y)*(point1.y-point2.y));
|
||||
}
|
||||
|
||||
|
||||
double Utils::calVecDot(Point2d vec1, Point2d vec2)
|
||||
{
|
||||
return vec1.x*vec2.x+vec1.y*vec2.y;
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <Windows.h>
|
||||
#include "cv.h"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
// ********** global variable list ********** //
|
||||
static string baseDir = "C:/Users/Richard/Desktop/AutoMosaic/Source/Data/";
|
||||
|
||||
struct TreeNode
|
||||
{
|
||||
TreeNode(){};
|
||||
TreeNode(int im, int re, int le)
|
||||
{
|
||||
imgNo = im;
|
||||
refNo = re;
|
||||
level = le;
|
||||
};
|
||||
|
||||
int level; //! the level of node in the tree
|
||||
int imgNo; //! node no.
|
||||
int refNo; //! parent node no.
|
||||
};
|
||||
|
||||
vector<string> get_filelist(string foldname);
|
||||
Mat_<double> buildCostGraph(const Mat_<int> &similarMat);
|
||||
bool loadMatchPts(int imgIndex1, int imgIndex2, vector<Point2d> &pointSet1, vector<Point2d> &pointSet2);
|
||||
Point2d pointTransform(Mat_<double> homoMat, Point2d srcPt);
|
||||
void pointTransform(Mat_<double> homoMat, Point2d srcPt, Point2d &dstPt);
|
||||
void pointTransform(Mat_<double> homoMat, vector<Point2d> &pointSet);
|
||||
double calPointDist(Point2d point1, Point2d point2);
|
||||
double calVecDot(Point2d vec1, Point2d vec2);
|
||||
//! convert gray image to pesudo-color image
|
||||
Mat grayToPesudoColor(Mat grayMap);
|
||||
}
|
Binary file not shown.
Loading…
Reference in new issue