Merge pull request #1 from OpenDroneMap/gh-pages

Merge gh-pages cleanup to our fork.

Former-commit-id: f31460b95e
gh-pages
deltafactory 2016-05-13 16:05:04 -04:00
commit 1f37dc3e3e
89 zmienionych plików z 11552 dodań i 10957 usunięć

Wyświetl plik

@ -1 +0,0 @@
Dockerfile

16
.gitignore vendored
Wyświetl plik

@ -1,16 +0,0 @@
*~
bin/
include/
lib/
logs/
share/
src/
cmvs.tar.gz
parallel.tar.bz2
LAStools.zip
pcl.tar.gz
ceres-solver.tar.gz
*.pyc
pcl.tar.gz
opencv.zip

3
.gitmodules vendored
Wyświetl plik

@ -1,3 +0,0 @@
[submodule "src/bundler"]
path = src/bundler
url = https://github.com/chris-cooper/bundler_sfm

1
CNAME 100644
Wyświetl plik

@ -0,0 +1 @@
opendronemap.org

Wyświetl plik

@ -1,45 +0,0 @@
FROM ubuntu:14.04
MAINTAINER Danilo Bargen <mail@dbrgn.ch>
# Env variables
ENV DEBIAN_FRONTEND noninteractive
# Install dependencies
RUN apt-get update \
&& apt-get install -y --install-recommends \
build-essential cmake g++ gcc gFortran perl git autoconf \
curl wget \
unzip \
imagemagick jhead proj-bin libproj-dev\
libjpeg-dev libboost-all-dev libgsl0-dev libx11-dev libxext-dev liblapack-dev \
libeigen3-dev libflann-dev libvtk5-dev libqhull-dev libusb-1.0-0-dev\
libjson-perl \
libzip-dev \
libswitch-perl \
libcv-dev libcvaux-dev libopencv-dev \
libgoogle-glog-dev libatlas-base-dev libsuitesparse-dev \
&& apt-get autoremove \
&& apt-get clean
# Add users
RUN useradd -m -U odm
# Prepare directories
RUN mkdir /code
WORKDIR /code
# Add repository files
ADD . /code/
# Update submodules
RUN git submodule init && git submodule update
# Build OpenDroneMap
RUN ./install.sh && \
chown -R odm:odm /code
USER odm
# Entry point
VOLUME ["/images"]
WORKDIR /images
ENTRYPOINT ["/code/run.py"]

Plik binarny nie jest wyświetlany.

160
README.md
Wyświetl plik

@ -1,158 +1,4 @@
![](https://opendronemap.github.io/OpenDroneMap/img/odm_image.png)
OpenDroneMap
============
What is it?
===========
OpenDroneMap is an open source toolkit for processing aerial drone imagery. Typical drones use simple point-and-shoot cameras, so the images from drones, while from a different perspective, are similar to any pictures taken from point-and-shoot cameras, i.e. non-metric imagery. OpenDroneMap turns those simple images into three dimensional geographic data that can be used in combination with other geographic datasets.
In a word, OpenDroneMap is a toolchain for processing raw civilian UAS imagery to other useful products. What kind of products?
1. Point Clouds
2. Digital Surface Models
3. Textured Digital Surface Models
4. Orthorectified Imagery
5. Classified Point Clouds
6. Digital Elevation Models
7. etc.
So far, it does Point Clouds, Digital Surface Models, Textured Digital Surface Models, and Orthorectified Imagery.
Users' mailing list: http://lists.osgeo.org/cgi-bin/mailman/listinfo/opendronemap-users
Developer's mailing list: http://lists.osgeo.org/cgi-bin/mailman/listinfo/opendronemap-dev
Overview video: https://www.youtube.com/watch?v=0UctfoeNB_Y
Developers
=================
Help improve our software!
[![Join the chat at https://gitter.im/OpenDroneMap/OpenDroneMap](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OpenDroneMap/OpenDroneMap?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
1. Try to keep commits clean and simple
2. Submit a pull request with detailed changes and test results
Steps to get OpenDroneMap running:
==================================
(Requires Ubuntu 14.04 or later, see https://github.com/OpenDroneMap/odm_vagrant for running on Windows in a VM)
Support for Ubuntu 12.04 is currently BROKEN with the addition of OpenSfM and Ceres-Solver. We are working hard to get it working again in the future.
Run install.sh to build.
./install.sh
From a directory full of your images, run
./run.py
An overview of installing and running OpenDroneMap on Ubuntu can be found here: https://www.youtube.com/watch?v=e2qp3o8caPs
Here are some other videos:
- https://www.youtube.com/watch?v=7ZTufQkODLs (2015-01-30)
- https://www.youtube.com/watch?v=m0i4GQdfl8A (2015-03-15)
Now that texturing is in the code base, you can access the full textured meshes using MeshLab. Open MeshLab, choose `File:Import Mesh` and choose your textured mesh from a location similar to the following: `reconstruction-with-image-size-1200-results\odm_texturing\odm_textured_model.obj`
For Ubuntu 15.10 users, this will help you get running:
```
sudo apt-get install python-xmltodict
sudo ln -s /usr/lib/x86_64-linux-gnu/libproj.so.9 /usr/lib/libproj.so
```
---
Alternatively, you can also run OpenDroneMap in a Docker container:
export IMAGES=/absolute/path/to/your/images
docker build -t opendronemap:latest .
docker run -v $IMAGES:/images opendronemap:latest
To pass in custom parameters to the `run.py` script, simply pass it as arguments to the `docker run` command.
---
Example data can be found at https://github.com/OpenDroneMap/odm_data
---
Long term, the aim is for the toolchain to also be able to optionally push to a variety of online data repositories, pushing hi-resolution aerials to [OpenAerialMap](https://openaerialmap.org/), point clouds to [OpenTopography](http://opentopography.org/), and pushing digital elevation models to an emerging global repository (yet to be named...). That leaves only digital surface model meshes and UV textured meshes with no global repository home.
---
Documentation:
==============
For documentation, please take a look at our [wiki](https://github.com/OpenDroneMap/OpenDroneMap/wiki).
Troubleshooting:
================
Make sure you have enough RAM and CPU. Only lowercase file extension supported now.
If you run ODM with your own camera, it is possible you will see something like this:
```
- configuration:
--cmvs-maxImages: 500
--end-with: pmvs
--match-size: 200
--matcher-ratio: 0.6
--matcher-threshold: 2
--pmvs-csize: 2
--pmvs-level: 1
--pmvs-minImageNum: 3
--pmvs-threshold: 0.7
--pmvs-wsize: 7
--resize-to: 1200
--start-with: resize
- source files - Fri Sep 19 13:47:42 UTC 2014
no CCD width or focal length found for DSC05391.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05392.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05393.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05394.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05395.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05396.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05397.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05398.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05399.JPG - camera: "SONY DSC-HX5V"
found no usable images - quitting
Died at ../../OpenDroneMap/./run.pl line 364.
```
~~This means that your camera is not in the database, https://github.com/OpenDroneMap/OpenDroneMap/blob/gh-pages/ccd_defs.json~~
~~This problem is easily remedied. We need to know CCD size in the camera. We'll get these for our Sony Cyber-shot DSC-HX5 from dpreview: http://www.dpreview.com/products/sony/compacts/sony_dschx5/specifications~~
~~So, we'll add the following line to our ccd_defs.json:~~
~~"SONY DSC-HX5V": 6.104,~~
~~To check that ccd_defs.json compiles, run `ccd_defs_check.py`~~
~~If it prints the message 'CCD_DEFS compiles OK', then you can commit your changes.~~
~~And so others can use it, we'll do a pull request to add it to our array for everyone else.~~
See issue [#237](https://github.com/OpenDroneMap/OpenDroneMap/issues/237). OpenSfM uses its own sensor reference file, which you can find in the OpenSfM directory under `opensfm/data/`.
---
Maintainers can run the ccd_defs.json compilation test automatically by creating a
symbolic link in .git/hooks to hooks/pre-commit
cd .git/hooks
ln -s ../../hooks/pre-commit
If ccd_defs.json does not compile, then the pre-commit hook will abort the commit.
Hosting for [OpenDroneMap](https://opendronemap.org)

Wyświetl plik

@ -1,339 +0,0 @@
{
"Apple iPhone 5s": 8.46,
"Asahi Optical Co.,Ltd. PENTAX Optio330RS": 7.176,
"Canon Canon IXUS 240 HS": 6.17,
"Canon Canon DIGITAL IXUS 400": 7.176,
"Canon Canon DIGITAL IXUS 40": 5.76,
"Canon Canon DIGITAL IXUS 430": 6.18,
"Canon Canon DIGITAL IXUS 500": 7.176,
"Canon Canon DIGITAL IXUS 50": 5.76,
"Canon Canon DIGITAL IXUS 55": 5.76,
"Canon Canon DIGITAL IXUS 60": 5.76,
"Canon Canon DIGITAL IXUS 65": 5.76,
"Canon Canon DIGITAL IXUS 700": 7.176,
"Canon Canon DIGITAL IXUS 750": 7.176,
"Canon Canon DIGITAL IXUS 800 IS": 5.76,
"Canon Canon DIGITAL IXUS II": 5.27,
"Canon Canon EOS 10D": 22.7,
"Canon Canon EOS-1D Mark II": 28.7,
"Canon Canon EOS-1Ds Mark II": 35.95,
"Canon Canon EOS 20D": 22.5,
"Canon Canon EOS 20D": 22.5,
"Canon Canon EOS 300D DIGITAL": 22.66,
"Canon Canon EOS 30D": 22.5,
"Canon Canon EOS 350D DIGITAL": 22.2,
"Canon Canon EOS 400D DIGITAL": 22.2,
"Canon Canon EOS 40D": 22.2,
"Canon Canon EOS 5D": 35.8,
"Canon Canon EOS 5D Mark II": 36.0,
"Canon Canon EOS 6D": 35.8,
"Canon Canon EOS DIGITAL REBEL": 22.66,
"Canon Canon EOS DIGITAL REBEL XT": 22.2,
"Canon Canon EOS DIGITAL REBEL XTi": 22.2,
"Canon Canon EOS Kiss Digital": 22.66,
"Canon Canon IXY DIGITAL 600": 7.176,
"Canon Canon PowerShot A10": 5.23,
"Canon Canon PowerShot A20": 7.176,
"Canon Canon PowerShot A400": 4.54,
"Canon Canon PowerShot A40": 5.27,
"Canon Canon PowerShot A510": 5.76,
"Canon Canon PowerShot A520": 5.76,
"Canon Canon PowerShot A530": 5.76,
"Canon Canon PowerShot A60": 5.27,
"Canon Canon PowerShot A620": 7.176,
"Canon Canon PowerShot A630": 7.176,
"Canon Canon PowerShot A640": 7.176,
"Canon Canon PowerShot A700": 5.76,
"Canon Canon PowerShot A70": 5.27,
"Canon Canon PowerShot A710 IS": 5.76,
"Canon Canon PowerShot A75": 5.27,
"Canon Canon PowerShot A80": 7.176,
"Canon Canon PowerShot A85": 5.27,
"Canon Canon PowerShot A95": 7.176,
"Canon Canon PowerShot G12": 7.44,
"Canon Canon PowerShot G1": 7.176,
"Canon Canon PowerShot G2": 7.176,
"Canon Canon PowerShot G3": 7.176,
"Canon Canon PowerShot G5": 7.176,
"Canon Canon PowerShot G6": 7.176,
"Canon Canon PowerShot G7": 7.176,
"Canon Canon PowerShot G9": 7.6,
"Canon Canon PowerShot Pro1": 8.8,
"Canon Canon PowerShot S90": 7.44,
"Canon Canon PowerShot S95": 7.44,
"Canon Canon PowerShot S100": 7.44,
"Canon Canon PowerShot S110": 7.44,
"Canon Canon PowerShot S120": 7.44,
"Canon Canon PowerShot S1 IS": 5.27,
"Canon Canon PowerShot S200": 5.27,
"Canon Canon PowerShot S2 IS": 5.76,
"Canon Canon PowerShot S30": 7.176,
"Canon Canon PowerShot S3 IS": 5.76,
"Canon Canon PowerShot S400": 7.176,
"Canon Canon PowerShot S40": 7.176,
"Canon Canon PowerShot S410": 7.176,
"Canon Canon PowerShot S45": 7.176,
"Canon Canon PowerShot S500": 7.176,
"Canon Canon PowerShot S50": 7.176,
"Canon Canon PowerShot S60": 7.176,
"Canon Canon PowerShot S70": 7.176,
"Canon Canon PowerShot S80": 7.176,
"Canon Canon PowerShot SD1000": 5.75,
"Canon Canon PowerShot SD100": 5.27,
"Canon Canon PowerShot SD10": 5.75,
"Canon Canon PowerShot SD110": 5.27,
"Canon Canon PowerShot SD200": 5.76,
"Canon Canon PowerShot SD300": 5.76,
"Canon Canon PowerShot SD400": 5.76,
"Canon Canon PowerShot SD450": 5.76,
"Canon Canon PowerShot SD500": 7.176,
"Canon Canon PowerShot SD550": 7.176,
"Canon Canon PowerShot SD600": 5.76,
"Canon Canon PowerShot SD630": 5.76,
"Canon Canon PowerShot SD700 IS": 5.76,
"Canon Canon PowerShot SD750": 5.75,
"Canon Canon PowerShot SD800 IS": 5.76,
"Canon Canon PowerShot SX260 HS": 6.2,
"Canon EOS 300D DIGITAL": 22.66,
"Canon EOS DIGITAL REBEL": 22.66,
"Canon PowerShot A510": 5.76,
"Canon PowerShot S30": 7.176,
"CASIO COMPUTER CO.,LTD. EX-S500": 5.76,
"CASIO COMPUTER CO.,LTD. EX-Z1000": 7.716,
"CASIO COMPUTER CO.,LTD EX-Z30": 5.76,
"CASIO COMPUTER CO.,LTD. EX-Z600": 5.76,
"CASIO COMPUTER CO.,LTD. EX-Z60": 7.176,
"CASIO COMPUTER CO.,LTD EX-Z750": 7.176,
"CASIO COMPUTER CO.,LTD. EX-Z850": 7.176,
"DJI FC300S": 6.16,
"DJI FC300X": 6.2,
"DJI FC350": 6.17,
"DJI PHANTOM VISION FC200": 6.17,
"EASTMAN KODAK COMPANY KODAK CX7330 ZOOM DIGITAL CAMERA": 5.27,
"EASTMAN KODAK COMPANY KODAK CX7530 ZOOM DIGITAL CAMERA": 5.76,
"EASTMAN KODAK COMPANY KODAK DX3900 ZOOM DIGITAL CAMERA": 7.176,
"EASTMAN KODAK COMPANY KODAK DX4900 ZOOM DIGITAL CAMERA": 7.176,
"EASTMAN KODAK COMPANY KODAK DX6340 ZOOM DIGITAL CAMERA": 5.27,
"EASTMAN KODAK COMPANY KODAK DX6490 ZOOM DIGITAL CAMERA": 5.76,
"EASTMAN KODAK COMPANY KODAK DX7630 ZOOM DIGITAL CAMERA": 7.176,
"EASTMAN KODAK COMPANY KODAK Z650 ZOOM DIGITAL CAMERA": 5.76,
"EASTMAN KODAK COMPANY KODAK Z700 ZOOM DIGITAL CAMERA": 5.76,
"EASTMAN KODAK COMPANY KODAK Z740 ZOOM DIGITAL CAMERA": 5.76,
"FUJIFILM FinePix2600Zoom": 5.27,
"FUJIFILM FinePix40i": 7.6,
"FUJIFILM FinePix A310": 5.27,
"FUJIFILM FinePix A330": 5.27,
"FUJIFILM FinePix A600": 7.6,
"FUJIFILM FinePix E500": 5.76,
"FUJIFILM FinePix E510": 5.76,
"FUJIFILM FinePix E550": 7.6,
"FUJIFILM FinePix E900": 7.78,
"FUJIFILM FinePix F10": 7.6,
"FUJIFILM FinePix F30": 7.6,
"FUJIFILM FinePix F450": 5.76,
"FUJIFILM FinePix F601 ZOOM": 7.6,
"FUJIFILM FinePix S3Pro": 23,
"FUJIFILM FinePix S5000": 5.27,
"FUJIFILM FinePix S5200": 5.76,
"FUJIFILM FinePix S5500": 5.27,
"FUJIFILM FinePix S6500fd": 7.6,
"FUJIFILM FinePix S7000": 7.6,
"FUJIFILM FinePix Z2": 5.76,
"Garmin VIRB": 6.17,
"GoPro HD2 U": 5.8,
"Gopro HD3": 5.76,
"GoPro HERO4 Black": 6.17,
"GoPro HERO4 Silver":6.17,
"GoPro HERO4 S":6.17,
"Hewlett-Packard hp 635 Digital Camera": 4.54,
"Hewlett-Packard hp PhotoSmart 43x series": 5.27,
"Hewlett-Packard HP PhotoSmart 618 (V1.1)": 5.27,
"Hewlett-Packard HP PhotoSmart C945 (V01.61)": 7.176,
"Hewlett-Packard HP PhotoSmart R707 (V01.00)": 7.176,
"KONICA MILOLTA DYNAX 5D": 23.5,
"Konica Minolta Camera, Inc. DiMAGE A2": 8.8,
"KONICA MINOLTA CAMERA, Inc. DiMAGE G400": 5.76,
"Konica Minolta Camera, Inc. DiMAGE Z2": 5.76,
"KONICA MINOLTA DiMAGE A200": 8.8,
"KONICA MINOLTA DiMAGE X1": 7.176,
"KONICA MINOLTA DYNAX 5D": 23.5,
"Minolta Co., Ltd. DiMAGE F100": 7.176,
"Minolta Co., Ltd. DiMAGE Xi": 5.27,
"Minolta Co., Ltd. DiMAGE Xt": 5.27,
"Minolta Co., Ltd. DiMAGE Z1": 5.27,
"Mobius Action Cam": 2.1,
"NIKON COOLPIX L3": 5.76,
"NIKON COOLPIX P2": 7.176,
"NIKON COOLPIX P7700": 7.44,
"NIKON COOLPIX S4": 5.76,
"NIKON COOLPIX S7c": 5.76,
"NIKON COOLPIX S8000": 6.17,
"NIKON CORPORATION NIKON 1 J4": 13.2,
"NIKON CORPORATION NIKON D100": 23.7,
"NIKON CORPORATION NIKON D1": 23.7,
"NIKON CORPORATION NIKON D1H": 23.7,
"NIKON CORPORATION NIKON D200": 23.6,
"NIKON CORPORATION NIKON D2H": 23.3,
"NIKON CORPORATION NIKON D2X": 23.7,
"NIKON CORPORATION NIKON D40": 23.7,
"NIKON CORPORATION NIKON D50": 23.7,
"NIKON CORPORATION NIKON D60": 23.6,
"NIKON CORPORATION NIKON D700": 36,
"NIKON CORPORATION NIKON D70": 23.7,
"NIKON CORPORATION NIKON D70s": 23.7,
"NIKON CORPORATION NIKON D80": 23.6,
"NIKON CORPORATION NIKON D5300": 23.5,
"NIKON D5100": 23.6,
"NIKON E2500": 5.27,
"NIKON E3100": 5.27,
"NIKON E3200": 5.27,
"NIKON E3700": 5.27,
"NIKON E4200": 7.176,
"NIKON E4300": 7.18,
"NIKON E4500": 7.176,
"NIKON E4600": 5.76,
"NIKON E5000": 8.8,
"NIKON E5200": 7.176,
"NIKON E5400": 7.176,
"NIKON E5600": 5.76,
"NIKON E5700": 8.8,
"NIKON E5900": 7.176,
"NIKON E7600": 7.176,
"NIKON E775": 5.27,
"NIKON E7900": 7.176,
"NIKON E8800": 8.8,
"NIKON E990": 7.176,
"NIKON E995": 7.176,
"NIKON S1": 5.76,
"Nokia N80": 5.27,
"Nokia N93": 4.536,
"Nokia N95": 5.7,
"OLYMPUS CORPORATION C-5000Z": 7.176,
"OLYMPUS CORPORATION C5060WZ": 7.176,
"OLYMPUS CORPORATION C750UZ": 5.27,
"OLYMPUS CORPORATION C765UZ": 5.76,
"OLYMPUS CORPORATION C8080WZ": 8.8,
"OLYMPUS CORPORATION X250,D560Z,C350Z": 5.76,
"OLYMPUS CORPORATION X-3,C-60Z": 7.176,
"OLYMPUS CORPORATION X400,D580Z,C460Z": 5.27,
"OLYMPUS IMAGING CORP. E-500": 17.3,
"OLYMPUS IMAGING CORP. E-510": 17.3,
"OLYMPUS IMAGING CORP. FE115,X715": 5.76,
"OLYMPUS IMAGING CORP. SP310": 7.176,
"OLYMPUS IMAGING CORP. SP510UZ": 5.75,
"OLYMPUS IMAGING CORP. SP550UZ": 5.76,
"OLYMPUS IMAGING CORP. uD600,S600": 5.75,
"OLYMPUS_IMAGING_CORP. X450,D535Z,C370Z": 5.27,
"OLYMPUS IMAGING CORP. X550,D545Z,C480Z": 5.76,
"Olympus E-M10": 17.3,
"Olympus E-PL5": 17.3,
"Olympus E-PL6": 17.3,
"OLYMPUS OPTICAL CO.,LTD C2040Z": 6.4,
"OLYMPUS OPTICAL CO.,LTD C211Z": 5.27,
"OLYMPUS OPTICAL CO.,LTD C2Z,D520Z,C220Z": 4.54,
"OLYMPUS OPTICAL CO.,LTD C3000Z": 7.176,
"OLYMPUS OPTICAL CO.,LTD C300Z,D550Z": 5.4,
"OLYMPUS OPTICAL CO.,LTD C4100Z,C4000Z": 7.176,
"OLYMPUS OPTICAL CO.,LTD C750UZ": 5.27,
"OLYMPUS OPTICAL CO.,LTD X-2,C-50Z": 7.176,
"OLYMPUS SP550UZ": 5.76,
"OLYMPUS X100,D540Z,C310Z": 5.27,
"Panasonic DMC-GH4": 17.3,
"Panasonic DMC-FX01": 5.76,
"Panasonic DMC-FX07": 5.75,
"Panasonic DMC-FX9": 5.76,
"Panasonic DMC-FZ20": 5.76,
"Panasonic DMC-FZ2": 4.54,
"Panasonic DMC-FZ30": 7.176,
"Panasonic DMC-FZ50": 7.176,
"Panasonic DMC-FZ5": 5.76,
"Panasonic DMC-FZ7": 5.76,
"Panasonic DMC-LC1": 8.8,
"Panasonic DMC-LC33": 5.76,
"Panasonic DMC-LX1": 8.5,
"Panasonic DMC-LZ2": 5.76,
"Panasonic DMC-TS4": 6.08,
"Panasonic DMC-TZ1": 5.75,
"Panasonic DMC-TZ3": 5.68,
"Panasonic DMC-TZ5": 6.12,
"PENTAX Corporation PENTAX *ist DL": 23.5,
"PENTAX Corporation PENTAX *ist DS2": 23.5,
"PENTAX Corporation PENTAX *ist DS": 23.5,
"PENTAX Corporation PENTAX K100D": 23.5,
"PENTAX Corporation PENTAX Optio 450": 7.176,
"PENTAX Corporation PENTAX Optio 550": 7.176,
"PENTAX Corporation PENTAX Optio E10": 5.76,
"PENTAX Corporation PENTAX Optio S40": 5.76,
"PENTAX Corporation PENTAX Optio S4": 5.76,
"PENTAX Corporation PENTAX Optio S50": 5.76,
"PENTAX Corporation PENTAX Optio S5i": 5.76,
"PENTAX Corporation PENTAX Optio S5z": 5.76,
"PENTAX Corporation PENTAX Optio SV": 5.76,
"PENTAX Corporation PENTAX Optio WP": 5.75,
"PHANTOM VISION FC200": 6.17,
"Ricoh GR": 23.7,
"RICOH CaplioG3 modelM": 5.27,
"RICOH Caplio GX": 7.176,
"RICOH Caplio R30": 5.75,
"Samsung Digimax 301": 5.27,
"Samsung Techwin <Digimax i5, Samsung #1>": 5.76,
"Samsung NX1000": 23.5,
"Samsung NX1100": 23.5,
"Samsung NX2000": 23.5,
"Samsung NX3000": 23.5,
"Samsung NX3300": 23.5,
"Samsung NX300": 23.5,
"Samsung NX200": 23.5,
"Samsung NX210": 23.5,
"Samsung NX500": 23.5,
"Samsung NX1": 23.5,
"SAMSUNG TECHWIN Pro 815": 8.8,
"SONY A7": 35.9,
"SONY A7R": 35.9,
"SONY DSC-F828": 8.8,
"SONY DSC-H1": 6.104,
"SONY DSC-H2": 5.744,
"SONY DSC-H3": 5.744,
"SONY DSC-H5": 5.744,
"SONY DSC-H7": 5.744,
"SONY DSC-H9": 5.744,
"SONY DSC-HX5V": 6.104,
"SONY DSC-HX50V": 6.17,
"SONY DSC-N12": 7.176,
"SONY DSC-P100": 7.176,
"SONY DSC-P10": 7.176,
"SONY DSC-P12": 7.176,
"SONY DSC-P150": 7.176,
"SONY DSC-P200": 7.176,
"SONY DSC-P52": 5.27,
"SONY DSC-P72": 5.27,
"SONY DSC-P73": 5.27,
"SONY DSC-P8": 5.27,
"SONY DSC-R1": 21.5,
"SONY DSC-S40": 5.27,
"SONY DSC-S600": 5.76,
"SONY DSC-T9": 7.18,
"SONY DSC-V1": 7.176,
"SONY DSC-W1": 7.176,
"SONY DSC-W30": 5.76,
"SONY DSC-W50": 5.75,
"SONY DSC-W5": 7.176,
"SONY DSC-W7": 7.176,
"SONY DSC-W80": 5.75,
"SONY DSC-WX220": 7.70,
"SONY ILCE-7S": 35.8,
"SONY ILCE-5100": 23.5,
"SONY NEX-5T": 23.4,
"SONY NEX-5R": 23.4,
"SONY NEX-7": 23.5,
"SONY SLT-A55": 23.5,
"SONY SLT-A57": 23.5,
"SONY SLT-A65": 23.5,
"SONY SLT-A77": 23.5,
"SONY SLT-A77 II": 23.5,
"SONY SLT-A77V": 23.5,
"SONY SLT-A99": 35.8,
"Vexcel UltraCam": 28.00,
"Mantis i23": 45.00,
"XIAOYI YDXJ 1": 5.23
}

Wyświetl plik

@ -1,25 +0,0 @@
#!/usr/bin/python
import sys
import os
import json
BIN_PATH_ABS = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
def get_ccd_widths():
"""Return the CCD Width of the camera listed in the JSON defs file."""
with open(BIN_PATH_ABS + '/ccd_defs.json') as jsonFile:
return json.load(jsonFile)
try:
ccd_defs = get_ccd_widths()
print "CCD_DEFS compiles OK"
print "Definitions in file: {0}".format(len(ccd_defs))
exit_code=0
except IOError as e:
print "I/O error with CCD_DEFS file: {0}".format(e.strerror)
exit_code=255
except:
print "Error with CCD_DEFS file: {0}".format(sys.exc_info()[1])
exit_code=255
sys.exit(exit_code)

Wyświetl plik

@ -1 +0,0 @@
eb0db6a2b212050bf310777b777483fceb93d223

Wyświetl plik

@ -1 +0,0 @@
5d0d7d69bfdffaca7c4e8b0159a20e673401e437

Wyświetl plik

@ -1 +0,0 @@
154afb080db62672cee7440ba5ce584c3c73c1ac

Wyświetl plik

@ -1 +0,0 @@
0afb2f4a439712e56c0da06303fc17a9ed6e7eec

Wyświetl plik

@ -1 +0,0 @@
a624a735a0bd41bed9e202eb62d6c717c44d6a13

Wyświetl plik

@ -1 +0,0 @@
dff89e8c496ad01eb0786dd2fb23559110c2572f

Wyświetl plik

@ -1,15 +0,0 @@
# Contributor Code of Conduct
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.1.0, available at [http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/)

Wyświetl plik

@ -1,112 +0,0 @@
#!/usr/local/bin/perl
$filename_base = $ARGV[0];
$write_binary = 1;
$filename_src = $filename_base.".key.sift";
$filename_dest_bin = $filename_base.".key.bin";
$filename_dest_key = $filename_base.".key";
$filename_image = $filename_base.".pgm";
open (DEST_BIN, ">$filename_dest_bin");
open (DEST_KEY, ">$filename_dest_key");
open (SRC, "$filename_src");
$linecount = 0;
$linecount += tr/\n/\n/ while sysread(SRC, $_, 2 ** 16);
printf ("%d", $linecount);
if($write_binary){
seek(SRC, 0, 0);
print DEST_BIN pack("L", $linecount);
while ($record = <SRC>) {
@parts = split(/ /, $record);
if(@parts[3] > 3.141){
@parts[3] -= 6.282;
}
@parts[3] *= -1;
@tmp = @parts[0];
@parts[0] = @parts[1];
@parts[1] = @tmp;
for ($count = 4; $count < 132; $count += 8) {
@tmp = @parts[$count+7];
@parts[$count+7] = @parts[$count+1];
@parts[$count+1] = @tmp;
@tmp = @parts[$count+6];
@parts[$count+6] = @parts[$count+2];
@parts[$count+2] = @tmp;
@tmp = @parts[$count+3];
@parts[$count+3] = @parts[$count+5];
@parts[$count+5] = @tmp;
}
print DEST_BIN pack("f4 C128", @parts);
}
}
seek(SRC, 0, 0);
print DEST_KEY $linecount, " 128\n";
while ($record = <SRC>) {
@parts = split(/ /, $record);
$counter = 0;
if(@parts[3] > 3.141){
@parts[3] -= 6.282;
}
@parts[3] *= -1;
printf (DEST_KEY "%.3f %.3f %.3f %.3f", @parts[1], @parts[0], @parts[2], @parts[3]);
shift(@parts);
shift(@parts);
shift(@parts);
shift(@parts);
for ($count = 0; $count < 128; $count += 8) {
@tmp = @parts[$count+7];
@parts[$count+7] = @parts[$count+1];
@parts[$count+1] = @tmp;
@tmp = @parts[$count+6];
@parts[$count+6] = @parts[$count+2];
@parts[$count+2] = @tmp;
@tmp = @parts[$count+3];
@parts[$count+3] = @parts[$count+5];
@parts[$count+5] = @tmp;
}
foreach (@parts) {
if((($counter) % 20) == 0) {
print DEST_KEY "\n ";
} else {
if($counter != 0){
print DEST_KEY " ";
}
}
print DEST_KEY $_;
$counter++;
}
}
close(DEST_BIN);
close(DEST_KEY);
close(SRC);

3878
css/cartodb.css 100644

Plik diff jest za duży Load Diff

350
css/cssmenu.css 100644
Wyświetl plik

@ -0,0 +1,350 @@
#cssmenu {
position: relative;
height: 44px;
background: #2b2f3a;
width: auto;
}
#cssmenu ul {
list-style: none;
padding: 0;
margin: 0;
line-height: 1;
}
#cssmenu > ul {
position: relative;
display: block;
background: #2b2f3a;
width: 100%;
z-index: 500;
}
#cssmenu:after,
#cssmenu > ul:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
#cssmenu.align-right > ul > li {
float: right;
}
#cssmenu.align-center ul {
text-align: center;
}
#cssmenu.align-center ul ul {
text-align: left;
}
#cssmenu > ul > li {
display: inline-block;
position: relative;
margin: 0;
padding: 0;
}
#cssmenu > ul > #menu-button {
display: none;
}
#cssmenu ul li a {
display: block;
font-family: Helvetica, sans-serif;
text-decoration: none;
}
#cssmenu > ul > li > a {
font-size: 14px;
font-weight: bold;
padding: 15px 20px;
color: #7a8189;
text-transform: uppercase;
-webkit-transition: color 0.25s ease-out;
-moz-transition: color 0.25s ease-out;
-ms-transition: color 0.25s ease-out;
-o-transition: color 0.25s ease-out;
transition: color 0.25s ease-out;
}
#cssmenu > ul > li.has-sub > a {
padding-right: 32px;
}
#cssmenu > ul > li:hover > a {
color: #ffffff;
}
#cssmenu li.has-sub::after {
display: block;
content: "";
position: absolute;
width: 0;
height: 0;
}
#cssmenu > ul > li.has-sub::after {
right: 10px;
top: 20px;
border: 5px solid transparent;
border-top-color: #7a8189;
}
#cssmenu > ul > li:hover::after {
border-top-color: #ffffff;
}
#indicatorContainer {
position: absolute;
height: 12px;
width: 100%;
bottom: 0px;
overflow: hidden;
z-index: -1;
}
#pIndicator {
position: absolute;
height: 0;
width: 100%;
border: 12px solid transparent;
border-top-color: #2b2f3a;
z-index: -2;
-webkit-transition: left .25s ease;
-moz-transition: left .25s ease;
-ms-transition: left .25s ease;
-o-transition: left .25s ease;
transition: left .25s ease;
}
#cIndicator {
position: absolute;
height: 0;
width: 100%;
border: 12px solid transparent;
border-top-color: #2b2f3a;
top: -12px;
right: 100%;
z-index: -2;
}
#cssmenu ul ul {
position: absolute;
left: -9999px;
top: 70px;
opacity: 0;
-webkit-transition: opacity .3s ease, top .25s ease;
-moz-transition: opacity .3s ease, top .25s ease;
-ms-transition: opacity .3s ease, top .25s ease;
-o-transition: opacity .3s ease, top .25s ease;
transition: opacity .3s ease, top .25s ease;
z-index: 1000;
}
#cssmenu ul ul ul {
top: 37px;
padding-left: 5px;
}
#cssmenu ul ul li {
position: relative;
}
#cssmenu > ul > li:hover > ul {
left: auto;
top: 44px;
opacity: 1;
}
#cssmenu.align-right > ul > li:hover > ul {
left: auto;
right: 0;
opacity: 1;
}
#cssmenu ul ul li:hover > ul {
left: 170px;
top: 0;
opacity: 1;
}
#cssmenu.align-right ul ul li:hover > ul {
left: auto;
right: 170px;
top: 0;
opacity: 1;
padding-right: 5px;
}
#cssmenu ul ul li a {
width: 130px;
border-bottom: 1px solid #eeeeee;
padding: 10px 20px;
font-size: 12px;
color: #9ea2a5;
background: #ffffff;
-webkit-transition: all .35s ease;
-moz-transition: all .35s ease;
-ms-transition: all .35s ease;
-o-transition: all .35s ease;
transition: all .35s ease;
}
#cssmenu.align-right ul ul li a {
text-align: right;
}
#cssmenu ul ul li:hover > a {
background: #f2f2f2;
color: #8c9195;
}
#cssmenu ul ul li:last-child > a,
#cssmenu ul ul li.last > a {
border-bottom: 0;
}
#cssmenu > ul > li > ul::after {
content: '';
border: 6px solid transparent;
width: 0;
height: 0;
border-bottom-color: #ffffff;
position: absolute;
top: -12px;
left: 30px;
}
#cssmenu.align-right > ul > li > ul::after {
left: auto;
right: 30px;
}
#cssmenu ul ul li.has-sub::after {
border: 4px solid transparent;
border-left-color: #9ea2a5;
right: 10px;
top: 12px;
-moz-transition: all .2s ease;
-ms-transition: all .2s ease;
-o-transition: all .2s ease;
transition: all .2s ease;
-webkit-transition: -webkit-transform 0.2s ease, right 0.2s ease;
}
#cssmenu.align-right ul ul li.has-sub::after {
border-left-color: transparent;
border-right-color: #9ea2a5;
right: auto;
left: 10px;
}
#cssmenu ul ul li.has-sub:hover::after {
border-left-color: #ffffff;
right: -5px;
-webkit-transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
transform: rotateY(180deg);
}
#cssmenu.align-right ul ul li.has-sub:hover::after {
border-right-color: #ffffff;
border-left-color: transparent;
left: -5px;
-webkit-transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
transform: rotateY(180deg);
}
@media all and (max-width: 800px), only screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 1024px), only screen and (min--moz-device-pixel-ratio: 2) and (max-width: 1024px), only screen and (-o-min-device-pixel-ratio: 2/1) and (max-width: 1024px), only screen and (min-device-pixel-ratio: 2) and (max-width: 1024px), only screen and (min-resolution: 192dpi) and (max-width: 1024px), only screen and (min-resolution: 2dppx) and (max-width: 1024px) {
#cssmenu {
width: auto;
}
#cssmenu.align-center ul {
text-align: left;
}
#cssmenu.align-right > ul > li {
float: none;
}
#cssmenu ul {
width: auto;
}
#cssmenu .submenuArrow,
#cssmenu #indicatorContainer {
display: none;
}
#cssmenu > ul {
height: auto;
display: block;
}
#cssmenu > ul > li {
float: none;
}
#cssmenu li,
#cssmenu > ul > li {
display: none;
}
#cssmenu ul ul,
#cssmenu ul ul ul,
#cssmenu ul > li:hover > ul,
#cssmenu ul ul > li:hover > ul,
#cssmenu.align-right ul ul,
#cssmenu.align-right ul ul ul,
#cssmenu.align-right ul > li:hover > ul,
#cssmenu.align-right ul ul > li:hover > ul {
position: relative;
left: auto;
top: auto;
opacity: 1;
padding-left: 0;
padding-right: 0;
right: auto;
}
#cssmenu ul .has-sub::after {
display: none;
}
#cssmenu ul li a {
padding: 12px 20px;
}
#cssmenu ul ul li a {
border: 0;
background: none;
width: auto;
padding: 8px 35px;
}
#cssmenu.align-right ul ul li a {
text-align: left;
}
#cssmenu ul ul li:hover > a {
background: none;
color: #8c9195;
}
#cssmenu ul ul ul a {
padding: 8px 50px;
}
#cssmenu ul ul ul ul a {
padding: 8px 65px;
}
#cssmenu ul ul ul ul ul a {
padding: 8px 80px;
}
#cssmenu ul ul ul ul ul ul a {
padding: 8px 95px;
}
#cssmenu > ul > #menu-button {
display: block;
cursor: pointer;
}
#cssmenu #menu-button > a {
padding: 14px 20px;
}
#cssmenu ul.open li,
#cssmenu > ul.open > li {
display: block;
}
#cssmenu > ul.open > li#menu-button > a {
color: #fff;
border-bottom: 1px solid rgba(150, 150, 150, 0.1);
}
#cssmenu ul ul::after {
display: none;
}
#cssmenu #menu-button::after {
display: block;
content: '';
position: absolute;
height: 3px;
width: 22px;
border-top: 2px solid #7a8189;
border-bottom: 2px solid #7a8189;
right: 20px;
top: 15px;
}
#cssmenu #menu-button::before {
display: block;
content: '';
position: absolute;
height: 3px;
width: 22px;
border-top: 2px solid #7a8189;
right: 20px;
top: 25px;
}
#cssmenu ul.open #menu-button::after,
#cssmenu ul.open #menu-button::before {
border-color: #fff;
}
}

355
css/cssmenu2.css 100644
Wyświetl plik

@ -0,0 +1,355 @@
#cssmenu2 {
position: relative;
height: 44px;
background: #2b2f3a;
width: 200px;
margin:0 auto;
margin-top:30px;
}
#cssmenu2 ul {
list-style: none;
padding: 0;
margin: 0;
line-height: 1;
}
#cssmenu2 > ul {
position: relative;
display: block;
background: #2b2f3a;
width: 100%;
z-index: 500;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px;
}
#cssmenu2:after,
#cssmenu2 > ul:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
#cssmenu2.align-right > ul > li {
float: right;
}
#cssmenu2.align-center ul {
text-align: center;
}
#cssmenu2.align-center ul ul {
text-align: left;
}
#cssmenu2 > ul > li {
display: inline-block;
position: relative;
margin: 0;
padding: 0;
}
#cssmenu2 > ul > #menu-button {
display: none;
}
#cssmenu2 ul li a {
display: block;
font-family: Helvetica, sans-serif;
text-decoration: none;
}
#cssmenu2 > ul > li > a {
font-size: 14px;
font-weight: bold;
padding: 15px 20px;
color: #7a8189;
text-transform: uppercase;
-webkit-transition: color 0.25s ease-out;
-moz-transition: color 0.25s ease-out;
-ms-transition: color 0.25s ease-out;
-o-transition: color 0.25s ease-out;
transition: color 0.25s ease-out;
}
#cssmenu2 > ul > li.has-sub > a {
padding-right: 32px;
}
#cssmenu2 > ul > li:hover > a {
color: #ffffff;
}
#cssmenu2 li.has-sub::after {
display: block;
content: "";
position: absolute;
width: 0;
height: 0;
}
#cssmenu2 > ul > li.has-sub::after {
right: 10px;
top: 20px;
border: 5px solid transparent;
border-top-color: #7a8189;
}
#cssmenu2 > ul > li:hover::after {
border-top-color: #ffffff;
}
#indicatorContainer {
position: absolute;
height: 12px;
width: 100%;
bottom: 0px;
overflow: hidden;
z-index: -1;
}
#pIndicator {
position: absolute;
height: 0;
width: 100%;
border: 12px solid transparent;
border-top-color: #2b2f3a;
z-index: -2;
-webkit-transition: left .25s ease;
-moz-transition: left .25s ease;
-ms-transition: left .25s ease;
-o-transition: left .25s ease;
transition: left .25s ease;
}
#cIndicator {
position: absolute;
height: 0;
width: 100%;
border: 12px solid transparent;
border-top-color: #2b2f3a;
top: -12px;
right: 100%;
z-index: -2;
}
#cssmenu2 ul ul {
position: absolute;
left: -9999px;
top: 70px;
opacity: 0;
-webkit-transition: opacity .3s ease, top .25s ease;
-moz-transition: opacity .3s ease, top .25s ease;
-ms-transition: opacity .3s ease, top .25s ease;
-o-transition: opacity .3s ease, top .25s ease;
transition: opacity .3s ease, top .25s ease;
z-index: 1000;
}
#cssmenu2 ul ul ul {
top: 37px;
padding-left: 5px;
}
#cssmenu2 ul ul li {
position: relative;
}
#cssmenu2 > ul > li:hover > ul {
left: auto;
top: 44px;
opacity: 1;
}
#cssmenu2.align-right > ul > li:hover > ul {
left: auto;
right: 0;
opacity: 1;
}
#cssmenu2 ul ul li:hover > ul {
left: 170px;
top: 0;
opacity: 1;
}
#cssmenu2.align-right ul ul li:hover > ul {
left: auto;
right: 170px;
top: 0;
opacity: 1;
padding-right: 5px;
}
#cssmenu2 ul ul li a {
width: 130px;
border-bottom: 1px solid #eeeeee;
padding: 10px 20px;
font-size: 12px;
color: #9ea2a5;
background: #ffffff;
-webkit-transition: all .35s ease;
-moz-transition: all .35s ease;
-ms-transition: all .35s ease;
-o-transition: all .35s ease;
transition: all .35s ease;
}
#cssmenu2.align-right ul ul li a {
text-align: right;
}
#cssmenu2 ul ul li:hover > a {
background: #f2f2f2;
color: #8c9195;
}
#cssmenu2 ul ul li:last-child > a,
#cssmenu2 ul ul li.last > a {
border-bottom: 0;
}
#cssmenu2 > ul > li > ul::after {
content: '';
border: 6px solid transparent;
width: 0;
height: 0;
border-bottom-color: #ffffff;
position: absolute;
top: -12px;
left: 30px;
}
#cssmenu2.align-right > ul > li > ul::after {
left: auto;
right: 30px;
}
#cssmenu2 ul ul li.has-sub::after {
border: 4px solid transparent;
border-left-color: #9ea2a5;
right: 10px;
top: 12px;
-moz-transition: all .2s ease;
-ms-transition: all .2s ease;
-o-transition: all .2s ease;
transition: all .2s ease;
-webkit-transition: -webkit-transform 0.2s ease, right 0.2s ease;
}
#cssmenu2.align-right ul ul li.has-sub::after {
border-left-color: transparent;
border-right-color: #9ea2a5;
right: auto;
left: 10px;
}
#cssmenu2 ul ul li.has-sub:hover::after {
border-left-color: #ffffff;
right: -5px;
-webkit-transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
transform: rotateY(180deg);
}
#cssmenu2.align-right ul ul li.has-sub:hover::after {
border-right-color: #ffffff;
border-left-color: transparent;
left: -5px;
-webkit-transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
transform: rotateY(180deg);
}
@media all and (max-width: 800px), only screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 1024px), only screen and (min--moz-device-pixel-ratio: 2) and (max-width: 1024px), only screen and (-o-min-device-pixel-ratio: 2/1) and (max-width: 1024px), only screen and (min-device-pixel-ratio: 2) and (max-width: 1024px), only screen and (min-resolution: 192dpi) and (max-width: 1024px), only screen and (min-resolution: 2dppx) and (max-width: 1024px) {
#cssmenu2 {
width: auto;
}
#cssmenu2.align-center ul {
text-align: left;
}
#cssmenu2.align-right > ul > li {
float: none;
}
#cssmenu2 ul {
width: auto;
}
#cssmenu2 .submenuArrow,
#cssmenu2 #indicatorContainer {
display: none;
}
#cssmenu2 > ul {
height: auto;
display: block;
}
#cssmenu2 > ul > li {
float: none;
}
#cssmenu2 li,
#cssmenu2 > ul > li {
display: none;
}
#cssmenu2 ul ul,
#cssmenu2 ul ul ul,
#cssmenu2 ul > li:hover > ul,
#cssmenu2 ul ul > li:hover > ul,
#cssmenu2.align-right ul ul,
#cssmenu2.align-right ul ul ul,
#cssmenu2.align-right ul > li:hover > ul,
#cssmenu2.align-right ul ul > li:hover > ul {
position: relative;
left: auto;
top: auto;
opacity: 1;
padding-left: 0;
padding-right: 0;
right: auto;
}
#cssmenu2 ul .has-sub::after {
display: none;
}
#cssmenu2 ul li a {
padding: 12px 20px;
}
#cssmenu2 ul ul li a {
border: 0;
background: none;
width: auto;
padding: 8px 35px;
}
#cssmenu2.align-right ul ul li a {
text-align: left;
}
#cssmenu2 ul ul li:hover > a {
background: none;
color: #8c9195;
}
#cssmenu2 ul ul ul a {
padding: 8px 50px;
}
#cssmenu2 ul ul ul ul a {
padding: 8px 65px;
}
#cssmenu2 ul ul ul ul ul a {
padding: 8px 80px;
}
#cssmenu2 ul ul ul ul ul ul a {
padding: 8px 95px;
}
#cssmenu2 > ul > #menu-button {
display: block;
cursor: pointer;
}
#cssmenu2 #menu-button > a {
padding: 14px 20px;
}
#cssmenu2 ul.open li,
#cssmenu2 > ul.open > li {
display: block;
}
#cssmenu2 > ul.open > li#menu-button > a {
color: #fff;
border-bottom: 1px solid rgba(150, 150, 150, 0.1);
}
#cssmenu2 ul ul::after {
display: none;
}
#cssmenu2 #menu-button::after {
display: block;
content: '';
position: absolute;
height: 3px;
width: 22px;
border-top: 2px solid #7a8189;
border-bottom: 2px solid #7a8189;
right: 20px;
top: 15px;
}
#cssmenu2 #menu-button::before {
display: block;
content: '';
position: absolute;
height: 3px;
width: 22px;
border-top: 2px solid #7a8189;
right: 20px;
top: 25px;
}
#cssmenu2 ul.open #menu-button::after,
#cssmenu2 ul.open #menu-button::before {
border-color: #fff;
}
}

68
css/map_styles.css 100644
Wyświetl plik

@ -0,0 +1,68 @@
html {
height:100%;
background-color:#c4c4c4;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
padding:0px;
margin:0px;
}
body {
height:100%;
text-align:center;
overflow-x:auto:
-webkit-font-smoothing: antialiased;
-webkit-overflow-scrolling: touch;
padding:0px;
margin:0px;
}
.main-header {
color:#EAE373;
font-family: 'Oswald', sans-serif;
font-weight: 300;
font-size:50px;
padding-top:15%;
}
#map{
height:100%;
width:100%;
padding:0px;
margin:0px;
}
/* Titles */
h2, h3, h4, h5, h6 {
font-family: 'Oswald', sans-serif;
font-weight: 300;
color: #fff;
}
h1 {
color:#EAE373;
font-family: 'Oswald', sans-serif;
font-weight: 300;
font-size:24px;
}
/* Paragraph & Typographic */
p {
line-height: 20px;
margin-bottom: 10px;
font-size:12px;
font-weight:400;
color:white;
}
#logo {
position:absolute;
left:5px;
top:0px;
z-index:9999;
}

63
css/style.css 100644
Wyświetl plik

@ -0,0 +1,63 @@
html {
height:100%;
background: url(../img/langley.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
body {
text-align:center;
overflow-x:auto:
-webkit-font-smoothing: antialiased;
-webkit-overflow-scrolling: touch;
margin:0px;
padding:0px;
}
.main-header {
color:#EAE373;
font-family: 'Oswald', sans-serif;
font-weight: 300;
font-size:50px;
padding-top:15%;
}
#map{
height:100%;
width:100%;
}
/* Titles */
h2, h3, h4, h5, h6 {
font-family: 'Oswald', sans-serif;
font-weight: 300;
color: #fff;
}
h1 {
color:#333333;
font-family: 'Oswald', sans-serif;
font-weight: 300;
font-size:24px;
}
/* Paragraph & Typographic */
p {
line-height: 20px;
margin-bottom: 10px;
font-size:12px;
font-weight:400;
color:white;
}
#logo {
position:absolute;
left:5px;
top:0px;
z-index:9999;
}

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -1,24 +0,0 @@
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
exec 1>&2
echo "RUNNING PRE-COMMIT"
EXIT_CODE=0
# Get list of files about to be committed
if git diff --cached --name-only --diff-filter=ACM | grep 'ccd_defs.json'; then
echo "We changed ccd_defs.json"
GIT_ROOT=$(git rev-parse --show-toplevel)
python $GIT_ROOT/ccd_defs_check.py
EXIT_CODE=$(echo $?)
fi
# non-zero exit fails the commit
exit $EXIT_CODE

BIN
img/.DS_Store vendored 100644

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -0,0 +1 @@
dac47368ffb53158b52bc4381754af4bc453ad62

133
img/logo.svg 100644
Wyświetl plik

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="200.00186"
height="34.613998"
id="svg44851"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="logo.svg">
<defs
id="defs44853" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.9195959"
inkscape:cx="104.55345"
inkscape:cy="16.955099"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1056"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1" />
<metadata
id="metadata44856">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-125.71334,-475.05516)">
<g
id="g51667"
transform="matrix(0.76597163,0,0,0.76597163,80.176488,113.77503)">
<g
id="g51649">
<path
id="path20809"
d="m 70.81205,490.92913 c 2.414,0 4.09,0.973 5.027,2.918 0.48,0.973 0.715,1.951 0.703,2.936 v 6.311 c 0,2.414 -0.949,4.096 -2.848,5.045 -0.949,0.48 -1.898,0.715 -2.848,0.703 h -5.309 c -0.961,0.012 -1.922,-0.217 -2.883,-0.686 -1.934,-0.949 -2.9,-2.631 -2.9,-5.045 v -6.363 c 0,-0.973 0.24,-1.945 0.721,-2.918 0.961,-1.934 2.643,-2.9 5.045,-2.9 h 5.292 z m 2.566,6.592 c 0,-0.563 -0.135,-1.125 -0.404,-1.688 -0.551,-1.125 -1.523,-1.688 -2.918,-1.688 h -3.762 c -1.395,0 -2.367,0.557 -2.918,1.67 -0.281,0.563 -0.416,1.125 -0.404,1.688 v 4.816 c 0,1.395 0.557,2.367 1.67,2.918 0.551,0.27 1.107,0.398 1.67,0.387 h 3.779 c 0.539,0.012 1.084,-0.117 1.635,-0.387 1.102,-0.539 1.652,-1.518 1.652,-2.936 v -4.78 z"
inkscape:connector-curvature="0"
style="fill:#a8d166" />
<path
id="path20811"
d="m 93.34705,490.87613 c 0.516,-0.012 1.037,0.111 1.564,0.369 1.043,0.504 1.564,1.406 1.564,2.707 v 10.02 c 0,0.445 -0.129,0.914 -0.387,1.406 -0.516,0.973 -1.424,1.564 -2.725,1.775 l -10.266,1.389 -0.018,7.559 -3.129,-0.018 v -22.096 c 0,-1.289 0.51,-2.197 1.529,-2.725 0.504,-0.258 1.014,-0.387 1.529,-0.387 h 10.339 z m -0.018,5.133 c 0,-0.832 -0.34,-1.406 -1.02,-1.723 -0.328,-0.164 -0.662,-0.246 -1.002,-0.246 h -6.275 c -0.328,0 -0.656,0.082 -0.984,0.246 -0.645,0.34 -0.967,0.926 -0.967,1.758 v 9.299 l 8.244,-1.283 c 0.832,-0.188 1.412,-0.58 1.74,-1.178 0.176,-0.305 0.264,-0.586 0.264,-0.844 v -6.029 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
<path
id="path20813"
d="m 113.22805,490.92913 c 0.527,-0.012 1.055,0.111 1.582,0.369 1.066,0.516 1.6,1.436 1.6,2.76 v 3.041 c 0,0.457 -0.135,0.932 -0.404,1.424 -0.527,0.984 -1.447,1.582 -2.76,1.793 l -10.441,1.424 v 1.811 c -0.012,0.34 0.064,0.686 0.229,1.037 0.328,0.691 0.92,1.037 1.775,1.037 h 10.67 l 0.053,3.217 h -12.762 c -1.348,0 -2.273,-0.539 -2.777,-1.617 -0.258,-0.551 -0.381,-1.096 -0.369,-1.635 v -11.496 c 0,-1.313 0.516,-2.232 1.547,-2.76 0.516,-0.27 1.037,-0.404 1.564,-0.404 h 10.493 z m -2.057,7.225 c 0.785,-0.188 1.354,-0.551 1.705,-1.09 0.199,-0.305 0.305,-0.615 0.316,-0.932 0,-0.844 -0.34,-1.43 -1.02,-1.758 -0.34,-0.164 -0.68,-0.24 -1.02,-0.229 h -6.363 c -0.34,0 -0.674,0.082 -1.002,0.246 -0.656,0.34 -0.984,0.932 -0.984,1.775 v 3.287 l 8.368,-1.299 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
<path
id="path20815"
d="m 132.59905,490.85913 c 0.539,-0.105 1.072,-0.047 1.6,0.176 1.066,0.445 1.6,1.477 1.6,3.094 v 14.713 h -3.182 v -13.219 c 0,-0.703 -0.246,-1.119 -0.738,-1.248 -0.246,-0.07 -0.492,-0.064 -0.738,0.018 l -6.908,1.072 c -0.855,0.188 -1.453,0.586 -1.793,1.195 -0.164,0.305 -0.246,0.592 -0.246,0.861 v 11.32 h -3.234 v -17.947 l 3.182,-0.018 v 1.459 -0.018 l 10.457,-1.458 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
</g>
<g
id="g51660">
<path
id="path20817"
d="m 160.91705,491.22813 0.018,-7.541 3.111,0.018 v 22.043 c 0,1.277 -0.51,2.18 -1.529,2.707 -0.504,0.258 -1.014,0.387 -1.529,0.387 h -10.301 c -0.516,0.012 -1.037,-0.111 -1.564,-0.369 -1.043,-0.504 -1.564,-1.406 -1.564,-2.707 v -9.984 c 0,-0.445 0.129,-0.908 0.387,-1.389 0.527,-0.973 1.436,-1.564 2.725,-1.775 l 10.246,-1.39 z m -10.213,12.48 c 0,0.832 0.334,1.412 1.002,1.74 0.34,0.164 0.674,0.24 1.002,0.229 h 6.258 c 0.328,0 0.656,-0.082 0.984,-0.246 0.656,-0.328 0.984,-0.908 0.984,-1.74 v -9.281 l -8.227,1.283 c -0.832,0.188 -1.412,0.58 -1.74,1.178 -0.176,0.305 -0.264,0.586 -0.264,0.844 v 5.993 z"
inkscape:connector-curvature="0"
style="fill:#a8d166" />
<path
id="path20819"
d="m 176.49105,490.92913 c 0.539,-0.105 1.072,-0.047 1.6,0.176 1.055,0.445 1.582,1.477 1.582,3.094 v 1.529 l -3.164,-0.053 c 0,-0.691 -0.246,-1.107 -0.738,-1.248 -0.234,-0.059 -0.475,-0.053 -0.721,0.018 l -2.355,0.791 c -0.926,0.328 -1.541,0.879 -1.846,1.652 -0.152,0.387 -0.211,0.744 -0.176,1.072 v 10.881 h -3.217 v -17.877 l 3.164,-0.018 v 1.441 h 0.018 l 5.853,-1.458 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
<path
id="path20821"
d="m 192.27705,490.92913 c 2.414,0 4.09,0.973 5.027,2.918 0.48,0.973 0.715,1.951 0.703,2.936 v 6.311 c 0,2.414 -0.949,4.096 -2.848,5.045 -0.949,0.48 -1.898,0.715 -2.848,0.703 h -5.309 c -0.961,0.012 -1.922,-0.217 -2.883,-0.686 -1.934,-0.949 -2.9,-2.631 -2.9,-5.045 v -6.363 c 0,-0.973 0.24,-1.945 0.721,-2.918 0.961,-1.934 2.643,-2.9 5.045,-2.9 h 5.292 z m 2.566,6.592 c 0,-0.563 -0.135,-1.125 -0.404,-1.688 -0.551,-1.125 -1.523,-1.688 -2.918,-1.688 h -3.762 c -1.395,0 -2.367,0.557 -2.918,1.67 -0.281,0.563 -0.416,1.125 -0.404,1.688 v 4.816 c 0,1.395 0.557,2.367 1.67,2.918 0.551,0.27 1.107,0.398 1.67,0.387 h 3.779 c 0.539,0.012 1.084,-0.117 1.635,-0.387 1.102,-0.539 1.652,-1.518 1.652,-2.936 v -4.78 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
<path
id="path20823"
d="m 215.04005,490.85913 c 0.539,-0.105 1.072,-0.047 1.6,0.176 1.066,0.445 1.6,1.477 1.6,3.094 v 14.713 h -3.182 v -13.219 c 0,-0.703 -0.246,-1.119 -0.738,-1.248 -0.246,-0.07 -0.492,-0.064 -0.738,0.018 l -6.908,1.072 c -0.855,0.188 -1.453,0.586 -1.793,1.195 -0.164,0.305 -0.246,0.592 -0.246,0.861 v 11.32 h -3.234 v -17.947 l 3.182,-0.018 v 1.459 -0.018 l 10.457,-1.458 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
<path
id="path20825"
d="m 235.41305,490.92913 c 0.527,-0.012 1.055,0.111 1.582,0.369 1.066,0.516 1.6,1.436 1.6,2.76 v 3.041 c 0,0.457 -0.135,0.932 -0.404,1.424 -0.527,0.984 -1.447,1.582 -2.76,1.793 l -10.441,1.424 v 1.811 c -0.012,0.34 0.064,0.686 0.229,1.037 0.328,0.691 0.92,1.037 1.775,1.037 h 10.67 l 0.053,3.217 h -12.763 c -1.348,0 -2.273,-0.539 -2.777,-1.617 -0.258,-0.551 -0.381,-1.096 -0.369,-1.635 v -11.496 c 0,-1.313 0.516,-2.232 1.547,-2.76 0.516,-0.27 1.037,-0.404 1.564,-0.404 h 10.494 z m -2.056,7.225 c 0.785,-0.188 1.354,-0.551 1.705,-1.09 0.199,-0.305 0.305,-0.615 0.316,-0.932 0,-0.844 -0.34,-1.43 -1.02,-1.758 -0.34,-0.164 -0.68,-0.24 -1.02,-0.229 h -6.363 c -0.34,0 -0.674,0.082 -1.002,0.246 -0.656,0.34 -0.984,0.932 -0.984,1.775 v 3.287 l 8.368,-1.299 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
</g>
<g
id="g51655">
<path
id="path20827"
d="m 277.16105,490.98213 c 0.527,-0.105 1.055,-0.047 1.582,0.176 1.055,0.445 1.582,1.471 1.582,3.076 v 14.607 h -3.146 v -13.131 c 0,-0.691 -0.246,-1.102 -0.738,-1.23 -0.246,-0.07 -0.492,-0.07 -0.738,0 l -6.873,1.072 c -0.703,0.164 -1.23,0.475 -1.582,0.932 -0.223,0.293 -0.363,0.615 -0.422,0.967 v 11.391 h -3.199 v -13.201 c 0,-0.059 0.006,-0.135 0.018,-0.229 -0.082,-0.539 -0.346,-0.855 -0.791,-0.949 -0.223,-0.047 -0.434,-0.041 -0.633,0.018 l -6.873,1.072 c -0.844,0.188 -1.436,0.586 -1.775,1.195 -0.164,0.305 -0.246,0.592 -0.246,0.861 v 11.232 h -3.217 v -17.824 l 3.164,-0.018 v 1.441 l 10.389,-1.459 c 0.352,-0.07 0.732,-0.059 1.143,0.035 0.82,0.188 1.395,0.68 1.723,1.477 0.188,-0.047 0.27,-0.064 0.246,-0.053 l 10.386,-1.458 z"
inkscape:connector-curvature="0"
style="fill:#a8d166" />
<path
id="path20829"
d="m 297.00705,490.92913 c 1.348,0 2.273,0.539 2.777,1.617 0.258,0.551 0.381,1.096 0.369,1.635 v 11.496 c 0,1.313 -0.521,2.232 -1.564,2.76 -0.516,0.27 -1.031,0.404 -1.547,0.404 h -10.494 c -0.527,0.012 -1.055,-0.111 -1.582,-0.369 -1.066,-0.516 -1.6,-1.436 -1.6,-2.76 v -3.041 c 0,-0.445 0.135,-0.92 0.404,-1.424 0.527,-0.984 1.447,-1.582 2.76,-1.793 l 10.441,-1.424 v -1.811 c 0.012,-0.34 -0.064,-0.686 -0.229,-1.037 -0.328,-0.691 -0.92,-1.037 -1.775,-1.037 h -8.455 l -0.035,-3.217 h 10.53 z m -0.035,9.475 -8.367,1.213 c -0.785,0.188 -1.354,0.551 -1.705,1.09 -0.199,0.305 -0.305,0.615 -0.316,0.932 0,0.844 0.34,1.43 1.02,1.758 0.34,0.164 0.68,0.24 1.02,0.229 h 6.363 c 0.328,0 0.662,-0.082 1.002,-0.246 0.656,-0.34 0.984,-0.932 0.984,-1.775 v -3.201 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
<path
id="path20831"
d="m 317.11605,490.87613 c 0.516,-0.012 1.037,0.111 1.564,0.369 1.043,0.504 1.564,1.406 1.564,2.707 v 10.02 c 0,0.445 -0.129,0.914 -0.387,1.406 -0.516,0.973 -1.424,1.564 -2.725,1.775 l -10.266,1.389 -0.018,7.559 -3.129,-0.018 v -22.096 c 0,-1.289 0.51,-2.197 1.529,-2.725 0.504,-0.258 1.014,-0.387 1.529,-0.387 h 10.339 z m -0.017,5.133 c 0,-0.832 -0.34,-1.406 -1.02,-1.723 -0.328,-0.164 -0.662,-0.246 -1.002,-0.246 h -6.275 c -0.328,0 -0.656,0.082 -0.984,0.246 -0.645,0.34 -0.967,0.926 -0.967,1.758 v 9.299 l 8.244,-1.283 c 0.832,-0.188 1.412,-0.58 1.74,-1.178 0.176,-0.305 0.264,-0.586 0.264,-0.844 v -6.029 z"
inkscape:connector-curvature="0"
style="fill:#5fa3d9" />
</g>
</g>
</g>
</svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 11 KiB

6390
img/logo_full.svg 100644

Plik diff jest za duży Load Diff

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 573 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 38 KiB

Wyświetl plik

@ -1 +0,0 @@
2d1bc1543ef974c0c6a41db46c8c813c6a3b5692

Wyświetl plik

@ -1 +0,0 @@
fd7c406148027f41dc619fd833b9f55f9973a202

Wyświetl plik

@ -1 +0,0 @@
911fe91791a8506d3c641e51451a2f0a9121690f

Wyświetl plik

@ -1 +0,0 @@
715b5748537e5b44e0631d83da797e764531df8c

58
index.html 100644
Wyświetl plik

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>OpenDroneMap</title>
<link href="css/style.css" rel="stylesheet">
<link href="css/cssmenu.css" rel="stylesheet">
<link href="css/cssmenu2.css" rel="stylesheet">
<link href='http://fonts.googleapis.com/css?family=BenchNine|Oswald' rel='stylesheet' type='text/css'>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src="js/script.js"></script>
</head>
<style>
</style>
<body>
<div id='cssmenu'>
<div id="logo"><a href="#"><img src="img/logo.svg"></a></div>
<ul>
<li><a href='pages/about.html'><span>About</span></a></li>
<li><a href='https://github.com/OpenDroneMap/OpenDroneMap' target="_blank"><span>Code on GitHub</span></a></li>
<li class='active has-sub'><a href='#'><span>Example Data</span></a>
<ul>
<li><a href='https://github.com/OpenDroneMap/odm_data_benchmark' target="_blank"><span>Benchmark</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_pacifica' target="_blank"><span>Pacifica (Beach)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_langley' target="_blank"><span>Langley (Town Center)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_apt' target="_blank"><span>Corridor (Trail)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_seneca' target="_blank"><span>Seneca (Color Infrared Farm)</span></a></li>
</ul>
</li>
<li><a href='pages/contact.html'><span>Contact</span></a></li>
</ul>
</div>
<div id="container">
<h1 class="main-header"><a href="#"><img src="img/logo_full.svg"></a></h1>
<h1><i>Open Source Toolkit for processing Civilian Drone Imagery</i></h1>
<div id='cssmenu2'>
<ul>
<li class='active has-sub'><a href='#'><span>Code & Data</span></a>
<ul>
<li><a href='https://github.com/OpenDroneMap/OpenDroneMap' target="_blank"><span>Code</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_benchmark' target="_blank"><span>Benchmark</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_pacifica' target="_blank"><span>Pacifica (Beach)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_langley' target="_blank"><span>Langley (Town Center)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_apt' target="_blank"><span>Corridor (Trail)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data_seneca' target="_blank"><span>Seneca (Color Infrared Farm)</span></a></li> </ul>
</li>
</ul>
</div>
</div>
</body>
</html>

Wyświetl plik

@ -1,559 +0,0 @@
#!/bin/bash
set -o nounset
set -o errexit
echo
echo " created by Daniel Schwarz/daniel.schwarz@topoi.org"
echo " released under Creative Commons/CC-BY"
echo " Attribution"
echo
echo " if the script doesn't finish properly"
echo " (i.e. it doesn't print \"script finished\" at the end)"
echo " please email me the content of the logs folder"
echo
echo
echo " - script started - `date`"
## dest base path
TOOLS_PATH="$PWD"
## paths for the tools
TOOLS_BIN_PATH="$TOOLS_PATH/bin"
TOOLS_INC_PATH="$TOOLS_PATH/include"
TOOLS_LIB_PATH="$TOOLS_PATH/lib"
TOOLS_SRC_PATH="$TOOLS_PATH/src"
TOOLS_LOG_PATH="$TOOLS_PATH/logs"
TOOLS_PATCHED_PATH="$TOOLS_PATH/patched_files"
## loacal dest paths
LIB_PATH="/usr/local/lib"
INC_PATH="/usr/local/include"
## source paths
BUNDLER_PATH="$TOOLS_SRC_PATH/bundler"
CMVS_PATH="$TOOLS_SRC_PATH/cmvs"
PMVS_PATH="$TOOLS_SRC_PATH/pmvs"
CLAPACK_PATH="$TOOLS_SRC_PATH/clapack"
VLFEAT_PATH="$TOOLS_SRC_PATH/vlfeat"
PARALLEL_PATH="$TOOLS_SRC_PATH/parallel"
PSR_PATH="$TOOLS_SRC_PATH/PoissonRecon"
GRACLUS_PATH="$TOOLS_SRC_PATH/graclus"
CERES_PATH="$TOOLS_SRC_PATH/ceres-solver"
PCL_PATH="$TOOLS_SRC_PATH/pcl"
LASTOOLS_PATH="$TOOLS_SRC_PATH/lastools"
ODM_MESHING_PATH="$TOOLS_SRC_PATH/odm_meshing"
ODM_TEXTURING_PATH="$TOOLS_SRC_PATH/odm_texturing"
ODM_ORTHOPHOTO_PATH="$TOOLS_SRC_PATH/odm_orthophoto"
ODM_EXTRACT_UTM_PATH="$TOOLS_SRC_PATH/odm_extract_utm"
ODM_GEOREF_PATH="$TOOLS_SRC_PATH/odm_georef"
OPENGV_PATH="$TOOLS_SRC_PATH/opengv"
OPENSFM_PATH="$TOOLS_SRC_PATH/OpenSfM"
## executables
EXTRACT_FOCAL="$TOOLS_BIN_PATH/extract_focal.pl"
MATCHKEYS="$TOOLS_BIN_PATH/KeyMatch"
MATCHKEYSFULL="$TOOLS_BIN_PATH/KeyMatchFull"
BUNDLER="$TOOLS_BIN_PATH/bundler"
BUNDLE2PVMS="$TOOLS_BIN_PATH/Bundle2PMVS"
CMVS="$TOOLS_BIN_PATH/cmvs"
PMVS="$TOOLS_BIN_PATH/pmvs2"
GENOPTION="$TOOLS_BIN_PATH/genOption"
VLSIFT="$TOOLS_BIN_PATH/vlsift"
PARALLEL="$TOOLS_BIN_PATH/parallel"
PSR="$TOOLS_BIN_PATH/PoissonRecon"
VLSIFT_TO_LOWESIFT="$TOOLS_BIN_PATH/convert_vlsift_to_lowesift.pl"
ODM_MESHING="$TOOLS_BIN_PATH/odm_meshing"
ODM_TEXTURING="$TOOLS_BIN_PATH/odm_texturing"
ODM_ORTHOPHOTO="$TOOLS_BIN_PATH/odm_orthophoto"
ODM_EXTRACT_UTM="$TOOLS_BIN_PATH/odm_extract_utm"
ODM_GEOREF="$TOOLS_BIN_PATH/odm_georef"
## get sys vars
ARCH=`uname -m`
CORES=`grep -c processor /proc/cpuinfo`
## prevents different (localized) output
LC_ALL=C
## removing old stuff
sudo rm -Rf "$TOOLS_BIN_PATH"
sudo rm -Rf "$TOOLS_INC_PATH"
sudo rm -Rf "$TOOLS_LIB_PATH"
sudo rm -Rf "$TOOLS_SRC_PATH"
sudo rm -Rf "$TOOLS_LOG_PATH"
## create needed directories
mkdir -p "$TOOLS_BIN_PATH"
mkdir -p "$TOOLS_INC_PATH"
mkdir -p "$TOOLS_LIB_PATH"
mkdir -p "$TOOLS_SRC_PATH"
mkdir -p "$TOOLS_LOG_PATH"
## Copy meshing and texturing to src folder
cp -rf "odm_meshing" "$TOOLS_SRC_PATH/"
cp -rf "odm_texturing" "$TOOLS_SRC_PATH/"
cp -rf "odm_orthophoto" "$TOOLS_SRC_PATH/"
cp -rf "odm_extract_utm" "$TOOLS_SRC_PATH/"
cp -rf "odm_georef" "$TOOLS_SRC_PATH/"
## output sys info
echo "System info:" > "$TOOLS_LOG_PATH/sysinfo.txt"
uname -a > "$TOOLS_LOG_PATH/sysinfo.txt"
## install packages
echo
echo " > installing required packages"
echo " - updating"
sudo apt-get update --assume-yes > "$TOOLS_LOG_PATH/apt-get_get.log" 2>&1
echo " - installing"
if [[ `lsb_release -rs` == "12.04" ]];
then
sudo apt-get install --assume-yes --install-recommends \
build-essential cmake g++ gcc gFortran perl git autoconf \
curl wget \
unzip \
imagemagick jhead proj-bin libproj-dev\
libjpeg-dev libboost1.48-all-dev libgsl0-dev libx11-dev libxext-dev liblapack-dev \
libeigen3-dev libflann-dev libvtk5-dev libqhull-dev libusb-1.0-0-dev\
libzip-dev \
libswitch-perl libjson-perl \
libcv-dev libcvaux-dev libopencv-dev \
gdal-bin \
exiv2 \
libgoogle-glog-dev libatlas-base-dev libsuitesparse-dev \
> "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1
else
sudo apt-get install --assume-yes --install-recommends \
build-essential cmake g++ gcc gFortran perl git autoconf \
curl wget \
unzip \
imagemagick jhead proj-bin libproj-dev\
libjpeg-dev libboost-all-dev libgsl0-dev libx11-dev libxext-dev liblapack-dev \
libeigen3-dev libflann-dev libvtk5-dev libqhull-dev libusb-1.0-0-dev\
libjson-perl \
libzip-dev \
libswitch-perl \
libcv-dev libcvaux-dev libopencv-dev \
libgoogle-glog-dev libatlas-base-dev libeigen3-dev libsuitesparse-dev \
python-dev python-pip libboost-python-dev \
python-numpy-dev python-scipy python-yaml \
python-opencv python-pyexiv2 \
gdal-bin \
exiv2 \
> "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1
fi
sudo pip install networkx exifread xmltodict
echo " - installing git submodules"
git submodule init
git submodule update
echo " < done - `date`"
## downloading sources
echo
echo " > getting the sources"
## Reconstruct CMVS tar.gz from pieces...
cat cmvs.tar.gz.part-?? > cmvs.tar.gz
## getting all archives if not already present; save them to .tmp and rename them after download
while read target source
do
if [ ! -f "$target" ] ; then
echo " - getting $source"
curl --progress-bar --location -o "$target.tmp" "$source"
mv "$target.tmp" "$target"
echo " - finished $target"
echo
else
echo " - already downloaded $source"
fi
done <<EOF
parallel.tar.bz2 http://ftp.gnu.org/gnu/parallel/parallel-20141022.tar.bz2
clapack.tgz http://www.netlib.org/clapack/clapack-3.2.1-CMAKE.tgz
PoissonRecon.zip http://www.cs.jhu.edu/~misha/Code/PoissonRecon/Version2/PoissonRecon.zip
vlfeat.tar.gz http://www.vlfeat.org/download/vlfeat-0.9.13-bin.tar.gz
cmvs.tar.gz http://www.di.ens.fr/cmvs/cmvs-fix2.tar.gz
graclus.tar.gz http://smathermather.github.io/BundlerTools/patched_files/src/graclus/graclus1.2.tar.gz
pcl.tar.gz https://github.com/PointCloudLibrary/pcl/archive/pcl-1.7.2.tar.gz
ceres-solver.tar.gz http://ceres-solver.org/ceres-solver-1.10.0.tar.gz
LAStools.zip http://lastools.org/download/LAStools.zip
EOF
git clone https://github.com/paulinus/opengv.git $OPENGV_PATH
git clone https://github.com/mapillary/OpenSfM.git $OPENSFM_PATH
echo " < done - `date`"
## unzipping sources
echo
echo " - unzipping sources"
for i in *.tar.bz2 ; do
tar xjf "$i" > "$TOOLS_LOG_PATH/extract_$i.log" 2>&1 &
done
for i in *.tgz *.tar.gz ; do
tar xzf "$i" > "$TOOLS_LOG_PATH/extract_$i.log" 2>&1 &
done
for i in *.zip ; do
unzip "$i" > "$TOOLS_LOG_PATH/extract_$i.log" 2>&1 &
done
wait
mv -f graclus1.2 "$GRACLUS_PATH"
mv -f clapack-3.2.1-CMAKE "$CLAPACK_PATH"
mv -f vlfeat-0.9.13 "$VLFEAT_PATH"
mv -f parallel-20141022 "$PARALLEL_PATH"
mv -f PoissonRecon "$PSR_PATH"
mv -f cmvs "$CMVS_PATH"
mv -f pcl-pcl-1.7.2 "$PCL_PATH"
mv -f ceres-solver-1.10.0 "$CERES_PATH"
mv -f LAStools "$LASTOOLS_PATH"
echo " < done - `date`"
## copying patches
echo
echo " - copying patches"
echo
for file in `find $TOOLS_PATCHED_PATH -type f -print` ; do
cp $file $TOOLS_PATH/${file/$TOOLS_PATCHED_PATH/.}
done
echo " < done - `date`"
# building
echo
echo " - building"
echo
sudo chown -R `id -u`:`id -g` *
#sudo chmod -R 777 *
echo " > graclus"
cd "$GRACLUS_PATH"
if [ "$ARCH" = "i686" ]; then
sed -i "$GRACLUS_PATH/Makefile.in" -e "11c\COPTIONS = -DNUMBITS=32"
fi
if [ "$ARCH" = "x86_64" ]; then
sed -i "$GRACLUS_PATH/Makefile.in" -e "11c\COPTIONS = -DNUMBITS=64"
fi
echo " - cleaning graclus"
make clean > "$TOOLS_LOG_PATH/graclus_1_clean.log" 2>&1
echo " - building graclus"
make -j$CORES > "$TOOLS_LOG_PATH/graclus_2_build.log" 2>&1
mkdir "$TOOLS_INC_PATH/metisLib"
cp -f "$GRACLUS_PATH/metisLib/"*.h "$TOOLS_INC_PATH/metisLib/"
cp -f lib* "$TOOLS_LIB_PATH/"
echo " < done - `date`"
echo
echo " > poisson surface reconstruction "
cd "$PSR_PATH"
sed -i "$PSR_PATH/Makefile" -e "21c\BIN = ./"
echo " - building poisson surface reconstruction"
make -j$CORES > "$TOOLS_LOG_PATH/poisson_1_build.log" 2>&1
cp -f "$PSR_PATH/PoissonRecon" "$TOOLS_BIN_PATH/PoissonRecon"
echo " < done - `date`"
echo
echo " > parallel"
cd "$PARALLEL_PATH"
echo " - configuring parallel"
./configure > "$TOOLS_LOG_PATH/parallel_1_build.log" 2>&1
echo " - building paralel"
make -j$CORES> "$TOOLS_LOG_PATH/parallel_2_build.log" 2>&1
cp -f src/parallel "$TOOLS_BIN_PATH/"
echo " < done - `date`"
echo
echo " > clapack"
cd "$CLAPACK_PATH"
cp make.inc.example make.inc
set +e
echo " - building clapack"
make -j$CORES all > "$TOOLS_LOG_PATH/clapack_1_build.log" 2>&1
set -e
echo " - installing clapack"
make -j$CORES lapack_install > "$TOOLS_LOG_PATH/clapack_2_install.log" 2>&1
sudo cp -Rf INCLUDE "$INC_PATH/clapack"
echo " < done - `date`"
echo
echo " > vlfeat"
cd "$VLFEAT_PATH"
echo " - installing vlfeat"
if [ "$ARCH" = "i686" ]; then
cp -f "$VLFEAT_PATH/bin/glnx86/sift" "$TOOLS_BIN_PATH/vlsift"
cp -f "$VLFEAT_PATH/bin/glnx86/libvl.so" "$TOOLS_LIB_PATH/"
fi
if [ "$ARCH" = "x86_64" ]; then
cp -f "$VLFEAT_PATH/bin/glnxa64/sift" "$TOOLS_BIN_PATH/vlsift"
cp -f "$VLFEAT_PATH/bin/glnxa64/libvl.so" "$TOOLS_LIB_PATH/"
fi
echo " < done - `date`"
echo
echo " > LAStools"
cd "$LASTOOLS_PATH"
echo " - installing LAStools"
make -j$CORES > "$TOOLS_LOG_PATH/lastools_1_build.log" 2>&1
if [ "$ARCH" = "i686" ]; then
cp -f "$LASTOOLS_PATH/bin/txt2las" "$TOOLS_BIN_PATH/txt2las"
fi
if [ "$ARCH" = "x86_64" ]; then
cp -f "$LASTOOLS_PATH/bin/txt2las" "$TOOLS_BIN_PATH/txt2las"
fi
echo " < done - `date`"
echo
echo " > cmvs/pmvs"
cd "$CMVS_PATH/program/main"
sed -i "$CMVS_PATH/program/main/genOption.cc" -e "5c\#include <stdlib.h>\n"
sed -i "$CMVS_PATH/program/base/cmvs/bundle.cc" -e "3c\#include <numeric>\n"
sed -i "$CMVS_PATH/program/main/Makefile" -e "10c\#Your INCLUDE path (e.g., -I\/usr\/include)"
sed -i "$CMVS_PATH/program/main/Makefile" -e "11c\YOUR_INCLUDE_PATH =-I$INC_PATH -I$TOOLS_INC_PATH"
sed -i "$CMVS_PATH/program/main/Makefile" -e "13c\#Your metis directory (contains header files under graclus1.2/metisLib/)"
sed -i "$CMVS_PATH/program/main/Makefile" -e "14c\YOUR_INCLUDE_METIS_PATH = -I$TOOLS_INC_PATH/metisLib/"
sed -i "$CMVS_PATH/program/main/Makefile" -e "16c\#Your LDLIBRARY path (e.g., -L/usr/lib)"
sed -i "$CMVS_PATH/program/main/Makefile" -e "17c\YOUR_LDLIB_PATH = -L$LIB_PATH -L$TOOLS_LIB_PATH"
if [ "$ARCH" = "i686" ]; then
sed -i "$CMVS_PATH/program/main/Makefile" -e "22c\CXXFLAGS_CMVS = -O2 -Wall -Wno-deprecated -DNUMBITS=32 \\\\"
sed -i "$CMVS_PATH/program/main/Makefile" -e '24c\ -fopenmp -DNUMBITS=32 ${OPENMP_FLAG}'
fi
if [ "$ARCH" = "x86_64" ]; then
sed -i "$CMVS_PATH/program/main/Makefile" -e "22c\CXXFLAGS_CMVS = -O2 -Wall -Wno-deprecated -DNUMBITS=64 \\\\"
sed -i "$CMVS_PATH/program/main/Makefile" -e '24c\ -fopenmp -DNUMBITS=64 ${OPENMP_FLAG}'
fi
echo " - cleaning cmvs"
make clean > "$TOOLS_LOG_PATH/cmvs_1_clean.log" 2>&1
echo " - building cmvs"
make -j$CORES > "$TOOLS_LOG_PATH/cmvs_2_build.log" 2>&1
echo " - make depend cmvs"
sudo make depend > "$TOOLS_LOG_PATH/cmvs_3_depend.log" 2>&1
cp -f "$CMVS_PATH/program/main/cmvs" "$CMVS_PATH/program/main/pmvs2" "$CMVS_PATH/program/main/genOption" "$TOOLS_BIN_PATH/"
cp -f "$CMVS_PATH/program/main/"*so* "$TOOLS_LIB_PATH/"
echo " < done - `date`"
echo
echo " > ceres"
cd "$CERES_PATH"
echo " - configuring ceres"
mkdir -p build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$TOOLS_PATH \
-DCMAKE_C_FLAGS=-fPIC -DCMAKE_CXX_FLAGS=-fPIC \
-DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF > "$TOOLS_LOG_PATH/ceres_1_config.log" 2>&1
echo " - building ceres"
make -j$CORES install > "$TOOLS_LOG_PATH/ceres_1_build.log" 2>&1
echo " < done - `date`"
echo
echo " > bundler"
cd "$BUNDLER_PATH"
echo " - cleaning bundler"
make clean > "$TOOLS_LOG_PATH/bundler_1_clean.log" 2>&1
echo " - building bundler"
make -j$CORES > "$TOOLS_LOG_PATH/bundler_2_build.log" 2>&1
ln -s "$BUNDLER_PATH/bin/Bundle2PMVS" "$BUNDLER_PATH/bin/Bundle2Vis" "$BUNDLER_PATH/bin/KeyMatchFull" "$BUNDLER_PATH/bin/KeyMatch" "$BUNDLER_PATH/bin/bundler" "$BUNDLER_PATH/bin/RadialUndistort" "$TOOLS_BIN_PATH/"
ln -s "$BUNDLER_PATH/lib/libANN_char.so" "$TOOLS_LIB_PATH/"
echo " < done - `date`"
echo
echo " > pcl "
#cd "$PCL_PATH"
#Install pcl dependencies using the default package manager.
#sudo apt-get install libeigen3-dev libflann-dev libvtk5-dev libqhull-dev
#install the required boost version.
#sudo apt-get install libboost1.48-all-dev
mkdir -p "pcl"
mkdir -p "$TOOLS_LIB_PATH/pcl"
mkdir -p "$PCL_PATH/pcl_tmp"
mkdir -p "$PCL_PATH/pcl_build"
#mv -f "pcl-pcl-1.7.2" "$PCL_PATH/pcl_tmp"
cd "$PCL_PATH/pcl_build"
echo " - configuring pcl"
cmake .. -DCMAKE_INSTALL_PREFIX="$TOOLS_LIB_PATH/pcl" -DCMAKE_BUILD_TYPE=Release -DPCL_VERBOSITY_LEVEL=Error -DBUILD_features=OFF -DBUILD_filters=OFF -DBUILD_geometry=OFF -DBUILD_keypoints=OFF -DBUILD_outofcore=OFF -DBUILD_people=OFF -DBUILD_recognition=OFF -DBUILD_registration=OFF -DBUILD_sample_consensus=OFF -DBUILD_segmentation=OFF -DBUILD_features=OFF -DBUILD_surface_on_nurbs=OFF -DBUILD_tools=OFF -DBUILD_tracking=OFF -DBUILD_visualization=OFF -DWITH_QT=OFF -DBUILD_OPENNI=OFF -DBUILD_OPENNI2=OFF -DWITH_OPENNI=OFF -DWITH_OPENNI2=OFF -DWITH_FZAPI=OFF -DWITH_LIBUSB=OFF -DWITH_PCAP=OFF -DWITH_PXCAPI=OFF > "$TOOLS_LOG_PATH/pcl_1_build.log" 2>&1
echo " - building and installing pcl"
make install > "$TOOLS_LOG_PATH/pcl_2_build.log" 2>&1
echo " < done - `date`"
echo
echo " > meshing "
cd "$ODM_MESHING_PATH"
echo " - configuring odm_meshing"
cmake . -DPCL_DIR="$TOOLS_LIB_PATH/pcl" > "$TOOLS_LOG_PATH/odm_meshing_1_build.log" 2>&1
echo " - building odm_meshing"
make -j$CORES > "$TOOLS_LOG_PATH/odm_meshing_2_build.log" 2>&1
# copy output program to the binaries folder.
cp -f "odm_meshing" "$TOOLS_BIN_PATH/odm_meshing"
echo " < done - `date`"
echo
echo " > texturing "
cd "$ODM_TEXTURING_PATH"
echo " - configuring odm_texturing"
cmake . -DPCL_DIR="$TOOLS_LIB_PATH/pcl" > "$TOOLS_LOG_PATH/odm_texturing_1_build.log" 2>&1
echo " - building odm_texturing"
make -j$CORES > "$TOOLS_LOG_PATH/odm_texturing_2_build.log" 2>&1
# copy output program to the binaries folder.
cp -f "odm_texturing" "$TOOLS_BIN_PATH/odm_texturing"
echo " < done - `date`"
echo
echo " > extract_utm "
cd "$ODM_EXTRACT_UTM_PATH"
echo " - configuring odm_extract_utm"
cmake . > "$TOOLS_LOG_PATH/odm_extract_utm_1_build.log" 2>&1
echo " - building odm_extract_utm"
make -j$CORES > "$TOOLS_LOG_PATH/odm_extract_utm_2_build.log" 2>&1
# copy output program to the binaries folder.
cp -f "odm_extract_utm" "$TOOLS_BIN_PATH/odm_extract_utm"
echo " < done - `date`"
echo
echo " > georef "
cd "$ODM_GEOREF_PATH"
echo " - configuring odm_georef"
cmake . -DPCL_DIR="$TOOLS_LIB_PATH/pcl" > "$TOOLS_LOG_PATH/odm_georef_1_build.log" 2>&1
echo " - building odm_georef"
make -j$CORES > "$TOOLS_LOG_PATH/odm_georef_2_build.log" 2>&1
# copy output program to the binaries folder.
cp -f "odm_georef" "$TOOLS_BIN_PATH/odm_georef"
echo " < done - `date`"
echo
echo " > orthophoto "
cd "$ODM_ORTHOPHOTO_PATH"
echo " - configuring odm_orthophoto"
cmake . -DPCL_DIR="$TOOLS_LIB_PATH/pcl" > "$TOOLS_LOG_PATH/odm_orthophoto_1_build.log" 2>&1
echo " - building odm_orthophoto"
make -j$CORES > "$TOOLS_LOG_PATH/odm_orthophoto_2_build.log" 2>&1
# copy output program to the binaries folder.
cp -f "odm_orthophoto" "$TOOLS_BIN_PATH/odm_orthophoto"
echo " < done - `date`"
echo
echo " > OpenGV"
cd "$OPENGV_PATH"
echo " - configuring opengv"
git checkout python-wrapper
mkdir -p build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$TOOLS_PATH -DBUILD_TESTS=OFF -DBUILD_PYTHON=ON > "$TOOLS_LOG_PATH/opengv_1_build.log" 2>&1
echo " - building opengv"
make install > "$TOOLS_LOG_PATH/opengv_2_build.log" 2>&1
echo " < done - `date`"
echo
echo " > OpenSfM"
cd "$OPENSFM_PATH"
echo " - configuring opensfm"
git checkout odm-2
echo " - building opensfm"
CERES_ROOT_DIR=$TOOLS_PATH python setup.py build > "$TOOLS_LOG_PATH/opensfm_1_build.log" 2>&1
echo " < done - `date`"
echo
cd "$TOOLS_PATH"
sudo install -o `id -u` -g `id -g` -m 644 -t "$LIB_PATH" lib/*.so
sudo ldconfig -v > "$TOOLS_LOG_PATH/ldconfig.log" 2>&1
sudo chown -R `id -u`:`id -g` *
#sudo chmod -R 777 *
#sudo chmod 700 run.pl
echo " - script finished - `date`"
exit

20
js/cartodb.js 100644

File diff suppressed because one or more lines are too long

5
js/jquery.min.js vendored 100644

File diff suppressed because one or more lines are too long

50
js/script.js 100644
Wyświetl plik

@ -0,0 +1,50 @@
( function( $ ) {
$( document ).ready(function() {
$('#cssmenu').prepend('<div id="indicatorContainer"><div id="pIndicator"><div id="cIndicator"></div></div></div>');
var activeElement = $('#cssmenu>ul>li:first');
$('#cssmenu>ul>li').each(function() {
if ($(this).hasClass('active')) {
activeElement = $(this);
}
});
var posLeft = activeElement.position().left;
var elementWidth = activeElement.width();
posLeft = posLeft + elementWidth/2 -6;
if (activeElement.hasClass('has-sub')) {
posLeft -= 6;
}
$('#cssmenu #pIndicator').css('left', posLeft);
var element, leftPos, indicator = $('#cssmenu pIndicator');
$("#cssmenu>ul>li").hover(function() {
element = $(this);
var w = element.width();
if ($(this).hasClass('has-sub'))
{
leftPos = element.position().left + w/2 - 12;
}
else {
leftPos = element.position().left + w/2 - 6;
}
$('#cssmenu #pIndicator').css('left', leftPos);
}
, function() {
$('#cssmenu #pIndicator').css('left', posLeft);
});
$('#cssmenu>ul').prepend('<li id="menu-button"><a>Menu</a></li>');
$( "#menu-button" ).click(function(){
if ($(this).parent().hasClass('open')) {
$(this).parent().removeClass('open');
}
else {
$(this).parent().addClass('open');
}
});
});
} )( jQuery );

Wyświetl plik

@ -1,119 +0,0 @@
import os
import math
import subprocess
# Purpose:
# Preselect camera pairs for meature matching based by using GPS exif data.
def preselect_pairs(utm_extractor_path, image_list, k_distance, use_knn_mode = True, verbose = False):
# Parameterss:
# utm_extractor_path: Path to the odm utm_extraction program that parses exif data.
# images_path: Path to the folder containing the images.
# k_distance: Nearest neighbor count in case of use_knn_mode = True, otherwise
# the minimum distance between cameras to be matched.
# use_knn_mode: True if knn mode is used to preselect matches, False for distance thresholding.
# Temporary files
image_list_file = 'image_list_tmp.txt'
utm_coord_file = 'utm_coord_tmp.txt'
# Parse the list of files with successfullt detectd points.
image_folder = ""
filenames = []
with open(image_list, 'r') as keypoint_file:
first_line = keypoint_file.readline()
image_folder = first_line[:first_line.rfind("/")]
keypoint_file.seek(0)
for line in keypoint_file:
filename = line[line.rfind("/")+1:line.rfind(".")]
filename += ".jpg"
filenames.append(filename)
data = open(image_list_file, "w")
for filename in filenames:
data.write("%s\n" % filename)
data.close()
# Define call parameters for calling the odm_extract_utm module
utm_cmd = ''
if verbose:
utm_cmd = [utm_extractor_path, '-verbose', '-imagesPath', image_folder, \
'-imageListFile', image_list_file, '-outputCoordFile', utm_coord_file]
else:
utm_cmd = [utm_extractor_path, '-imagesPath', image_folder, '-imageListFile', \
image_list_file, '-outputCoordFile', utm_coord_file]
# Perform UTM extraction
utm_process = subprocess.Popen(utm_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output, err = utm_process.communicate()
# Check return code
if utm_process.returncode != 0:
print "Error when performing utm_extraction, dumping log file:"
print output
os.remove(image_list_file)
return []
# Parse odm_extract_utm output
coords = []
with open('utm_coord_tmp.txt', 'r') as coord_file:
# Skip header lines
next(coord_file)
next(coord_file)
for line in coord_file:
first_space = line.find(' ')
second_space = first_space + line[first_space+1:].find(' ')
xCoord = float(line[0: first_space])
yCoord = float(line[first_space+1: second_space+1])
coords.append([xCoord, yCoord])
# Calculate distances between camera pairs
distances = []
for xo,yo in coords:
distances.append([])
for xi, yi in coords:
current_image = len(distances)
xDist = xo-xi
yDist = yo-yi
distance = math.sqrt(xDist*xDist + yDist*yDist)
current_image = len(distances[-1])
distances[-1].append([current_image, distance, False])
distances[-1].sort(key=lambda tup: tup[1])
# Select matched pairs and make there are no doubles
matched_pairs = []
if use_knn_mode:
# Make sure that image count > k
if len(coords) <= k_distance:
print "Warning, k >= image count, the result will be equivalent to exhaustive matching"
k_distance = len(coords)-1
for outer_index, sorted_list in enumerate(distances):
# Skip first element as distance will always be zero
for sorted_index in xrange(1, k_distance+1):
image_index, distance, dummy = distances[outer_index][sorted_index]
is_added = distances[outer_index][image_index][2]
if not is_added:
matched_pairs.append([outer_index, image_index])
distances[outer_index][image_index][2] = True
distances[image_index][outer_index][2] = True
else: # Distance mode
for outer_index, sorted_list in enumerate(distances):
# Skip first element as distance will always be zero
for image_index, distance, dummy in sorted_list:
if outer_index == image_index:
continue
if distance > k_distance:
break
is_added = distances[outer_index][image_index][2]
if not is_added:
matched_pairs.append([outer_index, image_index])
distances[outer_index][image_index][2] = True
distances[image_index][outer_index][2] = True
# Remove temporary files
os.remove(image_list_file)
os.remove(utm_coord_file)
return matched_pairs

Wyświetl plik

@ -1,199 +0,0 @@
This package was downloaded from
http://xorg.freedesktop.org/releases/individual/lib/
Copyright 1986, 1987, 1988, 1989, 1994, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
Copyright (c) 1996 Digital Equipment Corporation, Maynard, Massachusetts.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Digital Equipment Corporation
shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization from Digital
Equipment Corporation.
Copyright (c) 1997 by Silicon Graphics Computer Systems, Inc.
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation, and that the name of Silicon Graphics not be
used in advertising or publicity pertaining to distribution
of the software without specific prior written permission.
Silicon Graphics makes no representation about the suitability
of this software for any purpose. It is provided "as is"
without any express or implied warranty.
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
THE USE OR PERFORMANCE OF THIS SOFTWARE.
Copyright 1992 Network Computing Devices
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of NCD. not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission. NCD. makes no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty.
NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Copyright 1991,1993 by Digital Equipment Corporation, Maynard, Massachusetts,
and Olivetti Research Limited, Cambridge, England.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Digital or Olivetti
not be used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
DIGITAL AND OLIVETTI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
Copyright 1986, 1987, 1988 by Hewlett-Packard Corporation
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation, and that the name of Hewlett-Packard not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
Hewlett-Packard makes no representations about the
suitability of this software for any purpose. It is provided
"as is" without express or implied warranty.
This software is not subject to any license of the American
Telephone and Telegraph Company or of the Regents of the
University of California.
Copyright (c) 1994, 1995 Hewlett-Packard Company
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the Hewlett-Packard
Company shall not be used in advertising or otherwise to promote the
sale, use or other dealings in this Software without prior written
authorization from the Hewlett-Packard Company.
Copyright Digital Equipment Corporation, 1996
Permission to use, copy, modify, distribute, and sell this
documentation for any purpose is hereby granted without fee,
provided that the above copyright notice and this permission
notice appear in all copies. Digital Equipment Corporation
makes no representations about the suitability for any purpose
of the information in this document. This documentation is
provided ``as is'' without express or implied warranty.
Copyright (c) 1999, 2005, 2006, Oracle and/or its affiliates. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Copyright (c) 1989 X Consortium, Inc. and Digital Equipment Corporation.
Copyright (c) 1992 X Consortium, Inc. and Intergraph Corporation.
Copyright (c) 1993 X Consortium, Inc. and Silicon Graphics, Inc.
Copyright (c) 1994, 1995 X Consortium, Inc. and Hewlett-Packard Company.
Permission to use, copy, modify, and distribute this documentation for
any purpose and without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
Digital Equipment Corporation, Intergraph Corporation, Silicon
Graphics, Hewlett-Packard, and the X Consortium make no
representations about the suitability for any purpose of the
information in this document. This documentation is provided ``as is''
without express or implied warranty.

Wyświetl plik

@ -1,944 +0,0 @@
This package was downloaded from
http://xorg.freedesktop.org/releases/individual/lib/
The following is the 'standard copyright' agreed upon by most contributors,
and is currently the canonical license preferred by the X.Org Foundation.
This is a slight variant of the common MIT license form published by the
Open Source Initiative at http://www.opensource.org/licenses/mit-license.php
Copyright holders of new code should use this license statement where
possible, and insert their name to this list. Please sort by surname
for people, and by the full name for other entities (e.g. Juliusz
Chroboczek sorts before Intel Corporation sorts before Daniel Stone).
See each individual source file or directory for the license that applies
to that file.
Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett
Copyright © 2009 Red Hat, Inc.
Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
The following licenses are 'legacy' - usually MIT/X11 licenses with the name
of the copyright holder(s) in the license statement:
Copyright 1984-1994, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
X Window System is a trademark of The Open Group.
----------------------------------------
Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1994, 1996 X Consortium
Copyright 2000 The XFree86 Project, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the X Consortium shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from the X Consortium.
Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 by
Digital Equipment Corporation
Portions Copyright 1990, 1991 by Tektronix, Inc.
Permission to use, copy, modify and distribute this documentation for
any purpose and without fee is hereby granted, provided that the above
copyright notice appears in all copies and that both that copyright notice
and this permission notice appear in all copies, and that the names of
Digital and Tektronix not be used in in advertising or publicity pertaining
to this documentation without specific, written prior permission.
Digital and Tektronix makes no representations about the suitability
of this documentation for any purpose.
It is provided ``as is'' without express or implied warranty.
----------------------------------------
Copyright (c) 1999-2000 Free Software Foundation, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
FREE SOFTWARE FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of the Free Software Foundation
shall not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization from the
Free Software Foundation.
----------------------------------------
Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
All Rights Reserved
This file is a component of an X Window System-specific implementation
of Xcms based on the TekColor Color Management System. TekColor is a
trademark of Tektronix, Inc. The term "TekHVC" designates a particular
color space that is the subject of U.S. Patent No. 4,985,853 (equivalent
foreign patents pending). Permission is hereby granted to use, copy,
modify, sell, and otherwise distribute this software and its
documentation for any purpose and without fee, provided that:
1. This copyright, permission, and disclaimer notice is reproduced in
all copies of this software and any modification thereof and in
supporting documentation;
2. Any color-handling application which displays TekHVC color
cooordinates identifies these as TekHVC color coordinates in any
interface that displays these coordinates and in any associated
documentation;
3. The term "TekHVC" is always used, and is only used, in association
with the mathematical derivations of the TekHVC Color Space,
including those provided in this file and any equivalent pathways and
mathematical derivations, regardless of digital (e.g., floating point
or integer) representation.
Tektronix makes no representation about the suitability of this software
for any purpose. It is provided "as is" and with all faults.
TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
(c) Copyright 1995 FUJITSU LIMITED
This is source code modified by FUJITSU LIMITED under the Joint
Development Agreement for the CDE/Motif PST.
----------------------------------------
Copyright 1992 by Oki Technosystems Laboratory, Inc.
Copyright 1992 by Fuji Xerox Co., Ltd.
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of Oki Technosystems
Laboratory and Fuji Xerox not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.
Oki Technosystems Laboratory and Fuji Xerox make no representations
about the suitability of this software for any purpose. It is provided
"as is" without express or implied warranty.
OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS
LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1990, 1991, 1992, 1993, 1994 by FUJITSU LIMITED
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of FUJITSU LIMITED
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
FUJITSU LIMITED makes no representations about the suitability of
this software for any purpose.
It is provided "as is" without express or implied warranty.
FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright (c) 1995 David E. Wexelblat. All rights reserved
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL DAVID E. WEXELBLAT BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of David E. Wexelblat shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from David E. Wexelblat.
----------------------------------------
Copyright 1990, 1991 by OMRON Corporation
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name OMRON not be used in
advertising or publicity pertaining to distribution of the software without
specific, written prior permission. OMRON makes no representations
about the suitability of this software for any purpose. It is provided
"as is" without express or implied warranty.
OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 by
Digital Equipment Corporation
Portions Copyright 1990, 1991 by Tektronix, Inc
Rewritten for X.org by Chris Lee <clee@freedesktop.org>
Permission to use, copy, modify, distribute, and sell this documentation
for any purpose and without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
Chris Lee makes no representations about the suitability for any purpose
of the information in this document. It is provided \`\`as-is'' without
express or implied warranty.
----------------------------------------
Copyright 1993 by Digital Equipment Corporation, Maynard, Massachusetts,
Copyright 1994 by FUJITSU LIMITED
Copyright 1994 by Sony Corporation
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Digital, FUJITSU
LIMITED and Sony Corporation not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission.
DIGITAL, FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL, FUJITSU LIMITED
AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1991 by the Open Software Foundation
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of Open Software Foundation
not be used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission. Open Software
Foundation makes no representations about the suitability of this
software for any purpose. It is provided "as is" without express or
implied warranty.
OPEN SOFTWARE FOUNDATION DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1990, 1991, 1992,1993, 1994 by FUJITSU LIMITED
Copyright 1993, 1994 by Sony Corporation
Permission to use, copy, modify, distribute, and sell this software and
its documentation for any purpose is hereby granted without fee, provided
that the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of FUJITSU LIMITED and Sony Corporation
not be used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission. FUJITSU LIMITED and
Sony Corporation makes no representations about the suitability of this
software for any purpose. It is provided "as is" without express or
implied warranty.
FUJITSU LIMITED AND SONY CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL FUJITSU LIMITED OR SONY CORPORATION BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright (c) 1993, 1995 by Silicon Graphics Computer Systems, Inc.
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation, and that the name of Silicon Graphics not be
used in advertising or publicity pertaining to distribution
of the software without specific prior written permission.
Silicon Graphics makes no representation about the suitability
of this software for any purpose. It is provided "as is"
without any express or implied warranty.
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1991, 1992, 1993, 1994 by FUJITSU LIMITED
Copyright 1993 by Digital Equipment Corporation
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of FUJITSU LIMITED and
Digital Equipment Corporation not be used in advertising or publicity
pertaining to distribution of the software without specific, written
prior permission. FUJITSU LIMITED and Digital Equipment Corporation
makes no representations about the suitability of this software for
any purpose. It is provided "as is" without express or implied
warranty.
FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION DISCLAIM ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
FUJITSU LIMITED AND DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
----------------------------------------
Copyright 1992, 1993 by FUJITSU LIMITED
Copyright 1993 by Fujitsu Open Systems Solutions, Inc.
Copyright 1994 by Sony Corporation
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of FUJITSU LIMITED,
Fujitsu Open Systems Solutions, Inc. and Sony Corporation not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
FUJITSU LIMITED, Fujitsu Open Systems Solutions, Inc. and
Sony Corporation make no representations about the suitability of
this software for any purpose. It is provided "as is" without
express or implied warranty.
FUJITSU LIMITED, FUJITSU OPEN SYSTEMS SOLUTIONS, INC. AND SONY
CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL FUJITSU OPEN SYSTEMS SOLUTIONS, INC., FUJITSU LIMITED
AND SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1987, 1988, 1990, 1993 by Digital Equipment Corporation,
Maynard, Massachusetts,
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
----------------------------------------
Copyright 1993 by SunSoft, Inc.
Copyright 1999-2000 by Bruno Haible
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the names of SunSoft, Inc. and
Bruno Haible not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission. SunSoft, Inc. and Bruno Haible make no representations
about the suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
SunSoft Inc. AND Bruno Haible DISCLAIM ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL SunSoft, Inc. OR Bruno Haible BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1991 by the Open Software Foundation
Copyright 1993 by the TOSHIBA Corp.
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the names of Open Software Foundation and TOSHIBA
not be used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission. Open Software
Foundation and TOSHIBA make no representations about the suitability of this
software for any purpose. It is provided "as is" without express or
implied warranty.
OPEN SOFTWARE FOUNDATION AND TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL OPEN SOFTWARE FOUNDATIONN OR TOSHIBA BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1988 by Wyse Technology, Inc., San Jose, Ca.,
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name Wyse not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
WYSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
----------------------------------------
Copyright 1991 by the Open Software Foundation
Copyright 1993, 1994 by the Sony Corporation
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the names of Open Software Foundation and
Sony Corporation not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
Open Software Foundation and Sony Corporation make no
representations about the suitability of this software for any purpose.
It is provided "as is" without express or implied warranty.
OPEN SOFTWARE FOUNDATION AND SONY CORPORATION DISCLAIM ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OPEN
SOFTWARE FOUNDATIONN OR SONY CORPORATION BE LIABLE FOR ANY SPECIAL,
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1992, 1993 by FUJITSU LIMITED
Copyright 1993 by Fujitsu Open Systems Solutions, Inc.
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of FUJITSU LIMITED and
Fujitsu Open Systems Solutions, Inc. not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission.
FUJITSU LIMITED and Fujitsu Open Systems Solutions, Inc. makes no
representations about the suitability of this software for any purpose.
It is provided "as is" without express or implied warranty.
FUJITSU LIMITED AND FUJITSU OPEN SYSTEMS SOLUTIONS, INC. DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJITSU OPEN SYSTEMS
SOLUTIONS, INC. AND FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
----------------------------------------
Copyright 1993, 1994 by Sony Corporation
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of Sony Corporation
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
Sony Corporation makes no representations about the suitability of
this software for any purpose. It is provided "as is" without
express or implied warranty.
SONY CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1986, 1998 The Open Group
Copyright (c) 2000 The XFree86 Project, Inc.
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
X CONSORTIUM OR THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Except as contained in this notice, the name of the X Consortium or of the
XFree86 Project shall not be used in advertising or otherwise to promote the
sale, use or other dealings in this Software without prior written
authorization from the X Consortium and the XFree86 Project.
----------------------------------------
Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
and Nippon Telegraph and Telephone Corporation
Copyright 1991 by the Open Software Foundation
Copyright 1993 by the FUJITSU LIMITED
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the names of OMRON, NTT Software, NTT, and
Open Software Foundation not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. OMRON, NTT Software, NTT, and Open Software
Foundation make no representations about the suitability of this
software for any purpose. It is provided "as is" without express or
implied warranty.
OMRON, NTT SOFTWARE, NTT, AND OPEN SOFTWARE FOUNDATION
DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
SHALL OMRON, NTT SOFTWARE, NTT, OR OPEN SOFTWARE FOUNDATION BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1988 by Wyse Technology, Inc., San Jose, Ca,
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL DIGITAL OR WYSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 1991, 1992 by Fuji Xerox Co., Ltd.
Copyright 1992, 1993, 1994 by FUJITSU LIMITED
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of Fuji Xerox,
FUJITSU LIMITED not be used in advertising or publicity pertaining
to distribution of the software without specific, written prior
permission. Fuji Xerox, FUJITSU LIMITED make no representations
about the suitability of this software for any purpose.
It is provided "as is" without express or implied warranty.
FUJI XEROX, FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX,
FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 2006 Josh Triplett
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------
(c) Copyright 1996 by Sebastien Marineau and Holger Veit
<marineau@genie.uottawa.ca>
<Holger.Veit@gmd.de>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Except as contained in this notice, the name of Sebastien Marineau or Holger Veit
shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization from Holger Veit or
Sebastien Marineau.
----------------------------------------
Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
and Nippon Telegraph and Telephone Corporation
Copyright 1991 by the Open Software Foundation
Copyright 1993 by the TOSHIBA Corp.
Copyright 1993, 1994 by Sony Corporation
Copyright 1993, 1994 by the FUJITSU LIMITED
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the names of OMRON, NTT Software, NTT, Open
Software Foundation, and Sony Corporation not be used in advertising
or publicity pertaining to distribution of the software without specific,
written prior permission. OMRON, NTT Software, NTT, Open Software
Foundation, and Sony Corporation make no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty.
OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, AND SONY
CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
SHALL OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, OR SONY
CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright 2000 by Bruno Haible
Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear
in supporting documentation, and that the name of Bruno Haible not
be used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission. Bruno Haible
makes no representations about the suitability of this software for
any purpose. It is provided "as is" without express or implied
warranty.
Bruno Haible DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
NO EVENT SHALL Bruno Haible BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright © 2003 Keith Packard
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of Keith Packard not be used in
advertising or publicity pertaining to distribution of the software without
specific, written prior permission. Keith Packard makes no
representations about the suitability of this software for any purpose. It
is provided "as is" without express or implied warranty.
KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
----------------------------------------
Copyright (c) 2007-2009, Troy D. Hanson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------
Copyright 1992, 1993 by TOSHIBA Corp.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided
that the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of TOSHIBA not be used in advertising
or publicity pertaining to distribution of the software without specific,
written prior permission. TOSHIBA make no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty.
TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
----------------------------------------
Copyright IBM Corporation 1993
All Rights Reserved
License to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of IBM not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND
NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
----------------------------------------
Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
and Nippon Telegraph and Telephone Corporation
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the names of OMRON, NTT Software, and NTT
not be used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission. OMRON, NTT Software,
and NTT make no representations about the suitability of this
software for any purpose. It is provided "as is" without express or
implied warranty.
OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT, BE
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Wyświetl plik

@ -1,26 +0,0 @@
Licensing for portions of OpenDroneMap are as follows:
* ImageMagick - Apache 2.0 - http://www.imagemagick.org/script/license.php
* Jhead - None - http://www.sentex.net/~mwandel/jhead/
* libjpeg - GPLv2 - http://sourceforge.net/projects/libjpeg/
* Boost - Boost Software License, Version 1.0 - http://www.boost.org/LICENSE_1_0.txt
* libgsl0 - GPL - http://www.gnu.org/software/gsl/
* liblapack - Modified BSD - http://www.netlib.org/lapack/LICENSE.txt
* Flann - BSD2 - http://opensource.org/licenses/bsd-license.php
* libzip - BSD - http://www.nih.at/libzip/LICENSE.html
* libcv - BSD - http://opencv.org/license.html
* libcvaux - BSD - http://opencv.org/license.html
* bundler - GPLv3 - http://www.gnu.org/copyleft/gpl.html
* cmvs - GPLv3 - http://www.gnu.org/copyleft/gpl.html
* pmvs2 - GPLv3 - http://www.gnu.org/copyleft/gpl.html
* parallel - GPLv3 - http://www.gnu.org/copyleft/gpl.html
* PoissonRecon - BSD - http://www.cs.jhu.edu/~misha/Code/PoissonRecon/license.txt
* vlfeat - BSD - http://www.vlfeat.org/license.html
* graclus - GPLv3 - http://www.gnu.org/copyleft/gpl.html
* PROJ.4 - MIT - http://trac.osgeo.org/proj/wiki/WikiStart#License
* PCL - BSD - http://pointclouds.org
* Flann - BSD2 - http://opensource.org/licenses/bsd-license.php
* Eigen - MPL2 - http://www.mozilla.org/MPL/2.0
* Qhull - http://www.qhull.org/COPYING.txt
* vtk5 - BSD - http://www.vtk.org/VTK/project/license.html
* libext - https://github.com/OpenDroneMap/OpenDroneMap/blob/gh-pages/licenses/libext_copyright.txt
* libx11 - https://github.com/OpenDroneMap/OpenDroneMap/blob/gh-pages/licenses/libx11_copyright.txt

Wyświetl plik

@ -1,18 +0,0 @@
project(odm_extract_utm)
cmake_minimum_required(VERSION 2.8)
set(PROJ4_INCLUDE_DIR "/usr/include/" CACHE "PROJ4_INCLUDE_DIR" "Path to the proj4 inlcude directory")
set(PROJ4_LIBRARY "/usr/lib/libproj.so" CACHE "PROJ4_LIBRARY" "Path to the proj4 library directory")
# Add compiler options.
add_definitions(-Wall -Wextra)
# Add source directory
aux_source_directory("./src" SRC_LIST)
# Add exectuteable
add_executable(${PROJECT_NAME} ${SRC_LIST})
# Link
target_link_libraries(${PROJECT_NAME} ${PROJ4_LIBRARY})

Wyświetl plik

@ -1,31 +0,0 @@
#include "Logger.hpp"
Logger::Logger(bool isPrintingInCout) : isPrintingInCout_(isPrintingInCout)
{
}
Logger::~Logger()
{
}
void Logger::printToFile(std::string filePath)
{
std::ofstream file(filePath.c_str(), std::ios::binary);
file << logStream_.str();
file.close();
}
bool Logger::isPrintingInCout() const
{
return isPrintingInCout_;
}
void Logger::setIsPrintingInCout(bool isPrintingInCout)
{
isPrintingInCout_ = isPrintingInCout;
}

Wyświetl plik

@ -1,68 +0,0 @@
#pragma once
// STL
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
/*!
* \brief The Logger class is used to store program messages in a log file.
* \details By using the << operator while printInCout is set, the class writes both to
* cout and to file, if the flag is not set, output is written to file only.
*/
class Logger
{
public:
/*!
* \brief Logger Contains functionality for printing and displaying log information.
* \param printInCout Flag toggling if operator << also writes to cout.
*/
Logger(bool isPrintingInCout = true);
/*!
* \brief Destructor.
*/
~Logger();
/*!
* \brief print Prints the contents of the log to file.
* \param filePath Path specifying where to write the log.
*/
void printToFile(std::string filePath);
/*!
* \brief isPrintingInCout Check if console printing flag is set.
* \return Console printing flag.
*/
bool isPrintingInCout() const;
/*!
* \brief setIsPrintingInCout Set console printing flag.
* \param isPrintingInCout Value, if true, messages added to the log are also printed in cout.
*/
void setIsPrintingInCout(bool isPrintingInCout);
/*!
* Operator for printing messages to log and in the standard output stream if desired.
*/
template<class T>
friend Logger& operator<< (Logger &log, T t)
{
// If console printing is enabled.
if (log.isPrintingInCout_)
{
std::cout << t;
std::cout.flush();
}
// Write to log.
log.logStream_ << t;
return log;
}
private:
bool isPrintingInCout_; /*!< If flag is set, log is printed in cout and written to the log. */
std::stringstream logStream_; /*!< Stream for storing the log. */
};

Wyświetl plik

@ -1,383 +0,0 @@
// STL
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include <cstdlib>
#include <stdio.h>
#include <ctype.h>
#include <sstream>
#include <math.h>
// Proj4
#include <proj_api.h>
// This
#include "UtmExtractor.hpp"
UtmExtractor::UtmExtractor() : log_(false)
{
logFile_ = "odm_extracting_utm_log.txt";
}
UtmExtractor::~UtmExtractor()
{
}
int UtmExtractor::run(int argc, char **argv)
{
if (argc <= 1)
{
printHelp();
return EXIT_SUCCESS;
}
try
{
parseArguments(argc, argv);
extractUtm();
}
catch (const UtmExtractorException& e)
{
log_.setIsPrintingInCout(true);
log_ << e.what() << "\n";
log_.printToFile(logFile_);
log_ << "For more detailed information, see log file." << "\n";
return EXIT_FAILURE;
}
catch (const std::exception& e)
{
log_.setIsPrintingInCout(true);
log_ << "Error in OdmExtractUtm:\n";
log_ << e.what() << "\n";
log_.printToFile(logFile_);
log_ << "For more detailed information, see log file." << "\n";
return EXIT_FAILURE;
}
catch (...)
{
log_.setIsPrintingInCout(true);
log_ << "Unknown error in OdmExtractUtm:\n";
log_.printToFile(logFile_);
log_ << "For more detailed information, see log file." << "\n";
return EXIT_FAILURE;
}
log_.printToFile(logFile_);
return EXIT_SUCCESS;
}
void UtmExtractor::parseArguments(int argc, char **argv)
{
for(int argIndex = 1; argIndex < argc; ++argIndex)
{
// The argument to be parsed
std::string argument = std::string(argv[argIndex]);
if (argument == "-help")
{
printHelp();
}
else if (argument == "-verbose")
{
log_.setIsPrintingInCout(true);
}
else if (argument == "-imageListFile")
{
++argIndex;
if (argIndex >= argc)
{
throw UtmExtractorException("Missing argument for '" + argument + "'.");
}
imageListFileName_ = std::string(argv[argIndex]);
std::ifstream testFile(imageListFileName_.c_str(), std::ios_base::binary);
if (!testFile.is_open())
{
throw UtmExtractorException("Argument '" + argument + "' has a bad value (file not accessible).");
}
log_ << "imageListFile was set to: " << imageListFileName_ << "\n";
}
else if (argument == "-imagesPath")
{
++argIndex;
if (argIndex >= argc)
{
throw UtmExtractorException("Missing argument for '" + argument + "'.");
}
std::stringstream ss(argv[argIndex]);
ss >> imagesPath_;
if (ss.bad())
{
throw UtmExtractorException("Argument '" + argument + "' has a bad value. (wrong type)");
}
log_ << "imagesPath was set to: " << imagesPath_ << "\n";
}
else if (argument == "-outputCoordFile")
{
++argIndex;
if (argIndex >= argc)
{
throw UtmExtractorException("Missing argument for '" + argument + "'.");
}
std::stringstream ss(argv[argIndex]);
ss >> outputCoordFileName_;
if (ss.bad())
{
throw UtmExtractorException("Argument '" + argument + "' has a bad value. (wrong type)");
}
log_ << "outputCoordFile was set to: " << outputCoordFileName_ << "\n";
}
else if (argument == "-logFile")
{
++argIndex;
if (argIndex >= argc)
{
throw UtmExtractorException("Missing argument for '" + argument + "'.");
}
std::stringstream ss(argv[argIndex]);
ss >> logFile_;
if (ss.bad())
{
throw UtmExtractorException("Argument '" + argument + "' has a bad value. (wrong type)");
}
log_ << "logFile_ was set to: " << logFile_ << "\n";
}
else
{
printHelp();
throw UtmExtractorException("Unrecognised argument '" + argument + "'.");
}
}
}
void UtmExtractor::extractUtm()
{
// Open file listing all used camera images
std::ifstream imageListStream(imageListFileName_.c_str());
if (!imageListStream.good()) {
throw UtmExtractorException("Failed to open " + imageListFileName_ + " for reading.");
}
// Traverse images
int utmZone = 99; // for auto-select
char hemisphere;
std::string imageFilename;
std::vector<Coord> coords;
while (getline(imageListStream, imageFilename)) {
// Run jhead on image to extract EXIF data to temporary file
std::string commandLine = "jhead -v " + imagesPath_ + "/" + imageFilename + " > extract_utm_output.txt";
system(commandLine.c_str());
// Read temporary EXIF data file
std::ifstream jheadDataStream;
jheadDataStream.open("extract_utm_output.txt");
if (!jheadDataStream.good()) {
throw UtmExtractorException("Failed to open temporary jhead data file extract_utm_output.txt");
}
// Delete temporary file
remove("extract_utm_output.txt");
// Parse jhead output
double lon, lat, alt;
if (!parsePosition(jheadDataStream, lon, lat, alt)) {
throw UtmExtractorException("Failed parsing GPS position.");
jheadDataStream.close();
}
jheadDataStream.close();
// Convert to UTM
double x, y, z;
convert(lon, lat, alt, x, y, z, utmZone, hemisphere);
coords.push_back(Coord(x, y, z));
}
imageListStream.close();
// Calculate average
double dx = 0.0, dy = 0.0;
double num = static_cast<double>(coords.size());
for (std::vector<Coord>::iterator iter = coords.begin(); iter != coords.end(); ++iter) {
dx += iter->x/num;
dy += iter->y/num;
}
dx = floor(dx);
dy = floor(dy);
// Open output file
std::ofstream outputCoordStream(outputCoordFileName_.c_str());
if (!outputCoordStream.good()) {
throw UtmExtractorException("Failed to openg " + outputCoordFileName_ + " for writing.");
}
outputCoordStream.precision(10);
// Write coordinate file
outputCoordStream << "WGS84 UTM " << utmZone << hemisphere << std::endl;
outputCoordStream << dx << " " << dy << std::endl;
for (std::vector<Coord>::iterator iter = coords.begin(); iter != coords.end(); ++iter) {
outputCoordStream << (iter->x - dx) << " " << (iter->y - dy) << " " << iter->z << std::endl;
}
outputCoordStream.close();
}
bool UtmExtractor::convert(const double &lon, const double &lat, const double &alt, double &x, double &y, double &z, int &utmZone, char &hemisphere)
{
x = y = z = 0.0;
// Create WGS84 longitude/latitude coordinate system
projPJ pjLatLon = pj_init_plus("+proj=latlong +datum=WGS84");
if (!pjLatLon) {
throw UtmExtractorException("Couldn't create WGS84 coordinate system with PROJ.4.");
return false;
}
// Calculate UTM zone if it's set to magic 99
// NOTE: Special UTM cases in Norway/Svalbard not supported here
if (utmZone == 99) {
utmZone = ((static_cast<int>(floor((lon + 180.0)/6.0)) % 60) + 1);
if (lat < 0)
hemisphere = 'S';
else
hemisphere = 'N';
}
std::ostringstream ostr;
ostr << utmZone;
if (hemisphere == 'S')
ostr << " +south";
// Create UTM coordinate system
projPJ pjUtm = pj_init_plus(("+proj=utm +datum=WGS84 +zone=" + ostr.str()).c_str());
if (!pjUtm) {
throw UtmExtractorException("Couldn't create UTM coordinate system with PROJ.4.");
return false;
}
// Convert to radians
x = lon * DEG_TO_RAD;
y = lat * DEG_TO_RAD;
z = alt;
// Transform
int res = pj_transform(pjLatLon, pjUtm, 1, 1, &x, &y, &z);
if (res != 0) {
throw UtmExtractorException("Failed to transform coordinates");
return false;
}
return true;
}
bool UtmExtractor::parsePosition(std::ifstream &jheadStream, double &lon, double &lat, double &alt)
{
lon = lat = alt = 0.0;
// Parse position
std::string str;
std::string latStr, lonStr, altStr;
while (std::getline(jheadStream, str))
{
size_t index = str.find("GPS Latitude : ");
if (index != std::string::npos)
{
latStr = str.substr(index + 15);
size_t find = latStr.find_first_of("0123456789");
if(std::string::npos == find)
{
throw UtmExtractorException("Image is missing GPS Latitude data");
}
}
index = str.find("GPS Longitude: ");
if (index != std::string::npos)
{
lonStr = str.substr(index + 15);
size_t find = lonStr.find_first_of("0123456789");
if(std::string::npos == find)
{
throw UtmExtractorException("Image is missing GPS Latitude data");
}
}
index = str.find("GPSAltitude");
if (index != std::string::npos)
{
altStr = str.substr(index + 12);
size_t find = altStr.find_first_of("0123456789");
if(std::string::npos == find)
{
throw UtmExtractorException("Image is missing GPS Latitude data");
}
}
}
if (lonStr.empty() || latStr.empty()) {
throw UtmExtractorException("No valid GPS position found");
return false;
}
// Parse longitude
std::string hemisphere;
double degrees, minutes, seconds;
std::istringstream istr(lonStr);
char degChar = 'd', minChar = 'm', secChar = 's';
istr >> hemisphere >> degrees >> degChar >> minutes >> minChar >> seconds >> secChar;
lon = (hemisphere == "W" ? -1 : 1) * (degrees + minutes/60.0 + seconds/3600.0);
// Parse latitude
istr.clear();
istr.str(latStr);
istr >> hemisphere >> degrees >> degChar >> minutes >> minChar >> seconds >> secChar;
lat = (hemisphere == "S" ? -1 : 1) * (degrees + minutes/60.0 + seconds/3600.0);
if (!altStr.empty())
{
size_t index = altStr.find_last_of("=");
if (index != std::string::npos)
{
altStr = altStr.substr(index + 1);
istr.clear();
istr.str(altStr);
char dummyChar;
int nominator, denominator;
istr >> nominator;
istr >> dummyChar;
istr >> denominator;
alt = static_cast<double>(nominator)/static_cast<double>(denominator);
}
}
return true;
}
void UtmExtractor::printHelp()
{
log_.setIsPrintingInCout(true);
log_ << "Purpose:\n";
log_ << "Create a coordinate file containing the GPS positions of all cameras to be used later in the ODM toolchain for automatic georeferecing.\n";
log_ << "Usage:\n";
log_ << "The program requires paths to a image list file, a image folder path and an output textfile to store the results.\n";
log_ << "The following flags are available:\n";
log_ << "Call the program with flag \"-help\", or without parameters to print this message, or check any generated log file.\n";
log_ << "Call the program with flag \"-verbose\", to print log messages in the standard output.\n\n";
log_ << "Parameters are specified as: \"-<argument name> <argument>\", (without <>), and the following parameters are configurable:\n";
log_ << "\"-imageListFile <path>\" (mandatory)\n";
log_ << "Path to the list containing the image names used in the bundle.out file.\n";
log_ << "\"-imagesPath <path>\" (mandatory)\n";
log_ << "Path folder containing all images in the imageListFile.\n";
log_ << "\"-outputCoordFile <path>\" (mandatory)\n";
log_ << "Path output textfile.\n";
log_.setIsPrintingInCout(false);
}

Wyświetl plik

@ -1,96 +0,0 @@
#pragma once
// Logging
#include "Logger.hpp"
/*!
* \breif The Coord struct Class used in UtmExtractor to extract GPS positions from images and ODM output
*/
struct Coord
{
double x, y, z;
Coord(double ix, double iy, double iz) : x(ix), y(iy), z(iz) {}
};
class UtmExtractor
{
public:
UtmExtractor();
~UtmExtractor();
/*!
* \brief run Runs the texturing functionality using the provided input arguments.
* For a list of the accepted arguments, please see the main page documentation or
* call the program with parameter "-help".
* \param argc Application argument count.
* \param argv Argument values.
* \return 0 if successful.
*/
int run (int argc, char **argv);
private:
/*!
* \brief parseArguments Parses command line arguments.
* \param argc Application argument count.
* \param argv Argument values.
*/
void parseArguments(int argc, char **argv);
/*!
* \breif extractUtm Performs the extraction of coordinates inside the run function.
*/
void extractUtm();
/*!
* /brief Static method that converts a WGS84 longitude/latitude coordinate in decimal degrees to UTM.
*
* \param lon The longitude in decimal degrees (negative if western hemisphere).
* \param lat The latitude in decimal degrees (negative if southern hemisphere).
* \param alt The altitude in meters.
* \param x Output parameter, the easting UTM value in meters.
* \param y Output parameter, the northing UTM value in meters.
* \param utmZone Input or output parameter, the UTM zone. Set to 99 for automatic selection.
* \param hemisphere Input or output parameter, 'N' for norther hemisphere, 'S' for southern. Automatically selected if utmZone is 99.
*
* \returns True if successful (otherwise output parameters are 0)
*/
static bool convert(const double &lon, const double &lat, const double &alt, double &x, double &y, double &z, int &utmZone, char &hemisphere);
/*!
* \brief Static method that parses a GPS position from jhead data.
*
* \param jheadDataStream Jhead data stream with EXIF information.
* \param lon Output parameter, the longitude in decimal degrees.
* \param lat Output parameter, the latitude in decimal degrees.
* \param alt Output parameter, the altitude in meters.
*
* \returns True if successful (otherwise output parameters are 0)
*/
static bool parsePosition(std::ifstream &jheadStream, double &lon, double &lat, double &alt);
/*!
* \brief printHelp Prints help, explaining usage. Can be shown by calling the program with arguments: "-help".
*/
void printHelp();
std::string imageListFileName_; /**< Path to the image list. */
std::string outputCoordFileName_; /**< Path to the file to store the output textfile. */
std::string imagesPath_; /**< Path to the folder with all images in the image list. */
Logger log_; /**< Logging object. */
std::string logFile_; /**< Path to store the log file. */
};
class UtmExtractorException : public std::exception
{
public:
UtmExtractorException() : message("Error in OdmExtractUtm") {}
UtmExtractorException(std::string msgInit) : message("Error in OdmExtractUtm:\n" + msgInit) {}
~UtmExtractorException() throw() {}
virtual const char* what() const throw() {return message.c_str(); }
private:
std::string message; /**< The error message. */
};

Wyświetl plik

@ -1,9 +0,0 @@
#include "UtmExtractor.hpp"
int main (int argc, char **argv)
{
UtmExtractor utmExtractor;
return utmExtractor.run(argc, argv);
}

Wyświetl plik

@ -1,35 +0,0 @@
project(odm_georef)
cmake_minimum_required(VERSION 2.8)
# Set pcl dir to the input spedified with option -DPCL_DIR="path"
set(PCL_DIR "PCL_DIR-NOTFOUND" CACHE "PCL_DIR" "Path to the pcl installation directory")
set(OPENCV_DIR "OPENCV_DIR-NOTFOUND" CACHE "OPENCV_DIR" "Path to the opencv installation directory")
set(PROJ4_INCLUDE_DIR "/usr/include/" CACHE "PROJ4_INCLUDE_DIR" "Path to the proj4 inlcude directory")
set(PROJ4_LIBRARY "/usr/lib/libproj.so" CACHE "PROJ4_LIBRARY" "Path to the proj4 library directory")
# Add compiler options.
add_definitions(-Wall -Wextra -Wconversion -pedantic)
#add_definitions(-pedantic -pedantic-errors -Wall -Wextra -Werror -Wfatal-errors -Wabi -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Weffc++ -Wstrict-null-sentinel -Wnon-template-friend -Wold-style-cast -Woverloaded-virtual -Wpmf-conversions -Wsign-promo -Waddress -Warray-bounds -Wattributes -Wbuiltin-macro-redefined -Wc++0x-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wclobbered -Wcomment -Wconversion -Wcoverage-mismatch -Wdeprecated -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wempty-body -Wenum-compare -Wendif-labels -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 -Wformat-contains-nul -Wformat-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wignored-qualifiers -Winit-self -Wint-to-pointer-cast -Winvalid-offsetof -Winvalid-pch -Wlogical-op -Wmain -Wvariadic-macros -Wmissing-braces -Wmissing-field-initializers -Wmissing-include-dirs -Wmissing-noreturn -Wvla -Wmultichar -Wfatal-errors -Wnonnull -Woverflow -Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wparentheses -Wpointer-arith -Wredundant-decls -Wsequence-point -Wshadow -Wsign-compare -Wsign-conversion -Wstack-protector -Wstrict-overflow=5 -Wswitch -Wswitch-enum -Wsync-nand -Wvolatile-register-var -Wtrigraphs -Wtype-limits -Wuninitialized -Wunknown-pragmas -Wwrite-strings -Wpragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wno-return-type)
# Find pcl at the location specified by PCL_DIR
find_package(PCL 1.7 HINTS "${PCL_DIR}/share/pcl-1.7")
# Find OpenCV at the default location
find_package(OpenCV HINTS "${OPENCV_DIR}" REQUIRED)
# Only link with required opencv modules.
set(OpenCV_LIBS opencv_core opencv_imgproc opencv_highgui)
# Add the PCL and Eigen include dirs.
# Necessary since the PCL_INCLUDE_DIR variable set bu find_package is broken.)
include_directories(${PCL_ROOT}/include/pcl-${PCL_VERSION_MAJOR}.${PCL_VERSION_MINOR})
include_directories(${EIGEN_ROOT})
# Add source directory
aux_source_directory("./src" SRC_LIST)
# Add exectuteable
add_executable(${PROJECT_NAME} ${SRC_LIST})
# Link
target_link_libraries(${PROJECT_NAME} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_SURFACE_LIBRARIES} ${PROJ4_LIBRARY} ${OpenCV_LIBS})

Wyświetl plik

@ -1,203 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by Qt Creator 2.4.1, 2015-02-03T10:36:15. -->
<qtcreator>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QString" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QString" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">System</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.DefaultCMakeTarget</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory">/home/spotscale/odm/OpenDroneMap-texturing_orthophoto_spotscale_additions/odm_georef-build</value>
<value type="QString" key="CMakeProjectManager.CMakeBuildConfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-32bit./usr/bin/gdb</value>
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-32bit./usr/bin/gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="CMakeProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments">clean</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="CMakeProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">all</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">No deployment</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Project.UseGlobal">true</value>
<value type="bool" key="Analyzer.Project.UseGlobal">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="CMakeProjectManager.BaseEnvironmentBase">2</value>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguation.Title">odm_georef</value>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.Arguments">-verbose -bundleFile ../../../shared_folder/seneca/reconstruction-with-image-size-1200/pmvs/bundle.rd.out -inputFile ../../../shared_folder/seneca/reconstruction-with-image-size-1200-results/odm_texturing/odm_textured_model.obj -imagesListPath ../../../shared_folder/seneca/reconstruction-with-image-size-1200/pmvs/list.rd.txt -gcpFile ../../../shared_folder/seneca_georef_input/gcp_list.txt -imagesPath ../../../shared_folder/seneca/ -bundleResizedTo 1200</value>
<value type="bool" key="CMakeProjectManager.CMakeRunConfiguration.UseTerminal">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.CMakeRunConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">odm_georef</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
<value type="QString">{785a73be-b55f-490c-9d46-e1451c235840}</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">10</value>
</data>
</qtcreator>

Wyświetl plik

@ -1,149 +0,0 @@
// This
#include "FindTransform.hpp"
Vec3::Vec3(double x, double y, double z) :x_(x), y_(y), z_(z)
{
}
Vec3::Vec3(const Vec3 &o) : x_(o.x_), y_(o.y_), z_(o.z_)
{
}
Vec3 Vec3::cross(Vec3 o) const
{
Vec3 res;
res.x_ = y_*o.z_ - z_*o.y_;
res.y_ = z_*o.x_ - x_*o.z_;
res.z_ = x_*o.y_ - y_*o.x_;
return res;
}
double Vec3::dot(Vec3 o) const
{
return x_*o.x_ + y_*o.y_ + z_*o.z_;
}
double Vec3::length() const
{
return sqrt(x_*x_ + y_*y_ + z_*z_);
}
Vec3 Vec3::norm() const
{
Vec3 res;
double l = length();
res.x_ = x_ / l;
res.y_ = y_ / l;
res.z_ = z_ / l;
return res;
}
Vec3 Vec3::operator*(double d) const
{
return Vec3(x_*d, y_*d, z_*d);
}
Vec3 Vec3::operator+(Vec3 o) const
{
return Vec3(x_ + o.x_, y_ + o.y_,z_ + o.z_);
}
Vec3 Vec3::operator-(Vec3 o) const
{
return Vec3(x_ - o.x_, y_ - o.y_,z_ - o.z_);
}
OnMat3::OnMat3(Vec3 r1, Vec3 r2, Vec3 r3) : r1_(r1), r2_(r2), r3_(r3)
{
c1_.x_ = r1_.x_; c2_.x_ = r1_.y_; c3_.x_ = r1_.z_;
c1_.y_ = r2_.x_; c2_.y_ = r2_.y_; c3_.y_ = r2_.z_;
c1_.z_ = r3_.x_; c2_.z_ = r3_.y_; c3_.z_ = r3_.z_;
}
OnMat3::OnMat3(const OnMat3 &o) : r1_(o.r1_), r2_(o.r2_), r3_(o.r3_)
{
c1_.x_ = r1_.x_; c2_.x_ = r1_.y_; c3_.x_ = r1_.z_;
c1_.y_ = r2_.x_; c2_.y_ = r2_.y_; c3_.y_ = r2_.z_;
c1_.z_ = r3_.x_; c2_.z_ = r3_.y_; c3_.z_ = r3_.z_;
}
double OnMat3::det() const
{
return r1_.x_*r2_.y_*r3_.z_ + r1_.y_*r2_.z_*r3_.x_ + r1_.z_*r2_.x_*r3_.y_ - r1_.z_*r2_.y_*r3_.x_ - r1_.y_*r2_.x_*r3_.z_ - r1_.x_*r2_.z_*r3_.y_;
}
OnMat3 OnMat3::transpose() const
{
return OnMat3(Vec3(r1_.x_, r2_.x_, r3_.x_), Vec3(r1_.y_, r2_.y_, r3_.y_), Vec3(r1_.z_, r2_.z_, r3_.z_));
}
OnMat3 OnMat3::operator*(OnMat3 o) const
{
return OnMat3( Vec3(r1_.dot(o.c1_), r1_.dot(o.c2_), r1_.dot(o.c3_)),
Vec3(r2_.dot(o.c1_), r2_.dot(o.c2_), r2_.dot(o.c3_)),
Vec3(r3_.dot(o.c1_), r3_.dot(o.c2_), r3_.dot(o.c3_)));
}
Vec3 OnMat3::operator*(Vec3 o)
{
return Vec3(r1_.dot(o), r2_.dot(o), r3_.dot(o));
}
Mat4::Mat4()
{
r1c1_ = 1.0; r1c2_ = 0.0; r1c3_ = 0.0; r1c4_ = 0.0;
r2c1_ = 0.0; r2c2_ = 1.0; r2c3_ = 0.0; r2c4_ = 0.0;
r3c1_ = 0.0; r3c2_ = 0.0; r3c3_ = 1.0; r3c4_ = 0.0;
r4c1_ = 0.0; r4c2_ = 0.0; r4c3_ = 0.0; r4c4_ = 1.0;
}
Mat4::Mat4(OnMat3 rotation, Vec3 translation, double scaling)
{
r1c1_ = scaling * rotation.r1_.x_; r1c2_ = scaling * rotation.r1_.y_; r1c3_ = scaling * rotation.r1_.z_; r1c4_ = translation.x_;
r2c1_ = scaling * rotation.r2_.x_; r2c2_ = scaling * rotation.r2_.y_; r2c3_ = scaling * rotation.r2_.z_; r2c4_ = translation.y_;
r3c1_ = scaling * rotation.r3_.x_; r3c2_ = scaling * rotation.r3_.y_; r3c3_ = scaling * rotation.r3_.z_; r3c4_ = translation.z_;
r4c1_ = 0.0; r4c2_ = 0.0; r4c3_ = 0.0; r4c4_ = 1.0;
}
Vec3 Mat4::operator*(Vec3 o)
{
return Vec3(
r1c1_ * o.x_ + r1c2_* o.y_ + r1c3_* o.z_ + r1c4_,
r2c1_ * o.x_ + r2c2_* o.y_ + r2c3_* o.z_ + r2c4_,
r3c1_ * o.x_ + r3c2_* o.y_ + r3c3_* o.z_ + r3c4_
);
}
void FindTransform::findTransform(Vec3 fromA, Vec3 fromB, Vec3 fromC, Vec3 toA, Vec3 toB, Vec3 toC)
{
Vec3 a1 = toA;
Vec3 b1 = toB;
Vec3 c1 = toC;
Vec3 a2 = fromA;
Vec3 b2 = fromB;
Vec3 c2 = fromC;
Vec3 y1 = (a1 - c1).cross(b1 - c1).norm();
Vec3 z1 = (a1 - c1).norm();
Vec3 x1 = y1.cross(z1);
Vec3 y2 = (a2 - c2).cross(b2 - c2).norm();
Vec3 z2 = (a2 - c2).norm();
Vec3 x2 = y2.cross(z2);
OnMat3 mat1 = OnMat3(x1, y1, z1).transpose();
OnMat3 mat2 = OnMat3(x2, y2, z2).transpose();
OnMat3 rotation = mat1 * mat2.transpose();
Vec3 translation = c1 - c2;
double scale = (a1 - c1).length() / (a2 - c2).length();
translation = rotation * c2 * (-scale) + c1;
Mat4 transformation(rotation, translation, scale);
transform_ = transformation;
}
double FindTransform::error(Vec3 fromA, Vec3 toA)
{
return (transform_*fromA - toA).length();
}

Wyświetl plik

@ -1,165 +0,0 @@
// C++
#include <math.h>
#include <string>
#include <iomanip>
#include <sstream>
#include <iostream>
/*!
* \brief Handles basic 3d vector math.
**/
struct Vec3
{
Vec3(double x = 0.0, double y = 0.0, double z = 0.0);
Vec3(const Vec3 &o);
double x_,y_,z_; /**< The x, y and z values of the vector. **/
/*!
* \brief cross The cross product between two vectors.
**/
Vec3 cross(Vec3 o) const;
/*!
* \brief dot The scalar product between two vectors.
**/
double dot(Vec3 o) const;
/*!
* \brief length The length of the vector.
**/
double length() const;
/*!
* \brief norm Returns a normalized version of this vector.
**/
Vec3 norm() const;
/*!
* \brief Scales this vector.
**/
Vec3 operator*(double d) const;
/*!
* \brief Addition between two vectors.
**/
Vec3 operator+(Vec3 o) const;
/*!
* \brief Subtraction between two vectors.
**/
Vec3 operator-(Vec3 o) const;
friend std::ostream & operator<<(std::ostream &os, Vec3 v)
{
return os << "[" << std::setprecision(8) << v.x_ << ", " << std::setprecision(4) << v.y_ << ", " << v.z_ << "]";
}
};
/*!
* \brief Describes a 3d orthonormal matrix.
**/
class OnMat3
{
public:
OnMat3(Vec3 r1, Vec3 r2, Vec3 r3);
OnMat3(const OnMat3 &o);
Vec3 r1_; /**< The first row of the matrix. **/
Vec3 r2_; /**< The second row of the matrix. **/
Vec3 r3_; /**< The third row of the matrix. **/
Vec3 c1_; /**< The first column of the matrix. **/
Vec3 c2_; /**< The second column of the matrix. **/
Vec3 c3_; /**< The third column of the matrix. **/
/*!
* \brief The determinant of the matrix.
**/
double det() const;
/*!
* \brief The transpose of the OnMat3 (equal to inverse).
**/
OnMat3 transpose() const;
/*!
* \brief Matrix multiplication between two ON matrices.
**/
OnMat3 operator*(OnMat3 o) const;
/*!
* \brief Right side multiplication with a 3d vector.
**/
Vec3 operator*(Vec3 o);
friend std::ostream & operator<<(std::ostream &os, OnMat3 m)
{
return os << "[" << std::endl << m.r1_ << std::endl << m.r2_ << std::endl << m.r3_ << std::endl << "]" << std::endl;
}
};
/*!
* \brief Describes an affine transformation.
**/
class Mat4
{
public:
Mat4();
Mat4(OnMat3 rotation, Vec3 translation, double scaling);
/*!
* \brief Right side multiplication with a 3d vector.
**/
Vec3 operator*(Vec3 o);
double r1c1_; /**< Matrix element 0 0 **/
double r1c2_; /**< Matrix element 0 1 **/
double r1c3_; /**< Matrix element 0 2 **/
double r1c4_; /**< Matrix element 0 3 **/
double r2c1_; /**< Matrix element 1 0 **/
double r2c2_; /**< Matrix element 1 1 **/
double r2c3_; /**< Matrix element 1 2 **/
double r2c4_; /**< Matrix element 1 3 **/
double r3c1_; /**< Matrix element 2 0 **/
double r3c2_; /**< Matrix element 2 1 **/
double r3c3_; /**< Matrix element 2 2 **/
double r3c4_; /**< Matrix element 2 3 **/
double r4c1_; /**< Matrix element 3 0 **/
double r4c2_; /**< Matrix element 3 1 **/
double r4c3_; /**< Matrix element 3 2 **/
double r4c4_; /**< Matrix element 3 3 **/
friend std::ostream & operator<<(std::ostream &os, Mat4 m)
{
std::stringstream ss;
ss.precision(8);
ss.setf(std::ios::fixed, std::ios::floatfield);
ss << "[ " << m.r1c1_ << ",\t" << m.r1c2_ << ",\t" << m.r1c3_ << ",\t" << m.r1c4_ << " ]" << std::endl <<
"[ " << m.r2c1_ << ",\t" << m.r2c2_ << ",\t" << m.r2c3_ << ",\t" << m.r2c4_ << " ]" << std::endl <<
"[ " << m.r3c1_ << ",\t" << m.r3c2_ << ",\t" << m.r3c3_ << ",\t" << m.r3c4_ << " ]" << std::endl <<
"[ " << m.r4c1_ << ",\t" << m.r4c2_ << ",\t" << m.r4c3_ << ",\t" << m.r4c4_ << " ]";
return os << ss.str();
}
};
class FindTransform
{
public:
/*!
* \brief findTransform Generates an affine transform from the three 'from' vector to the three 'to' vectors.
* The transform is such that transform * fromA = toA,
* transform * fromB = toB,
* transform * fromC = toC,
**/
void findTransform(Vec3 fromA, Vec3 fromB, Vec3 fromC, Vec3 toA, Vec3 toB, Vec3 toC);
/*!
* \brief error Returns the distance beteween the 'from' and 'to' vectors, after the transform has been applied.
**/
double error(Vec3 fromA, Vec3 toA);
Mat4 transform_; /**< The affine transform. **/
};

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,249 +0,0 @@
#pragma once
// C++
#include <string>
#include <sstream>
#include <fstream>
// PCL
#include <pcl/common/eigen.h>
#include <pcl/common/common.h>
// Logger
#include "Logger.hpp"
// Transformation
#include "FindTransform.hpp"
/*!
* \brief The GeorefSystem struct is used to store information about a georeference system.
*/
struct GeorefSystem
{
std::string system_; /**< The name of the system. **/
double eastingOffset_; /**< The easting offset for the georeference system. **/
double northingOffset_; /**< The northing offset for the georeference system. **/
friend std::ostream& operator<<(std::ostream &os, const GeorefSystem &geo);
};
/*!
* \brief The GeorefGCP struct used to store information about a GCP.
*/
struct GeorefGCP
{
double x_; /**< The X coordinate of the GCP **/
double y_; /**< The Y coordinate of the GCP **/
double z_; /**< The Z coordinate of the GCP **/
bool use_; /**< Bool to check if the GCP is corresponding in the local model **/
double localX_; /**< The corresponding X coordinate in the model **/
double localY_; /**< The corresponding Y coordinate in the model **/
double localZ_; /**< The corresponding Z coordinate in the model **/
size_t cameraIndex_; /**< The index to the corresponding camera for the image. **/
int pixelX_; /**< The pixels x-position for the GCP in the corresponding image **/
int pixelY_; /**< The pixels y-position for the GCP in the corresponding image **/
std::string image_; /**< The corresponding image for the GCP **/
GeorefGCP();
~GeorefGCP();
void extractGCP(std::istringstream &gcpStream);
/*!
* \brief getPos Get the local position of the GCP.
*/
Vec3 getPos();
/*!
* \brief getReferencedPos Get the georeferenced position of the GCP.
*/
Vec3 getReferencedPos();
};
/*!
* \brief The GeorefCamera struct is used to store information about a camera.
*/
struct GeorefCamera
{
GeorefCamera();
GeorefCamera(const GeorefCamera &other);
~GeorefCamera();
/*!
* \brief extractCamera Extracts a camera's intrinsic and extrinsic parameters from a stream.
*/
void extractCamera(std::ifstream &bundleStream);
/*!
* \brief extractCameraGeoref Extracts a camera's world position from a stream.
*/
void extractCameraGeoref(std::istringstream &coordStream);
/*!
* \brief getPos Get the local position of the camera.
*/
Vec3 getPos();
/*!
* \brief getReferencedPos Get the georeferenced position of the camera.
*/
Vec3 getReferencedPos();
double focalLength_; /**< The focal length of the camera. */
double k1_; /**< The k1 lens distortion parameter. **/
double k2_; /**< The k2 lens distortion parameter. **/
double easting_; /**< The easting of the camera. **/
double northing_; /**< The northing of the camera. **/
double altitude_; /**< The altitude of the camera. **/
Eigen::Affine3f* transform_; /**< The rotation of the camera. **/
Eigen::Vector3f* position_; /**< The position of the camera. **/
Eigen::Affine3f* pose_; /**< The pose of the camera. **/
friend std::ostream& operator<<(std::ostream &os, const GeorefCamera &cam);
};
/*!
* \brief The Georef class is used to transform a mesh into a georeferenced system.
* The class reads camera positions from a bundle file.
* The class reads the georefenced camera positions from a coords file.
* The class reads a textured mesh from an OBJ-file.
* The class writes the georeferenced textured mesh to an OBJ-file.
* The class uses file read and write from pcl.
*/
class Georef
{
public:
Georef();
~Georef();
int run(int argc, char* argv[]);
private:
/*!
* \brief parseArguments Parses command line arguments.
* \param argc Application argument count.
* \param argv Argument values.
*/
void parseArguments(int argc, char* argv[]);
/*!
* \brief printHelp Prints help, explaining usage. Can be shown by calling the program with argument: "-help".
*/
void printHelp();
/*!
* \brief setDefaultOutput Setup the output file name given the input file name.
*/
void setDefaultOutput();
/*!
* \brief setDefaultPointCloudOutput Setup the output file name given the input file name.
*/
void setDefaultPointCloudOutput();
/*!
* \brief createGeoreferencedModel Makes the input file georeferenced and saves it to the output file.
*/
void createGeoreferencedModel();
/*!
* \brief readCameras Reads the camera information from the bundle file.
*/
void readCameras();
/*!
* \brief readGCP Reads the ground control points from the gcp file.
*/
void readGCPs();
/*!
* \brief calculateGCPOffset Calculates an offset weighted from the ground control points read in the readGCP function.
*/
void calculateGCPOffset();
/*!
* \brief barycentricCoordinates Returns the world position of a point inside a 2d triangle by using the triangle vertex positions.
*/
pcl::PointXYZ barycentricCoordinates(pcl::PointXY point, pcl::PointXYZ vert0, pcl::PointXYZ vert1, pcl::PointXYZ vert2, pcl::PointXY p0, pcl::PointXY p1, pcl::PointXY p2);
/*!
* \brief performGeoreferencingWithGCP Performs the georeferencing of the model with the ground control points.
*/
void performGeoreferencingWithGCP();
/*!
* \brief createGeoreferencedModelFromGCPData Makes the input file georeferenced and saves it to the output file.
*/
void createGeoreferencedModelFromGCPData();
/*!
* \brief createGeoreferencedModelFromExifData Makes the input file georeferenced and saves it to the output file.
*/
void createGeoreferencedModelFromExifData();
/*!
* \brief chooseBestGCPTriplet Chooses the best triplet of GCPs to use when making the model georeferenced.
*/
void chooseBestGCPTriplet(size_t &gcp0, size_t &gcp1, size_t &gcp2);
/*!
* \brief chooseBestCameraTriplet Chooses the best triplet of cameras to use when making the model georeferenced.
*/
void chooseBestCameraTriplet(size_t &cam0, size_t &cam1, size_t &cam2);
/*!
* \brief printGeorefSystem Prints a file containing information about the georeference system, next to the ouptut file.
**/
void printGeorefSystem();
Logger log_; /**< Logging object. */
std::string logFile_; /**< The path to the output log file. */
std::string bundleFilename_; /**< The path to the cameras bundle file. **/
std::string inputCoordFilename_; /**< The path to the cameras exif gps positions file. **/
std::string outputCoordFilename_; /**< The path to the cameras georeferenced gps positions file. **/
std::string gcpFilename_; /**< The path to the GCP file **/
std::string imagesListPath_; /**< Path to the image list. **/
std::string imagesLocation_; /**< The folder containing the images in the image list. **/
std::string inputObjFilename_; /**< The path to the input mesh obj file. **/
std::string outputObjFilename_; /**< The path to the output mesh obj file. **/
std::string inputPointCloudFilename_; /**< The path to the input point cloud file. **/
std::string outputPointCloudFilename_; /**< The path to the output point cloud file. **/
std::string georefFilename_; /**< The path to the output offset file. **/
bool georeferencePointCloud_;
bool exportCoordinateFile_;
bool exportGeorefSystem_;
bool useGCP_; /**< Check if GCP-file is present and use this to georeference the model. **/
double bundleResizedTo_; /**< The size used in the previous steps to calculate the camera focal_length. */
std::vector<GeorefCamera> cameras_; /**< A vector of all cameras. **/
std::vector<GeorefGCP> gcps_; /**< A vector of all GCPs. **/
std::vector<std::string> imageList_; /**< A vector containing the names of the corresponding cameras. **/
GeorefSystem georefSystem_; /**< Contains the georeference system. **/
};
/*!
* \brief The Georef class
*/
class GeorefException : public std::exception
{
public:
GeorefException() : message("Error in Georef") {}
GeorefException(std::string msgInit) : message("Error in Georef:\n" + msgInit) {}
~GeorefException() throw() {}
virtual const char* what() const throw() {return message.c_str(); }
private:
std::string message; /**< The error message **/
};

Wyświetl plik

@ -1,31 +0,0 @@
#include "Logger.hpp"
Logger::Logger(bool isPrintingInCout) : isPrintingInCout_(isPrintingInCout)
{
}
Logger::~Logger()
{
}
void Logger::print(std::string filePath)
{
std::ofstream file(filePath.c_str(), std::ios::binary);
file << logStream_.str();
file.close();
}
bool Logger::isPrintingInCout() const
{
return isPrintingInCout_;
}
void Logger::setIsPrintingInCout(bool isPrintingInCout)
{
isPrintingInCout_ = isPrintingInCout;
}

Wyświetl plik

@ -1,68 +0,0 @@
#pragma once
// STL
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
/*!
* \brief The Logger class is used to store program messages in a log file.
* \details By using the << operator while printInCout is set, the class writes both to
* cout and to file, if the flag is not set, output is written to file only.
*/
class Logger
{
public:
/*!
* \brief Logger Contains functionality for printing and displaying log information.
* \param printInCout Flag toggling if operator << also writes to cout.
*/
Logger(bool isPrintingInCout = true);
/*!
* \brief Destructor.
*/
~Logger();
/*!
* \brief print Prints the contents of the log to file.
* \param filePath Path specifying where to write the log.
*/
void print(std::string filePath);
/*!
* \brief isPrintingInCout Check if console printing flag is set.
* \return Console printing flag.
*/
bool isPrintingInCout() const;
/*!
* \brief setIsPrintingInCout Set console printing flag.
* \param isPrintingInCout Value, if true, messages added to the log are also printed in cout.
*/
void setIsPrintingInCout(bool isPrintingInCout);
/*!
* Operator for printing messages to log and in the standard output stream if desired.
*/
template<class T>
friend Logger& operator<< (Logger &log, T t)
{
// If console printing is enabled.
if (log.isPrintingInCout_)
{
std::cout << t;
std::cout.flush();
}
// Write to log.
log.logStream_ << t;
return log;
}
private:
bool isPrintingInCout_; /*!< If flag is set, log is printed in cout and written to the log. */
std::stringstream logStream_; /*!< Stream for storing the log. */
};

Wyświetl plik

@ -1,8 +0,0 @@
#include "Georef.hpp"
int main(int argc, char* argv[])
{
Georef ref;
return ref.run(argc, argv);
}

Wyświetl plik

@ -1,336 +0,0 @@
/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) 2012-, Open Perception, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "modifiedPclFunctions.hpp"
int saveOBJFile(const std::string &file_name, const pcl::TextureMesh &tex_mesh, unsigned precision)
{
if (tex_mesh.cloud.data.empty ())
{
PCL_ERROR ("[pcl::io::saveOBJFile] Input point cloud has no data!\n");
return (-1);
}
// Open file
std::ofstream fs;
fs.precision (precision);
fs.open (file_name.c_str ());
// Define material file
std::string mtl_file_name = file_name.substr (0, file_name.find_last_of (".")) + ".mtl";
// Strip path for "mtllib" command
std::string mtl_file_name_nopath = mtl_file_name;
//std::cout << mtl_file_name_nopath << std::endl;
mtl_file_name_nopath.erase (0, mtl_file_name.find_last_of ('/') + 1);
/* Write 3D information */
// number of points
int nr_points = tex_mesh.cloud.width * tex_mesh.cloud.height;
int point_size = tex_mesh.cloud.data.size () / nr_points;
// mesh size
int nr_meshes = tex_mesh.tex_polygons.size ();
// number of faces for header
int nr_faces = 0;
for (int m = 0; m < nr_meshes; ++m)
nr_faces += tex_mesh.tex_polygons[m].size ();
// Write the header information
fs << "####" << std::endl;
fs << "# OBJ dataFile simple version. File name: " << file_name << std::endl;
fs << "# Vertices: " << nr_points << std::endl;
fs << "# Faces: " <<nr_faces << std::endl;
fs << "# Material information:" << std::endl;
fs << "mtllib " << mtl_file_name_nopath << std::endl;
fs << "####" << std::endl;
// Write vertex coordinates
fs << "# Vertices" << std::endl;
for (int i = 0; i < nr_points; ++i)
{
int xyz = 0;
// "v" just be written one
bool v_written = false;
for (size_t d = 0; d < tex_mesh.cloud.fields.size (); ++d)
{
int count = tex_mesh.cloud.fields[d].count;
if (count == 0)
count = 1; // we simply cannot tolerate 0 counts (coming from older converter code)
int c = 0;
// adding vertex
if ((tex_mesh.cloud.fields[d].datatype == pcl::PCLPointField::FLOAT32) /*sensor_msgs::PointField::FLOAT32)*/ && (
tex_mesh.cloud.fields[d].name == "x" ||
tex_mesh.cloud.fields[d].name == "y" ||
tex_mesh.cloud.fields[d].name == "z"))
{
if (!v_written)
{
// write vertices beginning with v
fs << "v ";
v_written = true;
}
float value;
memcpy (&value, &tex_mesh.cloud.data[i * point_size + tex_mesh.cloud.fields[d].offset + c * sizeof (float)], sizeof (float));
fs << value;
if (++xyz == 3)
break;
fs << " ";
}
}
if (xyz != 3)
{
PCL_ERROR ("[pcl::io::saveOBJFile] Input point cloud has no XYZ data!\n");
return (-2);
}
fs << std::endl;
}
fs << "# "<< nr_points <<" vertices" << std::endl;
// // Write vertex normals
// for (int i = 0; i < nr_points; ++i)
// {
// int xyz = 0;
// // "vn" just be written one
// bool v_written = false;
// for (size_t d = 0; d < tex_mesh.cloud.fields.size (); ++d)
// {
// int count = tex_mesh.cloud.fields[d].count;
// if (count == 0)
// count = 1; // we simply cannot tolerate 0 counts (coming from older converter code)
// int c = 0;
// // adding vertex
// if ((tex_mesh.cloud.fields[d].datatype == pcl::PCLPointField::FLOAT32) && (
// tex_mesh.cloud.fields[d].name == "normal_x" ||
// tex_mesh.cloud.fields[d].name == "normal_y" ||
// tex_mesh.cloud.fields[d].name == "normal_z"))
// {
// if (!v_written)
// {
// // write vertices beginning with vn
// fs << "vn ";
// v_written = true;
// }
// float value;
// memcpy (&value, &tex_mesh.cloud.data[i * point_size + tex_mesh.cloud.fields[d].offset + c * sizeof (float)], sizeof (float));
// fs << value;
// if (++xyz == 3)
// break;
// fs << " ";
// }
// }
// if (xyz != 3)
// {
// //PCL_ERROR ("[pcl::io::saveOBJFile] Input point cloud has no normals!\n");
// //return (-2);
// }
// fs << std::endl;
// }
// Write vertex texture with "vt" (adding latter)
for (int m = 0; m < nr_meshes; ++m)
{
if(tex_mesh.tex_coordinates.size() == 0)
continue;
//PCL_INFO ("%d vertex textures in submesh %d\n", tex_mesh.tex_coordinates[m].size (), m);
fs << "# " << tex_mesh.tex_coordinates[m].size() << " vertex textures in submesh " << m << std::endl;
for (size_t i = 0; i < tex_mesh.tex_coordinates[m].size (); ++i)
{
fs << "vt ";
fs << tex_mesh.tex_coordinates[m][i][0] << " " << tex_mesh.tex_coordinates[m][i][1] << std::endl;
}
}
int f_idx = 0;
// int idx_vt =0;
//PCL_INFO ("Writting faces...\n");
for (int m = 0; m < nr_meshes; ++m)
{
if (m > 0)
f_idx += tex_mesh.tex_polygons[m-1].size ();
if(tex_mesh.tex_materials.size() !=0)
{
fs << "# The material will be used for mesh " << m << std::endl;
//TODO pbl here with multi texture and unseen faces
fs << "usemtl " << tex_mesh.tex_materials[m].tex_name << std::endl;
fs << "# Faces" << std::endl;
}
for (size_t i = 0; i < tex_mesh.tex_polygons[m].size(); ++i)
{
// Write faces with "f"
fs << "f";
size_t j = 0;
// There's one UV per vertex per face, i.e., the same vertex can have
// different UV depending on the face.
for (j = 0; j < tex_mesh.tex_polygons[m][i].vertices.size (); ++j)
{
unsigned int idx = tex_mesh.tex_polygons[m][i].vertices[j] + 1;
fs << " " << idx
<< "/" << 3*(i+f_idx) +j+1;
//<< "/" << idx; // vertex index in obj file format starting with 1
}
fs << std::endl;
}
//PCL_INFO ("%d faces in mesh %d \n", tex_mesh.tex_polygons[m].size () , m);
fs << "# "<< tex_mesh.tex_polygons[m].size() << " faces in mesh " << m << std::endl;
}
fs << "# End of File";
// Close obj file
//PCL_INFO ("Closing obj file\n");
fs.close ();
/* Write material defination for OBJ file*/
// Open file
//PCL_INFO ("Writing material files\n");
//dont do it if no material to write
if(tex_mesh.tex_materials.size() ==0)
return (0);
std::ofstream m_fs;
m_fs.precision (precision);
m_fs.open (mtl_file_name.c_str ());
//std::cout << "MTL file is located at_ " << mtl_file_name << std::endl;
// default
m_fs << "#" << std::endl;
m_fs << "# Wavefront material file" << std::endl;
m_fs << "#" << std::endl;
for(int m = 0; m < nr_meshes; ++m)
{
m_fs << "newmtl " << tex_mesh.tex_materials[m].tex_name << std::endl;
m_fs << "Ka "<< tex_mesh.tex_materials[m].tex_Ka.r << " " << tex_mesh.tex_materials[m].tex_Ka.g << " " << tex_mesh.tex_materials[m].tex_Ka.b << std::endl; // defines the ambient color of the material to be (r,g,b).
m_fs << "Kd "<< tex_mesh.tex_materials[m].tex_Kd.r << " " << tex_mesh.tex_materials[m].tex_Kd.g << " " << tex_mesh.tex_materials[m].tex_Kd.b << std::endl; // defines the diffuse color of the material to be (r,g,b).
m_fs << "Ks "<< tex_mesh.tex_materials[m].tex_Ks.r << " " << tex_mesh.tex_materials[m].tex_Ks.g << " " << tex_mesh.tex_materials[m].tex_Ks.b << std::endl; // defines the specular color of the material to be (r,g,b). This color shows up in highlights.
m_fs << "d " << tex_mesh.tex_materials[m].tex_d << std::endl; // defines the transparency of the material to be alpha.
m_fs << "Ns "<< tex_mesh.tex_materials[m].tex_Ns << std::endl; // defines the shininess of the material to be s.
m_fs << "illum "<< tex_mesh.tex_materials[m].tex_illum << std::endl; // denotes the illumination model used by the material.
// illum = 1 indicates a flat material with no specular highlights, so the value of Ks is not used.
// illum = 2 denotes the presence of specular highlights, and so a specification for Ks is required.
m_fs << "map_Kd " << tex_mesh.tex_materials[m].tex_file << std::endl;
m_fs << "###" << std::endl;
}
m_fs.close ();
return (0);
}
bool getPixelCoordinates(const pcl::PointXYZ &pt, const pcl::TextureMapping<pcl::PointXYZ>::Camera &cam, pcl::PointXY &UV_coordinates)
{
if (pt.z > 0)
{
// compute image center and dimension
double sizeX = cam.width;
double sizeY = cam.height;
double cx, cy;
if (cam.center_w > 0)
cx = cam.center_w;
else
cx = sizeX / 2.0;
if (cam.center_h > 0)
cy = cam.center_h;
else
cy = sizeY / 2.0;
double focal_x, focal_y;
if (cam.focal_length_w > 0)
focal_x = cam.focal_length_w;
else
focal_x = cam.focal_length;
if (cam.focal_length_h > 0)
focal_y = cam.focal_length_h;
else
focal_y = cam.focal_length;
// project point on camera's image plane
UV_coordinates.x = static_cast<float> ((focal_x * (pt.x / pt.z) + cx)); //horizontal
UV_coordinates.y = static_cast<float> ((focal_y * (pt.y / pt.z) + cy)); //vertical
// point is visible!
if (UV_coordinates.x >= 1.0 && UV_coordinates.x <= (sizeX - 1.0) && UV_coordinates.y >= 1.0 && UV_coordinates.y <= (sizeY - 1.0))
{
return (true); // point was visible by the camera
}
}
// point is NOT visible by the camera
UV_coordinates.x = -1.0f;
UV_coordinates.y = -1.0f;
return (false); // point was not visible by the camera
}
bool isFaceProjected (const pcl::TextureMapping<pcl::PointXYZ>::Camera &camera, const pcl::PointXYZ &p1, const pcl::PointXYZ &p2, const pcl::PointXYZ &p3, pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3)
{
return (getPixelCoordinates(p1, camera, proj1) && getPixelCoordinates(p2, camera, proj2) && getPixelCoordinates(p3, camera, proj3));
}
void getTriangleCircumscribedCircleCentroid( const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius)
{
// compute centroid's coordinates (translate back to original coordinates)
circumcenter.x = static_cast<float> (p1.x + p2.x + p3.x ) / 3;
circumcenter.y = static_cast<float> (p1.y + p2.y + p3.y ) / 3;
double r1 = (circumcenter.x - p1.x) * (circumcenter.x - p1.x) + (circumcenter.y - p1.y) * (circumcenter.y - p1.y) ;
double r2 = (circumcenter.x - p2.x) * (circumcenter.x - p2.x) + (circumcenter.y - p2.y) * (circumcenter.y - p2.y) ;
double r3 = (circumcenter.x - p3.x) * (circumcenter.x - p3.x) + (circumcenter.y - p3.y) * (circumcenter.y - p3.y) ;
// radius
radius = std::sqrt( std::max( r1, std::max( r2, r3) )) ;
}
bool checkPointInsideTriangle(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, const pcl::PointXY &pt)
{
// Compute vectors
Eigen::Vector2d v0, v1, v2;
v0(0) = p3.x - p1.x; v0(1) = p3.y - p1.y; // v0= C - A
v1(0) = p2.x - p1.x; v1(1) = p2.y - p1.y; // v1= B - A
v2(0) = pt.x - p1.x; v2(1) = pt.y - p1.y; // v2= P - A
// Compute dot products
double dot00 = v0.dot(v0); // dot00 = dot(v0, v0)
double dot01 = v0.dot(v1); // dot01 = dot(v0, v1)
double dot02 = v0.dot(v2); // dot02 = dot(v0, v2)
double dot11 = v1.dot(v1); // dot11 = dot(v1, v1)
double dot12 = v1.dot(v2); // dot12 = dot(v1, v2)
// Compute barycentric coordinates
double invDenom = 1.0 / (dot00*dot11 - dot01*dot01);
double u = (dot11*dot02 - dot01*dot12) * invDenom;
double v = (dot00*dot12 - dot01*dot02) * invDenom;
// Check if point is in triangle
return ((u >= 0) && (v >= 0) && (u + v < 1));
}

Wyświetl plik

@ -1,20 +0,0 @@
#pragma once
// STL
#include <iostream>
#include <fstream>
// PCL
#include <pcl/point_types.h>
#include <pcl/surface/texture_mapping.h>
#include <pcl/io/ply_io.h>
int saveOBJFile(const std::string &file_name, const pcl::TextureMesh &tex_mesh, unsigned precision);
bool getPixelCoordinates(const pcl::PointXYZ &pt, const pcl::TextureMapping<pcl::PointXYZ>::Camera &cam, pcl::PointXY &UV_coordinates);
bool isFaceProjected (const pcl::TextureMapping<pcl::PointXYZ>::Camera &camera, const pcl::PointXYZ &p1, const pcl::PointXYZ &p2, const pcl::PointXYZ &p3, pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3);
void getTriangleCircumscribedCircleCentroid(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius);
bool checkPointInsideTriangle(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, const pcl::PointXY &pt);

Wyświetl plik

@ -1,26 +0,0 @@
project(odm_meshing)
cmake_minimum_required(VERSION 2.8)
# Set pcl dir to the input spedified with option -DPCL_DIR="path"
set(PCL_DIR "PCL_DIR-NOTFOUND" CACHE "PCL_DIR" "Path to the pcl installation directory")
# Add compiler options.
add_definitions(-Wall -Wextra)
# Find pcl at the location specified by PCL_DIR
find_package(PCL 1.7 HINTS "${PCL_DIR}/share/pcl-1.7")
# Add the PCL and Eigen include dirs.
# Necessary since the PCL_INCLUDE_DIR variable set by find_package is broken.)
include_directories(${PCL_ROOT}/include/pcl-${PCL_VERSION_MAJOR}.${PCL_VERSION_MINOR})
include_directories(${EIGEN_ROOT})
# Add source directory
aux_source_directory("./src" SRC_LIST)
# Add exectuteable
add_executable(${PROJECT_NAME} ${SRC_LIST})
# Link
target_link_libraries(odm_meshing ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_SURFACE_LIBRARIES})

Wyświetl plik

@ -1,31 +0,0 @@
#include "Logger.hpp"
Logger::Logger(bool isPrintingInCout) : isPrintingInCout_(isPrintingInCout)
{
}
Logger::~Logger()
{
}
void Logger::printToFile(std::string filePath)
{
std::ofstream file(filePath.c_str(), std::ios::binary);
file << logStream_.str();
file.close();
}
bool Logger::isPrintingInCout() const
{
return isPrintingInCout_;
}
void Logger::setIsPrintingInCout(bool isPrintingInCout)
{
isPrintingInCout_ = isPrintingInCout;
}

Wyświetl plik

@ -1,68 +0,0 @@
#pragma once
// STL
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
/*!
* \brief The Logger class is used to store program messages in a log file.
* \details By using the << operator while printInCout is set, the class writes both to
* cout and to file, if the flag is not set, output is written to file only.
*/
class Logger
{
public:
/*!
* \brief Logger Contains functionality for printing and displaying log information.
* \param printInCout Flag toggling if operator << also writes to cout.
*/
Logger(bool isPrintingInCout = true);
/*!
* \brief Destructor.
*/
~Logger();
/*!
* \brief print Prints the contents of the log to file.
* \param filePath Path specifying where to write the log.
*/
void printToFile(std::string filePath);
/*!
* \brief isPrintingInCout Check if console printing flag is set.
* \return Console printing flag.
*/
bool isPrintingInCout() const;
/*!
* \brief setIsPrintingInCout Set console printing flag.
* \param isPrintingInCout Value, if true, messages added to the log are also printed in cout.
*/
void setIsPrintingInCout(bool isPrintingInCout);
/*!
* Operator for printing messages to log and in the standard output stream if desired.
*/
template<class T>
friend Logger& operator<< (Logger &log, T t)
{
// If console printing is enabled.
if (log.isPrintingInCout_)
{
std::cout << t;
std::cout.flush();
}
// Write to log.
log.logStream_ << t;
return log;
}
private:
bool isPrintingInCout_; /*!< If flag is set, log is printed in cout and written to the log. */
std::stringstream logStream_; /*!< Stream for storing the log. */
};

Wyświetl plik

@ -1,361 +0,0 @@
#include "OdmMeshing.hpp"
OdmMeshing::OdmMeshing() : log_(false)
{
meshCreator_ = pcl::Poisson<pcl::PointNormal>::Ptr(new pcl::Poisson<pcl::PointNormal>());
points_ = pcl::PointCloud<pcl::PointNormal>::Ptr(new pcl::PointCloud<pcl::PointNormal>());
mesh_ = pcl::PolygonMeshPtr(new pcl::PolygonMesh);
decimatedMesh_ = pcl::PolygonMeshPtr(new pcl::PolygonMesh);
// Set default values
outputFile_ = "";
logFilePath_ = "";
maxVertexCount_ = 0;
treeDepth_ = 0;
solverDivide_ = 9.0;
samplesPerNode_ = 1.0;
decimationFactor_ = 0.0;
logFilePath_ = "odm_meshing_log.txt";
log_ << logFilePath_ << "\n";
}
OdmMeshing::~OdmMeshing()
{
}
int OdmMeshing::run(int argc, char **argv)
{
// If no arguments were passed, print help and return early.
if (argc <= 1)
{
printHelp();
return EXIT_SUCCESS;
}
try
{
parseArguments(argc, argv);
loadPoints();
createMesh();
decimateMesh();
writePlyFile();
}
catch (const OdmMeshingException& e)
{
log_.setIsPrintingInCout(true);
log_ << e.what() << "\n";
log_.printToFile(logFilePath_);
log_ << "For more detailed information, see log file." << "\n";
return EXIT_FAILURE;
}
catch (const std::exception& e)
{
log_.setIsPrintingInCout(true);
log_ << "Error in OdmMeshing:\n";
log_ << e.what() << "\n";
log_.printToFile(logFilePath_);
log_ << "For more detailed information, see log file." << "\n";
return EXIT_FAILURE;
}
catch (...)
{
log_.setIsPrintingInCout(true);
log_ << "Unknwon error in OdmMeshing:\n";
log_.printToFile(logFilePath_);
log_ << "For more detailed information, see log file." << "\n";
return EXIT_FAILURE;
}
log_.printToFile(logFilePath_);
return EXIT_SUCCESS;
}
void OdmMeshing::parseArguments(int argc, char **argv)
{
for(int argIndex = 1; argIndex < argc; ++argIndex)
{
// The argument to be parsed.
std::string argument = std::string(argv[argIndex]);
if(argument == "-help")
{
printHelp();
}
else if(argument == "-verbose")
{
log_.setIsPrintingInCout(true);
}
else if(argument == "-maxVertexCount" && argIndex < argc)
{
++argIndex;
if (argIndex >= argc)
{
throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
std::stringstream ss(argv[argIndex]);
ss >> maxVertexCount_;
if (ss.bad())
{
throw OdmMeshingException("Argument '" + argument + "' has a bad value (wrong type).");
}
log_ << "Vertex count was manually set to: " << maxVertexCount_ << "\n";
}
else if(argument == "-octreeDepth" && argIndex < argc)
{
++argIndex;
if (argIndex >= argc)
{
throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
std::stringstream ss(argv[argIndex]);
ss >> treeDepth_;
if (ss.bad())
{
throw OdmMeshingException("Argument '" + argument + "' has a bad value (wrong type).");
}
log_ << "Octree depth was manually set to: " << treeDepth_ << "\n";
}
else if(argument == "-solverDivide" && argIndex < argc)
{
++argIndex;
if (argIndex >= argc)
{
throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
std::stringstream ss(argv[argIndex]);
ss >> solverDivide_;
if (ss.bad())
{
throw OdmMeshingException("Argument '" + argument + "' has a bad value (wrong type).");
}
log_ << "Numerical solver divisions was manually set to: " << treeDepth_ << "\n";
}
else if(argument == "-samplesPerNode" && argIndex < argc)
{
++argIndex;
if (argIndex >= argc)
{
throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
std::stringstream ss(argv[argIndex]);
ss >> samplesPerNode_;
if (ss.bad())
{
throw OdmMeshingException("Argument '" + argument + "' has a bad value (wrong type).");
}
log_ << "The number of samples per octree node was manually set to: " << samplesPerNode_ << "\n";
}
else if(argument == "-inputFile" && argIndex < argc)
{
++argIndex;
if (argIndex >= argc)
{
throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
inputFile_ = std::string(argv[argIndex]);
std::ifstream testFile(inputFile_.c_str(), std::ios::binary);
if (!testFile.is_open())
{
throw OdmMeshingException("Argument '" + argument + "' has a bad value. (file not accessible)");
}
testFile.close();
log_ << "Reading point cloud at: " << inputFile_ << "\n";
}
else if(argument == "-outputFile" && argIndex < argc)
{
++argIndex;
if (argIndex >= argc)
{
throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
outputFile_ = std::string(argv[argIndex]);
std::ofstream testFile(outputFile_.c_str());
if (!testFile.is_open())
{
throw OdmMeshingException("Argument '" + argument + "' has a bad value.");
}
testFile.close();
log_ << "Writing output to: " << outputFile_ << "\n";
}
else if(argument == "-logFile" && argIndex < argc)
{
++argIndex;
if (argIndex >= argc)
{
throw OdmMeshingException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
logFilePath_ = std::string(argv[argIndex]);
std::ofstream testFile(outputFile_.c_str());
if (!testFile.is_open())
{
throw OdmMeshingException("Argument '" + argument + "' has a bad value.");
}
testFile.close();
log_ << "Writing log information to: " << logFilePath_ << "\n";
}
else
{
printHelp();
throw OdmMeshingException("Unrecognised argument '" + argument + "'");
}
}
}
void OdmMeshing::loadPoints()
{
if(pcl::io::loadPLYFile<pcl::PointNormal> (inputFile_.c_str(), *points_.get()) == -1) {
throw OdmMeshingException("Error when reading points and normals from:\n" + inputFile_ + "\n");
}
else
{
log_ << "Successfully loaded " << points_->size() << " points with corresponding normals from file.\n";
}
}
void OdmMeshing::printHelp()
{
bool printInCoutPop = log_.isPrintingInCout();
log_.setIsPrintingInCout(true);
log_ << "OpenDroneMapMeshing.exe\n\n";
log_ << "Purpose:" << "\n";
log_ << "Create a mesh from an oriented point cloud (points with normals) using the Poisson surface reconstruction method." << "\n";
log_ << "Usage:" << "\n";
log_ << "The program requires a path to an input PLY point cloud file, all other input parameters are optional." << "\n\n";
log_ << "The following flags are available\n";
log_ << "Call the program with flag \"-help\", or without parameters to print this message, or check any generated log file.\n";
log_ << "Call the program with flag \"-verbose\", to print log messages in the standard output stream as well as in the log file.\n\n";
log_ << "Parameters are specified as: \"-<argument name> <argument>\", (without <>), and the following parameters are configureable: " << "\n";
log_ << "\"-inputFile <path>\" (mandatory)" << "\n";
log_ << "\"Input ascii ply file that must contain a point cloud with normals.\n\n";
log_ << "\"-outputFile <path>\" (optional, default: odm_mesh.ply)" << "\n";
log_ << "\"Target file in which the mesh is saved.\n\n";
log_ << "\"-logFile <path>\" (optional, default: odm_meshing_log.txt)" << "\n";
log_ << "\"Target file in which the mesh is saved.\n\n";
log_ << "\"-maxVertexCount <integer>\" (optional, default: 100,000)" << "\n";
log_ << "Desired final vertex count (after decimation), set to 0 to disable decimation.\n\n";
log_ << "\"-treeDepth <integer>\" (optional, default: 0 (automatic))" << "\n";
log_ << "Controls octree depth used for poisson reconstruction. Recommended values (9-11).\n"
<< "Increasing the value on this parameter will raise initial vertex count."
<< "If omitted or zero, the depth is calculated automatically from the input point count.\n\n";
log_ << "\"-samplesPerNode <float>\" (optional, default: 1)" << "\n";
log_ << "Average number of samples (points) per octree node. Increasing this value might help if data is very noisy.\n\n";
log_ << "\"-solverDivide <integer>\" (optional, default: 9)" << "\n";
log_ << "Ocree depth at which the Laplacian equation is solved in the surface reconstruction step.\n";
log_ << "Increasing this value increases computation times slightly but helps reduce memory usage.\n\n";
log_.setIsPrintingInCout(printInCoutPop);
}
void OdmMeshing::createMesh()
{
// Attempt to calculate the depth of the tree if unspecified
if (treeDepth_ == 0)
{
treeDepth_ = calcTreeDepth(points_->size());
}
log_ << "Octree depth used for reconstruction is: " << treeDepth_ << "\n";
log_ << "Estimated initial vertex count: " << pow(4, treeDepth_) << "\n\n";
meshCreator_->setDepth(treeDepth_);
meshCreator_->setSamplesPerNode(samplesPerNode_);
meshCreator_->setInputCloud(points_);
// Guarantee manifold mesh.
meshCreator_->setManifold(true);
// Begin reconstruction
meshCreator_->reconstruct(*mesh_.get());
log_ << "Reconstruction complete:\n";
log_ << "Vertex count: " << mesh_->cloud.width << "\n";
log_ << "Triangle count: " << mesh_->polygons.size() << "\n\n";
}
void OdmMeshing::decimateMesh()
{
if (maxVertexCount_ <= 0)
{
log_ << "Vertex count not specified, decimation cancelled.\n";
return;
}
if (maxVertexCount_ > mesh_->cloud.height*mesh_->cloud.width)
{
log_ << "Vertex count in mesh lower than initially generated mesh, unable to decimate.\n";
return;
}
else
{
decimatedMesh_ = pcl::PolygonMeshPtr(new pcl::PolygonMesh);
double reductionFactor = 1.0 - double(maxVertexCount_)/double(mesh_->cloud.height*mesh_->cloud.width);
log_ << "Decimating mesh, removing " << reductionFactor*100 << " percent of vertices.\n";
pcl::MeshQuadricDecimationVTK decimator;
decimator.setInputMesh(mesh_);
decimator.setTargetReductionFactor(reductionFactor);
decimator.process(*decimatedMesh_.get());
log_ << "Decimation complete.\n";
log_ << "Decimated vertex count: " << decimatedMesh_->cloud.width << "\n";
log_ << "Decimated triangle count: " << decimatedMesh_->polygons.size() << "\n\n";
mesh_ = decimatedMesh_;
}
}
int OdmMeshing::calcTreeDepth(size_t nPoints)
{
// Assume points are located (roughly) in a plane.
double squareSide = std::sqrt(double(nPoints));
// Calculate octree depth such that if points were equally distributed in
// a quadratic plane, there would be at least 1 point per octree node.
int depth = 0;
while(std::pow<double>(2,depth) < squareSide/2)
{
depth++;
}
return depth;
}
void OdmMeshing::writePlyFile()
{
log_ << "Saving mesh to file.\n";
if (pcl::io::savePLYFile(outputFile_.c_str(), *mesh_.get()) == -1) {
throw OdmMeshingException("Error when saving mesh to file:\n" + outputFile_ + "\n");
}
else
{
log_ << "Successfully wrote mesh to:\n"
<< outputFile_ << "\n";
}
}

Wyświetl plik

@ -1,117 +0,0 @@
#pragma once
// STL
#include <string>
#include <iostream>
// PCL
#include <pcl/io/ply_io.h>
#include <pcl/surface/poisson.h>
#include <pcl/surface/vtk_smoothing/vtk_mesh_quadric_decimation.h>
// Logging
#include "Logger.hpp"
/*!
* \brief The OdmMeshing class is used to create a triangulated mesh using the Poisson method.
* The class reads an oriented point cloud (coordinates and normals) from a PLY ascii
* file and outputs the resulting welded manifold mesh on the form of an ASCII PLY-file.
* The class uses file read and write functions from pcl.
*/
class OdmMeshing
{
public:
OdmMeshing();
~OdmMeshing();
/*!
* \brief run Runs the meshing functionality using the provided input arguments.
* For a list of accepted arguments, please see the main page documentation or
* call the program with parameter "-help".
* \param argc Application argument count.
* \param argv Argument values.
* \return 0 If successful.
*/
int run(int argc, char **argv);
private:
/*!
* \brief parseArguments Parses command line arguments.
* \param argc Application argument count.
* \param argv Argument values.
*/
void parseArguments(int argc, char** argv);
/*!
* \brief createMesh Sets up the pcl::Poisson meshing class using provided arguments and calls
* it to start the meshing.
*/
void createMesh();
/*!
* \brief loadPoints Loads a PLY ascii file with points and normals from file.
*/
void loadPoints();
/*!
* \brief decimateMesh Performs post-processing on the form of quadric decimation to generate a mesh
* that has a higher density in areas with a lot of structure.
*/
void decimateMesh();
/*!
* \brief writePlyFile Writes the mesh to file on the Ply format.
*/
void writePlyFile();
/*!
* \brief printHelp Prints help, explaining usage. Can be shown by calling the program with argument: "-help".
*/
void printHelp();
/*!
* \brief calcTreeDepth Attepts to calculate the depth of the tree using the point cloud.
* The function makes the assumption points are located roughly in a plane
* (fairly reasonable for ortho-terrain photos) and tries to generate a mesh using
* an octree with an appropriate resolution.
* \param nPoints The total number of points in the input point cloud.
* \return The calcualated octree depth.
*/
int calcTreeDepth(size_t nPoints);
Logger log_; /**< Logging object. */
pcl::Poisson<pcl::PointNormal>::Ptr meshCreator_; /**< PCL poisson meshing class. */
pcl::PointCloud<pcl::PointNormal>::Ptr points_; /**< Input point and normals. */
pcl::PolygonMeshPtr mesh_; /**< PCL polygon mesh. */
pcl::PolygonMeshPtr decimatedMesh_; /**< Decimated polygon mesh. */
std::string inputFile_; /**< Path to a file containing points and normals. */
std::string outputFile_; /**< Path to the destination file. */
std::string logFilePath_; /**< Path to the log file. */
unsigned int maxVertexCount_; /**< Desired output vertex count. */
unsigned int treeDepth_; /**< Depth of octree used for reconstruction. */
double samplesPerNode_; /**< Samples per octree node.*/
double solverDivide_; /**< Depth at which the Laplacian equation solver is run during surface estimation.*/
double decimationFactor_; /**< Percentage of points to remove when decimating the mesh. */
};
/*!
* \brief The OdmMeshingException class
*/
class OdmMeshingException : public std::exception
{
public:
OdmMeshingException() : message("Error in OdmMeshing") {}
OdmMeshingException(std::string msgInit) : message("Error in OdmMeshing:\n" + msgInit) {}
~OdmMeshingException() throw() {}
virtual const char* what() const throw() {return message.c_str(); }
private:
std::string message; /**< The error message **/
};

Wyświetl plik

@ -1,20 +0,0 @@
// Insert license here.
// Include meshing source code.
#include "OdmMeshing.hpp"
/*!
* \mainpage main OpenDroneMap Meshing Module
*
* The OpenDroneMap Meshing Module generates a welded, manifold mesh using the Poisson
* surface reconstruction algorithm from any oriented point cloud (points with corresponding normals).
*
*/
int main(int argc, char** argv)
{
OdmMeshing meshCreator;
return meshCreator.run(argc, argv);
}

Wyświetl plik

@ -1,34 +0,0 @@
project(odm_orthophoto)
cmake_minimum_required(VERSION 2.8)
# Set pcl dir to the input spedified with option -DPCL_DIR="path"
set(PCL_DIR "PCL_DIR-NOTFOUND" CACHE "PCL_DIR" "Path to the pcl installation directory")
set(OPENCV_DIR "OPENCV_DIR-NOTFOUND" CACHE "OPENCV_DIR" "Path to the OPENCV installation directory")
# Add compiler options.
add_definitions(-Wall -Wextra)
# Find pcl at the location specified by PCL_DIR
find_package(PCL 1.7 HINTS "${PCL_DIR}/share/pcl-1.7" REQUIRED)
# Find OpenCV at the default location
find_package(OpenCV HINTS "${OPENCV_DIR}" REQUIRED)
# Only link with required opencv modules.
set(OpenCV_LIBS opencv_core opencv_imgproc opencv_highgui)
# Add the PCL, Eigen and OpenCV include dirs.
# Necessary since the PCL_INCLUDE_DIR variable set by find_package is broken.)
include_directories(${PCL_ROOT}/include/pcl-${PCL_VERSION_MAJOR}.${PCL_VERSION_MINOR})
include_directories(${EIGEN_ROOT})
include_directories(${OpenCV_INCLUDE_DIRS})
#library_directories(${OpenCV_LIBRARY_DIRS})
# Add source directory
aux_source_directory("./src" SRC_LIST)
# Add exectuteable
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(odm_orthophoto ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_SURFACE_LIBRARIES} ${OpenCV_LIBS})

Wyświetl plik

@ -1,203 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by Qt Creator 2.4.1, 2015-02-04T09:12:31. -->
<qtcreator>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QString" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QString" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">System</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.DefaultCMakeTarget</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory">/home/spotscale/odm/OpenDroneMap-texturing_orthophoto_spotscale_additions/odm_orthophoto-build</value>
<value type="QString" key="CMakeProjectManager.CMakeBuildConfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-32bit./usr/bin/gdb</value>
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-32bit./usr/bin/gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="CMakeProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments">clean</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="CMakeProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">all</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">No deployment</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Project.UseGlobal">true</value>
<value type="bool" key="Analyzer.Project.UseGlobal">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="CMakeProjectManager.BaseEnvironmentBase">2</value>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguation.Title">odm_orthophoto</value>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.Arguments"></value>
<value type="bool" key="CMakeProjectManager.CMakeRunConfiguration.UseTerminal">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.CMakeRunConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">odm_orthophoto</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
<value type="QString">{785a73be-b55f-490c-9d46-e1451c235840}</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">10</value>
</data>
</qtcreator>

Wyświetl plik

@ -1,29 +0,0 @@
#include "Logger.hpp"
Logger::Logger(bool isPrintingInCout) : isPrintingInCout_(isPrintingInCout)
{
}
Logger::~Logger()
{
}
void Logger::print(std::string filePath)
{
std::ofstream file(filePath.c_str(), std::ios::binary);
file << logStream_.str();
file.close();
}
bool Logger::isPrintingInCout() const
{
return isPrintingInCout_;
}
void Logger::setIsPrintingInCout(bool isPrintingInCout)
{
isPrintingInCout_ = isPrintingInCout;
}

Wyświetl plik

@ -1,68 +0,0 @@
#pragma once
// STL
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
/*!
* \brief The Logger class is used to store program messages in a log file.
* \details By using the << operator while printInCout is set, the class writes both to
* cout and to file, if the flag is not set, output is written to file only.
*/
class Logger
{
public:
/*!
* \brief Logger Contains functionality for printing and displaying log information.
* \param printInCout Flag toggling if operator << also writes to cout.
*/
Logger(bool isPrintingInCout = true);
/*!
* \brief Destructor.
*/
~Logger();
/*!
* \brief print Prints the contents of the log to file.
* \param filePath Path specifying where to write the log.
*/
void print(std::string filePath);
/*!
* \brief isPrintingInCout Check if console printing flag is set.
* \return Console printing flag.
*/
bool isPrintingInCout() const;
/*!
* \brief setIsPrintingInCout Set console printing flag.
* \param isPrintingInCout Value, if true, messages added to the log are also printed in cout.
*/
void setIsPrintingInCout(bool isPrintingInCout);
/*!
* Operator for printing messages to log and in the standard output stream if desired.
*/
template<class T>
friend Logger& operator<< (Logger &log, T t)
{
// If console printing is enabled.
if (log.isPrintingInCout_)
{
std::cout << t;
std::cout.flush();
}
// Write to log.
log.logStream_ << t;
return log;
}
private:
bool isPrintingInCout_; /*!< If flag is set, log is printed in cout and written to the log. */
std::stringstream logStream_; /*!< Stream for storing the log. */
};

Wyświetl plik

@ -1,996 +0,0 @@
// C++
#include <math.h>
#include <sstream>
#include <fstream>
// This
#include "OdmOrthoPhoto.hpp"
std::ostream & operator<< (std::ostream &os, const WorldPoint &worldPoint)
{
return os << worldPoint.eastInteger_ + worldPoint.eastFractional_ << " " << worldPoint.northInteger_ + worldPoint.northFractional_;
}
std::istream & operator>> (std::istream &is, WorldPoint &worldPoint)
{
is >> worldPoint.eastInteger_;
// Check if east coordinate is given as rational.
if('.' == is.peek())
{
is >> worldPoint.eastFractional_;
}
else
{
worldPoint.eastFractional_ = 0.0f;
}
is >> worldPoint.northInteger_;
// Check if north coordinate is given as rational.
if('.' == is.peek())
{
is >> worldPoint.northFractional_;
}
else
{
worldPoint.northFractional_ = 0.0f;
}
return is;
}
OdmOrthoPhoto::OdmOrthoPhoto()
:log_(false)
{
inputFile_ = "";
inputGeoRefFile_ = "";
outputFile_ = "ortho.jpg";
logFile_ = "log.txt";
outputCornerFile_ = "";
resolution_ = 0.0f;
boundaryDefined_ = false;
boundaryPoint1_[0] = 0.0f; boundaryPoint1_[1] = 0.0f;
boundaryPoint2_[0] = 0.0f; boundaryPoint2_[1] = 0.0f;
boundaryPoint3_[0] = 0.0f; boundaryPoint3_[1] = 0.0f;
boundaryPoint4_[0] = 0.0f; boundaryPoint4_[1] = 0.0f;
}
OdmOrthoPhoto::~OdmOrthoPhoto()
{
}
int OdmOrthoPhoto::run(int argc, char *argv[])
{
try
{
parseArguments(argc, argv);
createOrthoPhoto();
}
catch (const OdmOrthoPhotoException& e)
{
log_.setIsPrintingInCout(true);
log_ << e.what() << "\n";
log_.print(logFile_);
return EXIT_FAILURE;
}
catch (const std::exception& e)
{
log_.setIsPrintingInCout(true);
log_ << "Error in OdmOrthoPhoto:\n";
log_ << e.what() << "\n";
log_.print(logFile_);
return EXIT_FAILURE;
}
catch (...)
{
log_.setIsPrintingInCout(true);
log_ << "Unknown error, terminating:\n";
log_.print(logFile_);
return EXIT_FAILURE;
}
log_.print(logFile_);
return EXIT_SUCCESS;
}
void OdmOrthoPhoto::parseArguments(int argc, char *argv[])
{
logFile_ = std::string(argv[0]) + "_log.txt";
log_ << logFile_ << "\n\n";
// If no arguments were passed, print help.
if (argc == 1)
{
printHelp();
}
log_ << "Arguments given\n";
for(int argIndex = 1; argIndex < argc; ++argIndex)
{
log_ << argv[argIndex] << '\n';
}
log_ << '\n';
for(int argIndex = 1; argIndex < argc; ++argIndex)
{
// The argument to be parsed.
std::string argument = std::string(argv[argIndex]);
if(argument == "-help")
{
printHelp();
}
else if(argument == "-resolution")
{
++argIndex;
if (argIndex >= argc)
{
throw OdmOrthoPhotoException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
std::stringstream ss(argv[argIndex]);
ss >> resolution_;
log_ << "Resolution count was set to: " << resolution_ << "pixels/meter\n";
}
else if(argument == "-boundary")
{
if(argIndex+8 >= argc)
{
throw OdmOrthoPhotoException("Argument '" + argument + "' expects 8 more input following it, but no more inputs were provided.");
}
std::stringstream ss;
ss << argv[argIndex+1] << " " << argv[argIndex+2] << " " << argv[argIndex+3] << " " << argv[argIndex+4] << " " << argv[argIndex+5] << " " << argv[argIndex+6] << " " << argv[argIndex+7] << " " << argv[argIndex+8];
ss >> worldPoint1_ >> worldPoint2_ >> worldPoint3_ >> worldPoint4_;
boundaryDefined_ = true;
argIndex += 8;
log_ << "Boundary point 1 was set to: " << worldPoint1_ << '\n';
log_ << "Boundary point 2 was set to: " << worldPoint2_ << '\n';
log_ << "Boundary point 3 was set to: " << worldPoint3_ << '\n';
log_ << "Boundary point 4 was set to: " << worldPoint4_ << '\n';
}
else if(argument == "-boundaryMinMax")
{
if(argIndex+4 >= argc)
{
throw OdmOrthoPhotoException("Argument '" + argument + "' expects 4 more input following it, but no more inputs were provided.");
}
std::stringstream ss;
ss << argv[argIndex+1] << " " << argv[argIndex+2] << " " << argv[argIndex+3] << " " << argv[argIndex+4];
ss >> worldPoint1_ >> worldPoint3_;
boundaryDefined_ = true;
// Set the other world points as the other two corners.
worldPoint2_.eastFractional_ = worldPoint1_.eastFractional_;
worldPoint2_.eastInteger_ = worldPoint1_.eastInteger_;
worldPoint2_.northFractional_ = worldPoint3_.northFractional_;
worldPoint2_.northInteger_ = worldPoint3_.northInteger_;
worldPoint4_.eastFractional_ = worldPoint3_.eastFractional_;
worldPoint4_.eastInteger_ = worldPoint3_.eastInteger_;
worldPoint4_.northFractional_ = worldPoint1_.northFractional_;
worldPoint4_.northInteger_ = worldPoint1_.northInteger_;
argIndex += 4;
log_ << "Boundary point 1 was set to: " << worldPoint1_ << '\n';
log_ << "Boundary point 2 was set to: " << worldPoint2_ << '\n';
log_ << "Boundary point 3 was set to: " << worldPoint3_ << '\n';
log_ << "Boundary point 4 was set to: " << worldPoint4_ << '\n';
}
else if(argument == "-verbose")
{
log_.setIsPrintingInCout(true);
}
else if (argument == "-logFile")
{
++argIndex;
if (argIndex >= argc)
{
throw OdmOrthoPhotoException("Missing argument for '" + argument + "'.");
}
logFile_ = std::string(argv[argIndex]);
std::ofstream testFile(logFile_.c_str());
if (!testFile.is_open())
{
throw OdmOrthoPhotoException("Argument '" + argument + "' has a bad value.");
}
log_ << "Log file path was set to: " << logFile_ << "\n";
}
else if(argument == "-inputFile")
{
argIndex++;
if (argIndex >= argc)
{
throw OdmOrthoPhotoException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
inputFile_ = std::string(argv[argIndex]);
log_ << "Reading textured mesh from: " << inputFile_ << "\n";
}
else if(argument == "-inputGeoRefFile")
{
argIndex++;
if (argIndex >= argc)
{
throw OdmOrthoPhotoException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
inputGeoRefFile_ = std::string(argv[argIndex]);
log_ << "Reading georef from: " << inputGeoRefFile_ << "\n";
}
else if(argument == "-outputFile")
{
argIndex++;
if (argIndex >= argc)
{
throw OdmOrthoPhotoException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
outputFile_ = std::string(argv[argIndex]);
log_ << "Writing output to: " << outputFile_ << "\n";
}
else if(argument == "-outputCornerFile")
{
argIndex++;
if (argIndex >= argc)
{
throw OdmOrthoPhotoException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
outputCornerFile_ = std::string(argv[argIndex]);
log_ << "Writing corners to: " << outputCornerFile_ << "\n";
}
else
{
printHelp();
throw OdmOrthoPhotoException("Unrecognised argument '" + argument + "'");
}
}
log_ << "\n";
}
void OdmOrthoPhoto::printHelp()
{
log_.setIsPrintingInCout(true);
log_ << "OpenDroneMapOrthoPhoto.exe\n\n";
log_ << "Purpose\n";
log_ << "Create an orthograpical photo from an oriented textured mesh.\n\n";
log_ << "Usage:\n";
log_ << "The program requires a path to an input OBJ mesh file and a resolution, as pixels/m. All other input parameters are optional.\n\n";
log_ << "The following flags are available\n";
log_ << "Call the program with flag \"-help\", or without parameters to print this message, or check any generated log file.\n";
log_ << "Call the program with flag \"-verbose\", to print log messages in the standard output stream as well as in the log file.\n\n";
log_ << "Parameters are specified as: \"-<argument name> <argument>\", (without <>), and the following parameters are configureable:n";
log_ << "\"-inputFile <path>\" (mandatory)\n";
log_ << "\"Input obj file that must contain a textured mesh.\n\n";
log_ << "\"-inputGeoRefFile <path>\" (optional, if specified boundary points are assumed to be given as world coordinates. If not specified, the boundary points are assumed to be local coordinates)\n";
log_ << "\"Input geograpical reference system file that describes the world position of the model's origin.\n\n";
log_ << "\"-outputFile <path>\" (optional, default: ortho.jpg)\n";
log_ << "\"Target file in which the orthophoto is saved.\n\n";
log_ << "\"-outputCornerFile <path>\" (optional)\n";
log_ << "\"Target text file for boundary corner points, written as \"xmin ymin xmax ymax\".\n\n";
log_ << "\"-resolution <pixels/m>\" (mandatory)\n";
log_ << "\"The number of pixels used per meter.\n\n";
log_ << "\"-boundary <Point1x Point1y Point2x Point2y Point3x Point3y Point4x Point4y>\" (optional, if not specified the entire model will be rendered)\n";
log_ << "\"Describes the area which should be covered in the ortho photo. The area will be a bounding box containing all four points. The points should be given in the same georeference system as the model.\n\n";
log_ << "\"-boundaryMinMax <MinX MinY MaxX MaxY>\" (optional, if not specified the entire model will be rendered.)\n";
log_ << "\"Describes the area which should be covered in the ortho photo. The area will be a bounding box with corners at MinX, MinY and MaxX, MaxY. The points should be given in the same georeference system as the model.\n\n";
log_.setIsPrintingInCout(false);
}
void OdmOrthoPhoto::createOrthoPhoto()
{
if(inputFile_.empty())
{
throw OdmOrthoPhotoException("Failed to create ortho photo, no texture mesh given.");
}
if(boundaryDefined_)
{
if(inputGeoRefFile_.empty())
{
// Points are assumed to be given in as local points.
adjustBoundsForLocal();
}
else
{
// Points are assumed to be given in as world points.
adjustBoundsForGeoRef();
}
}
else if(!inputGeoRefFile_.empty())
{
// No boundary points specified, but georeference system file was given.
log_ << "Warning:\n";
log_ << "\tSpecified -inputGeoRefFile, but no boundary points. The georeference system will be ignored.\n";
}
log_ << "Reading mesh file...\n";
// The textureds mesh.
pcl::TextureMesh mesh;
pcl::io::loadOBJFile(inputFile_, mesh);
log_ << ".. mesh file read.\n\n";
// Does the model have more than one material?
multiMaterial_ = 1 < mesh.tex_materials.size();
if(multiMaterial_)
{
// Need to check relationship between texture coordinates and faces.
if(!isModelOk(mesh))
{
throw OdmOrthoPhotoException("Could not generate ortho photo: The given mesh has multiple textures, but the number of texture coordinates is NOT equal to 3 times the number of faces.");
}
}
if(!boundaryDefined_)
{
// Determine boundary from model.
adjustBoundsForEntireModel(mesh);
}
// The minimum and maximum boundary values.
float xMax, xMin, yMax, yMin;
xMin = std::min(std::min(boundaryPoint1_[0], boundaryPoint2_[0]), std::min(boundaryPoint3_[0], boundaryPoint4_[0]));
xMax = std::max(std::max(boundaryPoint1_[0], boundaryPoint2_[0]), std::max(boundaryPoint3_[0], boundaryPoint4_[0]));
yMin = std::min(std::min(boundaryPoint1_[1], boundaryPoint2_[1]), std::min(boundaryPoint3_[1], boundaryPoint4_[1]));
yMax = std::max(std::max(boundaryPoint1_[1], boundaryPoint2_[1]), std::max(boundaryPoint3_[1], boundaryPoint4_[1]));
log_ << "Ortho photo bounds x : " << xMin << " -> " << xMax << '\n';
log_ << "Ortho photo bounds y : " << yMin << " -> " << yMax << '\n';
// The size of the area.
float xDiff = xMax - xMin;
float yDiff = yMax - yMin;
log_ << "Ortho photo area : " << xDiff*yDiff << "m2\n";
// The resolution neccesary to fit the area with the given resolution.
int rowRes = static_cast<int>(std::ceil(resolution_*yDiff));
int colRes = static_cast<int>(std::ceil(resolution_*xDiff));
log_ << "Ortho photo resolution, width x height : " << colRes << "x" << rowRes << '\n';
// Check size of photo.
if(0 >= rowRes*colRes)
{
if(0 >= rowRes)
{
log_ << "Warning: ortho photo has zero area, height = " << rowRes << ". Forcing height = 1.\n";
rowRes = 1;
}
if(0 >= colRes)
{
log_ << "Warning: ortho photo has zero area, width = " << colRes << ". Forcing width = 1.\n";
colRes = 1;
}
log_ << "New ortho photo resolution, width x height : " << colRes << "x" << rowRes << '\n';
}
// Init ortho photo
photo_ = cv::Mat::zeros(rowRes, colRes, CV_8UC4) + cv::Scalar(255, 255, 255, 0);
depth_ = cv::Mat::zeros(rowRes, colRes, CV_32F) - std::numeric_limits<float>::infinity();
// Contains the vertices of the mesh.
pcl::PointCloud<pcl::PointXYZ>::Ptr meshCloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::fromPCLPointCloud2 (mesh.cloud, *meshCloud);
// Creates a transformation which aligns the area for the ortho photo.
Eigen::Transform<float, 3, Eigen::Affine> transform = getROITransform(xMin, -yMax);
log_ << "Translating and scaling mesh...\n";
// Move the mesh into position.
pcl::transformPointCloud(*meshCloud, *meshCloud, transform);
log_ << ".. mesh translated and scaled.\n\n";
// Flatten texture coordiantes.
std::vector<Eigen::Vector2f> uvs;
for(size_t t = 0; t < mesh.tex_coordinates.size(); ++t)
{
uvs.insert(uvs.end(), mesh.tex_coordinates[t].begin(), mesh.tex_coordinates[t].end());
}
// The current material texture
cv::Mat texture;
// Used to keep track of the global face index.
size_t faceOff = 0;
log_ << "Rendering the ortho photo...\n";
// Iterate over each part of the mesh (one per material).
for(size_t t = 0; t < mesh.tex_materials.size(); ++t)
{
// The material of the current submesh.
pcl::TexMaterial material = mesh.tex_materials[t];
texture = cv::imread(material.tex_file);
// Check for missing files.
if(texture.empty())
{
log_ << "Material texture could not be read:\n";
log_ << material.tex_file << '\n';
log_ << "Could not be read as image, does the file exist?\n";
continue; // Skip to next material.
}
// The faces of the current submesh.
std::vector<pcl::Vertices> faces = mesh.tex_polygons[t];
// Iterate over each face...
for(size_t faceIndex = 0; faceIndex < faces.size(); ++faceIndex)
{
// The current polygon.
pcl::Vertices polygon = faces[faceIndex];
// ... and draw it into the ortho photo.
drawTexturedTriangle(texture, polygon, meshCloud, uvs, faceIndex+faceOff);
}
faceOff += faces.size();
log_ << "Material " << t << " rendered.\n";
}
log_ << "...ortho photo rendered\n";
log_ << '\n';
log_ << "Writing ortho photo to " << outputFile_ << "\n";
cv::imwrite(outputFile_, photo_);
if (!outputCornerFile_.empty())
{
log_ << "Writing corner coordinates to " << outputCornerFile_ << "\n";
std::ofstream cornerStream(outputCornerFile_.c_str());
if (!cornerStream.is_open())
{
throw OdmOrthoPhotoException("Failed opening output corner file " + outputCornerFile_ + ".");
}
cornerStream.setf(std::ios::scientific, std::ios::floatfield);
cornerStream.precision(17);
cornerStream << xMin << " " << yMin << " " << xMax << " " << yMax;
cornerStream.close();
}
log_ << "Orthophoto generation done.\n";
}
void OdmOrthoPhoto::adjustBoundsForGeoRef()
{
log_ << "Adjusting bounds for world coordinates\n";
// A stream of the georef system.
std::ifstream geoRefStream(inputGeoRefFile_.c_str());
// The system name
std::string system;
// The east and north offsets
int eastOffset, northOffset;
// Parse file
std::getline(geoRefStream, system);
if(!(geoRefStream >> eastOffset))
{
throw OdmOrthoPhotoException("Could not extract geographical reference system from \n" + inputGeoRefFile_ + "\nCould not extract east offset.");
}
if(!(geoRefStream >> northOffset))
{
throw OdmOrthoPhotoException("Could not extract geographical reference system from \n" + inputGeoRefFile_ + "\nCould not extract north offset.");
}
log_ << "Georeference system:\n";
log_ << system << "\n";
log_ << "East offset: " << eastOffset << "\n";
log_ << "North offset: " << northOffset << "\n";
// Adjust boundary points.
boundaryPoint1_[0] = static_cast<float>(worldPoint1_.eastInteger_ - eastOffset) + worldPoint1_.eastFractional_;
boundaryPoint1_[1] = static_cast<float>(worldPoint1_.northInteger_ - northOffset) + worldPoint1_.northFractional_;
boundaryPoint2_[0] = static_cast<float>(worldPoint2_.eastInteger_ - eastOffset) + worldPoint2_.eastFractional_;
boundaryPoint2_[1] = static_cast<float>(worldPoint2_.northInteger_ - northOffset) + worldPoint2_.northFractional_;
boundaryPoint3_[0] = static_cast<float>(worldPoint3_.eastInteger_ - eastOffset) + worldPoint3_.eastFractional_;
boundaryPoint3_[1] = static_cast<float>(worldPoint3_.northInteger_ - northOffset) + worldPoint3_.northFractional_;
boundaryPoint4_[0] = static_cast<float>(worldPoint4_.eastInteger_ - eastOffset) + worldPoint4_.eastFractional_;
boundaryPoint4_[1] = static_cast<float>(worldPoint4_.northInteger_ - northOffset) + worldPoint4_.northFractional_;
log_ << "Local boundary points:\n";
log_ << "Point 1: " << boundaryPoint1_[0] << " " << boundaryPoint1_[1] << "\n";
log_ << "Point 2: " << boundaryPoint2_[0] << " " << boundaryPoint2_[1] << "\n";
log_ << "Point 3: " << boundaryPoint3_[0] << " " << boundaryPoint3_[1] << "\n";
log_ << "Point 4: " << boundaryPoint4_[0] << " " << boundaryPoint4_[1] << "\n";
}
void OdmOrthoPhoto::adjustBoundsForLocal()
{
log_ << "Adjusting bounds for local coordinates\n";
// Set boundary points from world points.
boundaryPoint1_[0] = static_cast<float>(worldPoint1_.eastInteger_ ) + worldPoint1_.eastFractional_;
boundaryPoint1_[1] = static_cast<float>(worldPoint1_.northInteger_) + worldPoint1_.northFractional_;
boundaryPoint2_[0] = static_cast<float>(worldPoint2_.eastInteger_ ) + worldPoint2_.eastFractional_;
boundaryPoint2_[1] = static_cast<float>(worldPoint2_.northInteger_) + worldPoint2_.northFractional_;
boundaryPoint3_[0] = static_cast<float>(worldPoint3_.eastInteger_ ) + worldPoint3_.eastFractional_;
boundaryPoint3_[1] = static_cast<float>(worldPoint3_.northInteger_) + worldPoint3_.northFractional_;
boundaryPoint4_[0] = static_cast<float>(worldPoint4_.eastInteger_ ) + worldPoint4_.eastFractional_;
boundaryPoint4_[1] = static_cast<float>(worldPoint4_.northInteger_) + worldPoint4_.northFractional_;
log_ << "Local boundary points:\n";
log_ << "Point 1: " << boundaryPoint1_[0] << " " << boundaryPoint1_[1] << "\n";
log_ << "Point 2: " << boundaryPoint2_[0] << " " << boundaryPoint2_[1] << "\n";
log_ << "Point 3: " << boundaryPoint3_[0] << " " << boundaryPoint3_[1] << "\n";
log_ << "Point 4: " << boundaryPoint4_[0] << " " << boundaryPoint4_[1] << "\n";
log_ << "\n";
}
void OdmOrthoPhoto::adjustBoundsForEntireModel(const pcl::TextureMesh &mesh)
{
log_ << "Set boundary to contain entire model.\n";
// The boundary of the model.
float xMin, xMax, yMin, yMax;
xMin = std::numeric_limits<float>::infinity();
xMax = -std::numeric_limits<float>::infinity();
yMin = std::numeric_limits<float>::infinity();
yMax = -std::numeric_limits<float>::infinity();
// Contains the vertices of the mesh.
pcl::PointCloud<pcl::PointXYZ>::Ptr meshCloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::fromPCLPointCloud2 (mesh.cloud, *meshCloud);
for(size_t t = 0; t < mesh.tex_materials.size(); ++t)
{
// The faces of the current submesh.
std::vector<pcl::Vertices> faces = mesh.tex_polygons[t];
// Iterate over each face...
for(size_t faceIndex = 0; faceIndex < faces.size(); ++faceIndex)
{
// The current polygon.
pcl::Vertices polygon = faces[faceIndex];
// The index to the vertices of the polygon.
size_t v1i = polygon.vertices[0];
size_t v2i = polygon.vertices[1];
size_t v3i = polygon.vertices[2];
// The polygon's points.
pcl::PointXYZ v1 = meshCloud->points[v1i];
pcl::PointXYZ v2 = meshCloud->points[v2i];
pcl::PointXYZ v3 = meshCloud->points[v3i];
xMin = std::min(std::min(xMin, v1.x), std::min(v2.x, v3.x));
xMax = std::max(std::max(xMax, v1.x), std::max(v2.x, v3.x));
yMin = std::min(std::min(yMin, v1.y), std::min(v2.y, v3.y));
yMax = std::max(std::max(yMax, v1.y), std::max(v2.y, v3.y));
}
}
// Create dummy boundary points.
boundaryPoint1_[0] = xMin; boundaryPoint1_[1] = yMin;
boundaryPoint2_[0] = xMin; boundaryPoint2_[1] = yMax;
boundaryPoint3_[0] = xMax; boundaryPoint3_[1] = yMax;
boundaryPoint4_[0] = xMax; boundaryPoint4_[1] = yMin;
log_ << "Local boundary points:\n";
log_ << "Point 1: " << boundaryPoint1_[0] << " " << boundaryPoint1_[1] << "\n";
log_ << "Point 2: " << boundaryPoint2_[0] << " " << boundaryPoint2_[1] << "\n";
log_ << "Point 3: " << boundaryPoint3_[0] << " " << boundaryPoint3_[1] << "\n";
log_ << "Point 4: " << boundaryPoint4_[0] << " " << boundaryPoint4_[1] << "\n";
log_ << "\n";
}
Eigen::Transform<float, 3, Eigen::Affine> OdmOrthoPhoto::getROITransform(float xMin, float yMin) const
{
// The tranform used to move the chosen area into the ortho photo.
Eigen::Transform<float, 3, Eigen::Affine> transform;
transform(0, 0) = resolution_; // x Scaling.
transform(1, 0) = 0.0f;
transform(2, 0) = 0.0f;
transform(3, 0) = 0.0f;
transform(0, 1) = 0.0f;
transform(1, 1) = -resolution_; // y Scaling, mirrored for easier rendering.
transform(2, 1) = 0.0f;
transform(3, 1) = 0.0f;
transform(0, 2) = 0.0f;
transform(1, 2) = 0.0f;
transform(2, 2) = 1.0f;
transform(3, 2) = 0.0f;
transform(0, 3) = -xMin*resolution_; // x Translation
transform(1, 3) = -yMin*resolution_; // y Translation
transform(2, 3) = 0.0f;
transform(3, 3) = 1.0f;
return transform;
}
void OdmOrthoPhoto::drawTexturedTriangle(const cv::Mat &texture, const pcl::Vertices &polygon, const pcl::PointCloud<pcl::PointXYZ>::Ptr &meshCloud, const std::vector<Eigen::Vector2f> &uvs, size_t faceIndex)
{
// The index to the vertices of the polygon.
size_t v1i = polygon.vertices[0];
size_t v2i = polygon.vertices[1];
size_t v3i = polygon.vertices[2];
// The polygon's points.
pcl::PointXYZ v1 = meshCloud->points[v1i];
pcl::PointXYZ v2 = meshCloud->points[v2i];
pcl::PointXYZ v3 = meshCloud->points[v3i];
if(isSliverPolygon(v1, v2, v3))
{
log_ << "Warning: Sliver polygon found at face index " << faceIndex << '\n';
return;
}
// The face data. Position v*{x,y,z}. Texture coordinate v*{u,v}. * is the vertex number in the polygon.
float v1x, v1y, v1z, v1u, v1v;
float v2x, v2y, v2z, v2u, v2v;
float v3x, v3y, v3z, v3u, v3v;
// Barycentric coordinates of the currently rendered point.
float l1, l2, l3;
// The size of the photo, as float.
float fRows, fCols;
fRows = static_cast<float>(texture.rows);
fCols = static_cast<float>(texture.cols);
// Get vertex position.
v1x = v1.x; v1y = v1.y; v1z = v1.z;
v2x = v2.x; v2y = v2.y; v2z = v2.z;
v3x = v3.x; v3y = v3.y; v3z = v3.z;
// Get texture coorinates. (Special cases for PCL when using multiple materials vs one material)
if(multiMaterial_)
{
v1u = uvs[3*faceIndex][0]; v1v = uvs[3*faceIndex][1];
v2u = uvs[3*faceIndex+1][0]; v2v = uvs[3*faceIndex+1][1];
v3u = uvs[3*faceIndex+2][0]; v3v = uvs[3*faceIndex+2][1];
}
else
{
v1u = uvs[v1i][0]; v1v = uvs[v1i][1];
v2u = uvs[v2i][0]; v2v = uvs[v2i][1];
v3u = uvs[v3i][0]; v3v = uvs[v3i][1];
}
// Check bounding box overlap.
int xMin = static_cast<int>(std::min(std::min(v1x, v2x), v3x));
if(xMin > photo_.cols)
{
return; // Completly outside to the right.
}
int xMax = static_cast<int>(std::max(std::max(v1x, v2x), v3x));
if(xMax < 0)
{
return; // Completly outside to the left.
}
int yMin = static_cast<int>(std::min(std::min(v1y, v2y), v3y));
if(yMin > photo_.rows)
{
return; // Completly outside to the top.
}
int yMax = static_cast<int>(std::max(std::max(v1y, v2y), v3y));
if(yMax < 0)
{
return; // Completly outside to the bottom.
}
// Top point row and column positions
float topR, topC;
// Middle point row and column positions
float midR, midC;
// Bottom point row and column positions
float botR, botC;
// Find top, middle and bottom points.
if(v1y < v2y)
{
if(v1y < v3y)
{
if(v2y < v3y)
{
// 1 -> 2 -> 3
topR = v1y; topC = v1x;
midR = v2y; midC = v2x;
botR = v3y; botC = v3x;
}
else
{
// 1 -> 3 -> 2
topR = v1y; topC = v1x;
midR = v3y; midC = v3x;
botR = v2y; botC = v2x;
}
}
else
{
// 3 -> 1 -> 2
topR = v3y; topC = v3x;
midR = v1y; midC = v1x;
botR = v2y; botC = v2x;
}
}
else // v2y <= v1y
{
if(v2y < v3y)
{
if(v1y < v3y)
{
// 2 -> 1 -> 3
topR = v2y; topC = v2x;
midR = v1y; midC = v1x;
botR = v3y; botC = v3x;
}
else
{
// 2 -> 3 -> 1
topR = v2y; topC = v2x;
midR = v3y; midC = v3x;
botR = v1y; botC = v1x;
}
}
else
{
// 3 -> 2 -> 1
topR = v3y; topC = v3x;
midR = v2y; midC = v2x;
botR = v1y; botC = v1x;
}
}
// General appreviations:
// ---------------------
// tm : Top(to)Middle.
// mb : Middle(to)Bottom.
// tb : Top(to)Bottom.
// c : column.
// r : row.
// dr : DeltaRow, step value per row.
// The step along column for every step along r. Top to middle.
float ctmdr;
// The step along column for every step along r. Top to bottom.
float ctbdr;
// The step along column for every step along r. Middle to bottom.
float cmbdr;
ctbdr = (botC-topC)/(botR-topR);
// The current column position, from top to middle.
float ctm = topC;
// The current column position, from top to bottom.
float ctb = topC;
// Check for vertical line between middle and top.
if(FLT_EPSILON < midR-topR)
{
ctmdr = (midC-topC)/(midR-topR);
// The first pixel row for the bottom part of the triangle.
int rqStart = std::max(static_cast<int>(std::floor(topR+0.5f)), 0);
// The last pixel row for the top part of the triangle.
int rqEnd = std::min(static_cast<int>(std::floor(midR+0.5f)), photo_.rows);
// Travers along row from top to middle.
for(int rq = rqStart; rq < rqEnd; ++rq)
{
// Set the current column positions.
ctm = topC + ctmdr*(static_cast<float>(rq)+0.5f-topR);
ctb = topC + ctbdr*(static_cast<float>(rq)+0.5f-topR);
// The first pixel column for the current row.
int cqStart = std::max(static_cast<int>(std::floor(0.5f+std::min(ctm, ctb))), 0);
// The last pixel column for the current row.
int cqEnd = std::min(static_cast<int>(std::floor(0.5f+std::max(ctm, ctb))), photo_.cols);
for(int cq = cqStart; cq < cqEnd; ++cq)
{
// Get barycentric coordinates for the current point.
getBarycentricCoordiantes(v1, v2, v3, static_cast<float>(cq)+0.5f, static_cast<float>(rq)+0.5f, l1, l2, l3);
if(0.f > l1 || 0.f > l2 || 0.f > l3)
{
//continue;
}
// The z value for the point.
float z = v1z*l1+v2z*l2+v3z*l3;
// Check depth
float depthValue = depth_.at<float>(rq, cq);
if(z < depthValue)
{
// Current is behind another, don't draw.
continue;
}
// The uv values of the point.
float u, v;
u = v1u*l1+v2u*l2+v3u*l3;
v = v1v*l1+v2v*l2+v3v*l3;
renderPixel(rq, cq, u*fCols, (1.0f-v)*fRows, texture);
// Update depth buffer.
depth_.at<float>(rq, cq) = z;
}
}
}
if(FLT_EPSILON < botR-midR)
{
cmbdr = (botC-midC)/(botR-midR);
// The current column position, from middle to bottom.
float cmb = midC;
// The first pixel row for the bottom part of the triangle.
int rqStart = std::max(static_cast<int>(std::floor(midR+0.5f)), 0);
// The last pixel row for the bottom part of the triangle.
int rqEnd = std::min(static_cast<int>(std::floor(botR+0.5f)), photo_.rows);
// Travers along row from middle to bottom.
for(int rq = rqStart; rq < rqEnd; ++rq)
{
// Set the current column positions.
ctb = topC + ctbdr*(static_cast<float>(rq)+0.5f-topR);
cmb = midC + cmbdr*(static_cast<float>(rq)+0.5f-midR);
// The first pixel column for the current row.
int cqStart = std::max(static_cast<int>(std::floor(0.5f+std::min(cmb, ctb))), 0);
// The last pixel column for the current row.
int cqEnd = std::min(static_cast<int>(std::floor(0.5f+std::max(cmb, ctb))), photo_.cols);
for(int cq = cqStart; cq < cqEnd; ++cq)
{
// Get barycentric coordinates for the current point.
getBarycentricCoordiantes(v1, v2, v3, static_cast<float>(cq)+0.5f, static_cast<float>(rq)+0.5f, l1, l2, l3);
if(0.f > l1 || 0.f > l2 || 0.f > l3)
{
//continue;
}
// The z value for the point.
float z = v1z*l1+v2z*l2+v3z*l3;
// Check depth
float depthValue = depth_.at<float>(rq, cq);
if(z < depthValue)
{
// Current is behind another, don't draw.
continue;
}
// The uv values of the point.
float u, v;
u = v1u*l1+v2u*l2+v3u*l3;
v = v1v*l1+v2v*l2+v3v*l3;
renderPixel(rq, cq, u*fCols, (1.0f-v)*fRows, texture);
// Update depth buffer.
depth_.at<float>(rq, cq) = z;
}
}
}
}
void OdmOrthoPhoto::renderPixel(int row, int col, float s, float t, const cv::Mat &texture)
{
// The colors of the texture pixels. tl : top left, tr : top right, bl : bottom left, br : bottom right.
cv::Vec3b tl, tr, bl, br;
// The offset of the texture coordinate from its pixel positions.
float leftF, topF;
// The position of the top left pixel.
int left, top;
// The distance to the left and right pixel from the texture coordinate.
float dl, dt;
// The distance to the top and bottom pixel from the texture coordinate.
float dr, db;
dl = modff(s, &leftF);
dr = 1.0f - dl;
dt = modff(t, &topF);
db = 1.0f - dt;
left = static_cast<int>(leftF);
top = static_cast<int>(topF);
tl = texture.at<cv::Vec3b>(top, left);
tr = texture.at<cv::Vec3b>(top, left+1);
bl = texture.at<cv::Vec3b>(top+1, left);
br = texture.at<cv::Vec3b>(top+1, left+1);
// The interpolated color values.
float r = 0.0f, g = 0.0f, b = 0.0f;
// Red
r += static_cast<float>(tl[2]) * dr * db;
r += static_cast<float>(tr[2]) * dl * db;
r += static_cast<float>(bl[2]) * dr * dt;
r += static_cast<float>(br[2]) * dl * dt;
// Green
g += static_cast<float>(tl[1]) * dr * db;
g += static_cast<float>(tr[1]) * dl * db;
g += static_cast<float>(bl[1]) * dr * dt;
g += static_cast<float>(br[1]) * dl * dt;
// Blue
b += static_cast<float>(tl[0]) * dr * db;
b += static_cast<float>(tr[0]) * dl * db;
b += static_cast<float>(bl[0]) * dr * dt;
b += static_cast<float>(br[0]) * dl * dt;
photo_.at<cv::Vec4b>(row,col) = cv::Vec4b(static_cast<unsigned char>(b), static_cast<unsigned char>(g), static_cast<unsigned char>(r), 255);
}
void OdmOrthoPhoto::getBarycentricCoordiantes(pcl::PointXYZ v1, pcl::PointXYZ v2, pcl::PointXYZ v3, float x, float y, float &l1, float &l2, float &l3) const
{
// Diff along y.
float y2y3 = v2.y-v3.y;
float y1y3 = v1.y-v3.y;
float y3y1 = v3.y-v1.y;
float yy3 = y -v3.y;
// Diff along x.
float x3x2 = v3.x-v2.x;
float x1x3 = v1.x-v3.x;
float xx3 = x -v3.x;
// Normalization factor.
float norm = (y2y3*x1x3 + x3x2*y1y3);
l1 = (y2y3*(xx3) + x3x2*(yy3)) / norm;
l2 = (y3y1*(xx3) + x1x3*(yy3)) / norm;
l3 = 1 - l1 - l2;
}
bool OdmOrthoPhoto::isSliverPolygon(pcl::PointXYZ v1, pcl::PointXYZ v2, pcl::PointXYZ v3) const
{
// Calculations are made using doubles, to minize rounding errors.
Eigen::Vector3d a = Eigen::Vector3d(static_cast<double>(v1.x), static_cast<double>(v1.y), static_cast<double>(v1.z));
Eigen::Vector3d b = Eigen::Vector3d(static_cast<double>(v2.x), static_cast<double>(v2.y), static_cast<double>(v2.z));
Eigen::Vector3d c = Eigen::Vector3d(static_cast<double>(v3.x), static_cast<double>(v3.y), static_cast<double>(v3.z));
Eigen::Vector3d dummyVec = (a-b).cross(c-b);
// Area smaller than, or equal to, floating-point epsilon.
return std::numeric_limits<float>::epsilon() >= static_cast<float>(std::sqrt(dummyVec.dot(dummyVec))/2.0);
}
bool OdmOrthoPhoto::isModelOk(const pcl::TextureMesh &mesh)
{
// The number of texture coordinates in the model.
size_t nTextureCoordinates = 0;
// The number of faces in the model.
size_t nFaces = 0;
for(size_t t = 0; t < mesh.tex_coordinates.size(); ++t)
{
nTextureCoordinates += mesh.tex_coordinates[t].size();
}
for(size_t t = 0; t < mesh.tex_polygons.size(); ++t)
{
nFaces += mesh.tex_polygons[t].size();
}
log_ << "Number of faces in the model " << nFaces << '\n';
return 3*nFaces == nTextureCoordinates;
}

Wyświetl plik

@ -1,217 +0,0 @@
#pragma once
// C++
#include <limits.h>
#include <istream>
#include <ostream>
// PCL
#include <pcl/io/obj_io.h>
#include <pcl/common/transforms.h>
// OpenCV
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
// PCL
#include <pcl/common/eigen.h>
#include <pcl/common/common.h>
// OpenCV
#include <opencv2/core/core.hpp>
// Logger
#include "Logger.hpp"
/*!
* \brief The WorldPoint struct encapsules world coordiantes used for the orhto photo boundary.
* Points are separated into integersand fractional parts for high numerical stability.
*/
struct WorldPoint
{
int eastInteger_; /**< The inger part of the east point. */
float eastFractional_; /**< The farctional part of the east point. */
int northInteger_; /**< The inger part of the east point. */
float northFractional_; /**< The farctional part of the east point. */
/*!
* \brief Overloads operator '<<' for WorldPoint.
*
* \param os The output stream in which the WorldPoint should be printed.
* \param worldPoint The WorldPoint should be printed.
* \return A reference to the given output stream.
*/
friend std::ostream & operator<< (std::ostream &os, const WorldPoint &worldPoint);
/*!
* \brief Overloads operator '>>' for WorldPoint.
*
* \param is The input stream from which the WorldPoint should be extracted
* \param worldPoint The modified WorldPoint.
* \return A reference to the given input stream.
*/
friend std::istream & operator>> (std::istream &os, WorldPoint &worldPoint);
};
/*!
* \brief The OdmOrthoPhoto class is used to create an orthograpic photo over a given area.
* The class reads an oriented textured mesh from an OBJ-file.
* The class uses file read from pcl.
* The class uses image read and write from opencv.
*/
class OdmOrthoPhoto
{
public:
OdmOrthoPhoto();
~OdmOrthoPhoto();
/*!
* \brief run Runs the ortho photo functionality using the provided input arguments.
* For a list of accepted arguments, pleas see the main page documentation or
* call the program with parameter "-help".
* \param argc Application argument count.
* \param argv Argument values.
* \return 0 if successful.
*/
int run(int argc, char* argv[]);
private:
/*!
* \brief parseArguments Parses command line arguments.
*
* \param argc Application argument count.
* \param argv Argument values.
*/
void parseArguments(int argc, char* argv[]);
/*!
* \brief printHelp Prints help, explaining usage. Can be shown by calling the program with argument: "-help".
*/
void printHelp();
/*!
* \brief Create the ortho photo using the current settings.
*/
void createOrthoPhoto();
/*!
* \brief Adjusts the boundary points according to the given georef system.
*/
void adjustBoundsForGeoRef();
/*!
* \brief Adjusts the boundary points assuming the wolrd points are relative the local coordinate system.
*/
void adjustBoundsForLocal();
/*!
* \brief Adjusts the boundary points so that the entire model fits inside the photo.
*
* \param mesh The model which decides the boundary.
*/
void adjustBoundsForEntireModel(const pcl::TextureMesh &mesh);
/*!
* \brief Creates a transformation which aligns the area for the orthophoto.
*/
Eigen::Transform<float, 3, Eigen::Affine> getROITransform(float xMin, float yMin) const;
/*!
* \brief Renders a triangle into the ortho photo.
*
* Pixel center defined as middle of pixel for triangle rasterisation, and in lower left corner for texture look-up.
*
* \param texture The texture of the polygon.
* \param polygon The polygon as athree indices relative meshCloud.
* \param meshCloud Contains all vertices.
* \param uvs Contains the texture coordiantes for the active material.
* \param faceIndex The index of the face.
*/
void drawTexturedTriangle(const cv::Mat &texture, const pcl::Vertices &polygon, const pcl::PointCloud<pcl::PointXYZ>::Ptr &meshCloud, const std::vector<Eigen::Vector2f> &uvs, size_t faceIndex);
/*!
* \brief Sets the color of a pixel in the photo.
*
* \param row The row index of the pixel.
* \param col The column index of the pixel.
* \param s The u texture-coordinate, multiplied with the number of columns in the texture.
* \param t The v texture-coordinate, multiplied with the number of rows in the texture.
* \param texture The texture from which to get the color.
**/
void renderPixel(int row, int col, float u, float v, const cv::Mat &texture);
/*!
* \brief Calcualtes the barycentric coordinates of a point in a triangle.
*
* \param v1 The first triangle vertex.
* \param v2 The second triangle vertex.
* \param v3 The third triangle vertex.
* \param x The x coordinate of the point.
* \param y The y coordinate of the point.
* \param l1 The first vertex weight.
* \param l2 The second vertex weight.
* \param l3 The third vertex weight.
*/
void getBarycentricCoordiantes(pcl::PointXYZ v1, pcl::PointXYZ v2, pcl::PointXYZ v3, float x, float y, float &l1, float &l2, float &l3) const;
/*!
* \brief Check if a given polygon is a sliver polygon.
*
* \param v1 The first vertex of the polygon.
* \param v2 The second vertex of the polygon.
* \param v3 The third vertex of the polygon.
*/
bool isSliverPolygon(pcl::PointXYZ v1, pcl::PointXYZ v2, pcl::PointXYZ v3) const;
/*!
* \brief Check if the model is suitable for ortho photo generation.
*
* \param mesh The model.
* \return True if the model is ok for generating ortho photo.
*/
bool isModelOk(const pcl::TextureMesh &mesh);
Logger log_; /**< Logging object. */
std::string inputFile_; /**< Path to the textured mesh as an obj-file. */
std::string inputGeoRefFile_; /**< Path to the georeference system file. */
std::string outputFile_; /**< Path to the destination file. */
std::string outputCornerFile_; /**< Path to the output corner file. */
std::string logFile_; /**< Path to the log file. */
float resolution_; /**< The number of pixels per meter in the ortho photo. */
bool boundaryDefined_; /**< True if the user has defined a boundary. */
WorldPoint worldPoint1_; /**< The first boundary point for the ortho photo, in world coordiantes. */
WorldPoint worldPoint2_; /**< The second boundary point for the ortho photo, in world coordiantes. */
WorldPoint worldPoint3_; /**< The third boundary point for the ortho photo, in world coordiantes. */
WorldPoint worldPoint4_; /**< The fourth boundary point for the ortho photo, in world coordiantes. */
Eigen::Vector2f boundaryPoint1_; /**< The first boundary point for the ortho photo, in local coordinates. */
Eigen::Vector2f boundaryPoint2_; /**< The second boundary point for the ortho photo, in local coordinates. */
Eigen::Vector2f boundaryPoint3_; /**< The third boundary point for the ortho photo, in local coordinates. */
Eigen::Vector2f boundaryPoint4_; /**< The fourth boundary point for the ortho photo, in local coordinates. */
cv::Mat photo_; /**< The ortho photo as an OpenCV matrix, CV_8UC3. */
cv::Mat depth_; /**< The depth of the ortho photo as an OpenCV matrix, CV_32F. */
bool multiMaterial_; /**< True if the mesh has multiple materials. **/
};
/*!
* \brief The OdmOrthoPhoto class
*/
class OdmOrthoPhotoException : public std::exception
{
public:
OdmOrthoPhotoException() : message("Error in OdmOrthoPhoto") {}
OdmOrthoPhotoException(std::string msgInit) : message("Error in OdmOrthoPhoto:\n" + msgInit) {}
~OdmOrthoPhotoException() throw() {}
virtual const char* what() const throw() {return message.c_str(); }
private:
std::string message; /**< The error message **/
};

Wyświetl plik

@ -1,8 +0,0 @@
// Ortho photo generator.
#include "OdmOrthoPhoto.hpp"
int main(int argc, char* argv[])
{
OdmOrthoPhoto orthoPhotoGenerator;
return orthoPhotoGenerator.run(argc, argv);
}

Wyświetl plik

@ -1,37 +0,0 @@
project(odm_texturing)
cmake_minimum_required(VERSION 2.8)
# Set pcl dir to the input spedified with option -DPCL_DIR="path"
set(PCL_DIR "PCL_DIR-NOTFOUND" CACHE "PCL_DIR" "Path to the pcl installation directory")
# Set opencv dir to the input spedified with option -DOPENCV_DIR="path"
set(OPENCV_DIR "OPENCV_DIR-NOTFOUND" CACHE "OPENCV_DIR" "Path to the opencv installation directory")
# Add compiler options.
add_definitions(-Wall -Wextra)
# Find pcl at the location specified by PCL_DIR
find_package(PCL 1.7 HINTS "${PCL_DIR}/share/pcl-1.7" REQUIRED)
# Find OpenCV at the default location
find_package(OpenCV HINTS "${OPENCV_DIR}" REQUIRED)
# Only link with required opencv modules.
set(OpenCV_LIBS opencv_core opencv_imgproc opencv_highgui)
# Add the PCL, Eigen and OpenCV include dirs.
# Necessary since the PCL_INCLUDE_DIR variable set by find_package is broken.)
include_directories(${PCL_ROOT}/include/pcl-${PCL_VERSION_MAJOR}.${PCL_VERSION_MINOR})
include_directories(${EIGEN_ROOT})
include_directories(${OpenCV_INCLUDE_DIRS})
#library_directories(${OpenCV_LIBRARY_DIRS})
# Add source directory
aux_source_directory("./src" SRC_LIST)
# Add exectuteable
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(odm_texturing ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_SURFACE_LIBRARIES} ${OpenCV_LIBS})

Wyświetl plik

@ -1,203 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by Qt Creator 2.4.1, 2015-02-09T16:23:25. -->
<qtcreator>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QString" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QString" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">System</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.DefaultCMakeTarget</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory">/home/spotscale/odm/OpenDroneMap_spotscale/odm_texturing4-build</value>
<value type="QString" key="CMakeProjectManager.CMakeBuildConfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-32bit./usr/bin/gdb</value>
<value type="QString" key="ProjectExplorer.BuildCOnfiguration.ToolChain">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-32bit./usr/bin/gdb</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="CMakeProjectManager.MakeStep.Clean">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments">clean</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets"/>
<value type="bool" key="CMakeProjectManager.MakeStep.Clean">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">all</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">No deployment</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Project.UseGlobal">true</value>
<value type="bool" key="Analyzer.Project.UseGlobal">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="CMakeProjectManager.BaseEnvironmentBase">2</value>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguation.Title">odm_texturing</value>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.Arguments">-verbose -bundleFile &quot;../../../shared_folder/copr2/reconstruction-with-image-size-1200/bundle/bundle.out&quot; -imagesPath &quot;../../../shared_folder/copr2&quot; -imagesListPath &quot;../../../shared_folder/copr2/reconstruction-with-image-size-1200/list.txt&quot; -inputModelPath &quot;../../../shared_folder/copr2/reconstruction-with-image-size-1200-results/odm_mesh-0000.ply&quot; -outputFolder &quot;../../../shared_folder/copr2/reconstruction-with-image-size-1200-results/odm_texturing/&quot; -textureResolution 4096 -textureWithSize 3600 -bundleResizedTo 1200</value>
<value type="bool" key="CMakeProjectManager.CMakeRunConfiguration.UseTerminal">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.CMakeRunConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">odm_texturing</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.</value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
<value type="QString">{785a73be-b55f-490c-9d46-e1451c235840}</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">10</value>
</data>
</qtcreator>

Wyświetl plik

@ -1,31 +0,0 @@
#include "Logger.hpp"
Logger::Logger(bool isPrintingInCout) : isPrintingInCout_(isPrintingInCout)
{
}
Logger::~Logger()
{
}
void Logger::printToFile(std::string filePath)
{
std::ofstream file(filePath.c_str(), std::ios::binary);
file << logStream_.str();
file.close();
}
bool Logger::isPrintingInCout() const
{
return isPrintingInCout_;
}
void Logger::setIsPrintingInCout(bool isPrintingInCout)
{
isPrintingInCout_ = isPrintingInCout;
}

Wyświetl plik

@ -1,68 +0,0 @@
#pragma once
// STL
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
/*!
* \brief The Logger class is used to store program messages in a log file.
* \details By using the << operator while printInCout is set, the class writes both to
* cout and to file, if the flag is not set, output is written to file only.
*/
class Logger
{
public:
/*!
* \brief Logger Contains functionality for printing and displaying log information.
* \param printInCout Flag toggling if operator << also writes to cout.
*/
Logger(bool isPrintingInCout = true);
/*!
* \brief Destructor.
*/
~Logger();
/*!
* \brief print Prints the contents of the log to file.
* \param filePath Path specifying where to write the log.
*/
void printToFile(std::string filePath);
/*!
* \brief isPrintingInCout Check if console printing flag is set.
* \return Console printing flag.
*/
bool isPrintingInCout() const;
/*!
* \brief setIsPrintingInCout Set console printing flag.
* \param isPrintingInCout Value, if true, messages added to the log are also printed in cout.
*/
void setIsPrintingInCout(bool isPrintingInCout);
/*!
* Operator for printing messages to log and in the standard output stream if desired.
*/
template<class T>
friend Logger& operator<< (Logger &log, T t)
{
// If console printing is enabled.
if (log.isPrintingInCout_)
{
std::cout << t;
std::cout.flush();
}
// Write to log.
log.logStream_ << t;
return log;
}
private:
bool isPrintingInCout_; /*!< If flag is set, log is printed in cout and written to the log. */
std::stringstream logStream_; /*!< Stream for storing the log. */
};

Wyświetl plik

@ -1,211 +0,0 @@
#pragma once
// STL
#include <iostream>
#include <fstream>
// PCL
#include <pcl/point_types.h>
#include <pcl/search/kdtree.h>
#include <pcl/surface/texture_mapping.h>
// OpenCV
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
// Modified PCL functions
#include "modifiedPclFunctions.hpp"
// Logging
#include "Logger.hpp"
/*!
* \brief The Coords struct Coordinate class used in recursiveFindCoordinates for OdmTexturing::sortPatches().
*/
struct Coords
{
// Coordinates for row and column
float r_, c_;
// If coordinates have been placed
bool success_;
Coords()
{
r_ = 0.0;
c_ = 0.0;
success_ = false;
}
};
/*!
* \brief The Patch struct Struct to hold all faces connected and with the same optimal camera.
*/
struct Patch
{
std::vector<size_t> faces_;
float minu_, minv_, maxu_, maxv_;
Coords c_;
bool placed_;
int materialIndex_;
int optimalCameraIndex_;
Patch()
{
placed_ = false;
faces_ = std::vector<size_t>(0);
minu_ = std::numeric_limits<double>::infinity();
minv_ = std::numeric_limits<double>::infinity();
maxu_ = 0.0;
maxv_ = 0.0;
optimalCameraIndex_ = -1;
materialIndex_ = 0;
}
};
/*!
* \brief The Node struct Node class for acceleration structure in OdmTexturing::sortPatches().
*/
struct Node
{
float r_, c_, width_, height_;
bool used_;
Node* rgt_;
Node* lft_;
Node()
{
r_ = 0.0;
c_ = 0.0;
width_ = 1.0;
height_ = 1.0;
used_ = false;
rgt_ = NULL;
lft_ = NULL;
}
Node(const Node &n)
{
r_ = n.r_;
c_ = n.c_;
used_ = n.used_;
width_ = n.width_;
height_ = n.height_;
rgt_ = n.rgt_;
lft_ = n.lft_;
}
};
/*!
* \brief The OdmTexturing class is used to create textures to a welded ply-mesh using the camera
* positions from pmvs as input. The result is stored in an obj-file with corresponding
* mtl-file and the textures saved as jpg.
*/
class OdmTexturing
{
public:
OdmTexturing();
~OdmTexturing();
/*!
* \brief run Runs the texturing functionality using the provided input arguments.
* For a list of the accepted arguments, please see the main page documentation or
* call the program with parameter "-help".
* \param argc Application argument count.
* \param argv Argument values.
* \return 0 if successful.
*/
int run(int argc, char **argv);
private:
/*!
* \brief parseArguments Parses command line arguments.
* \param argc Application argument count.
* \param argv Argument values.
*/
void parseArguments(int argc, char** argv);
/*!
* \brief loadMesh Loads a PLY-file containing vertices and faces.
*/
void loadMesh();
/*!
* \brief loadCameras Loads cameras from a bundle.out file with corresponding image list file.
*/
void loadCameras();
/*!
* \brief triangleToImageAssignment Assigns optimal camera to faces for the faces that are visible.
*/
void triangleToImageAssignment();
/*!
* \brief calculatePatches Arrange faces into patches as a prestep to arranging UV-mapping.
*/
void calculatePatches();
/*!
* \brief recursiveFindCoords Recursive function used in sortPatches() to find free area to place patch.
* \param n The container in which to check for free space in.
* \param w The width of the box to place.
* \param h The height of the box to place.
* \return The coordinates where the patch has been placed.
*/
Coords recursiveFindCoords(Node &n, float w, float h);
/*!
* \brief sortPatches Sorts patches into UV-containers to be used in createTextures() using a rectangle packer approach.
*/
void sortPatches();
/*!
* \brief createTextures Creates textures to the mesh.
*/
void createTextures();
/*!
* \brief writeObjFile Writes the textured mesh to file on the OBJ format.
*/
void writeObjFile();
/*!
* \brief printHelp Prints help, explaining usage. Can be shown by calling the program with arguments: "-help".
*/
void printHelp();
Logger log_; /**< Logging object. */
std::string logFilePath_; /**< Path to store the log file. */
std::string bundlePath_; /**< Path to the bundle.out file. */
std::string imagesPath_; /**< Path to the folder with all images in the image list. */
std::string imagesListPath_; /**< Path to the image list. */
std::string inputModelPath_; /**< Path to the ply-file containing the mesh to be textured. */
std::string outputFolder_; /**< Path to the folder to store the output mesh and textures. */
double bundleResizedTo_; /**< The size used in the previous steps to calculate the camera focal_length. */
double textureWithSize_; /**< The desired size of the images to texture with. */
double textureResolution_; /**< The resolution of each texture. */
double padding_; /**< A padding used to handle edge cases. */
int nrTextures_; /**< The number of textures created. */
pcl::TextureMesh::Ptr mesh_; /**< PCL Texture Mesh */
std::vector<Patch> patches_; /**< The vector containing all patches */
pcl::texture_mapping::CameraVector cameras_; /**< The vector containing all cameras. */
std::vector<int> tTIA_; /**< The vector containing the optimal cameras for all faces. */
};
class OdmTexturingException : public std::exception
{
public:
OdmTexturingException() : message("Error in OdmTexturing") {}
OdmTexturingException(std::string msgInit) : message("Error in OdmTexturing:\n" + msgInit) {}
~OdmTexturingException() throw() {}
virtual const char* what() const throw() {return message.c_str(); }
private:
std::string message; /**< The error message. */
};

Wyświetl plik

@ -1,15 +0,0 @@
// Include texturing source code
#include "OdmTexturing.hpp"
/*!
* \mainpage main OpenDroneMap Texturing Module
*
*
*
*/
int main (int argc, char** argv)
{
OdmTexturing textureCreator;
return textureCreator.run(argc, argv);
}

Wyświetl plik

@ -1,336 +0,0 @@
/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) 2012-, Open Perception, Inc.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "modifiedPclFunctions.hpp"
int saveOBJFile(const std::string &file_name, const pcl::TextureMesh &tex_mesh, unsigned precision)
{
if (tex_mesh.cloud.data.empty ())
{
PCL_ERROR ("[pcl::io::saveOBJFile] Input point cloud has no data!\n");
return (-1);
}
// Open file
std::ofstream fs;
fs.precision (precision);
fs.open (file_name.c_str ());
// Define material file
std::string mtl_file_name = file_name.substr (0, file_name.find_last_of (".")) + ".mtl";
// Strip path for "mtllib" command
std::string mtl_file_name_nopath = mtl_file_name;
//std::cout << mtl_file_name_nopath << std::endl;
mtl_file_name_nopath.erase (0, mtl_file_name.find_last_of ('/') + 1);
/* Write 3D information */
// number of points
int nr_points = tex_mesh.cloud.width * tex_mesh.cloud.height;
int point_size = tex_mesh.cloud.data.size () / nr_points;
// mesh size
int nr_meshes = tex_mesh.tex_polygons.size ();
// number of faces for header
int nr_faces = 0;
for (int m = 0; m < nr_meshes; ++m)
nr_faces += tex_mesh.tex_polygons[m].size ();
// Write the header information
fs << "####" << std::endl;
fs << "# OBJ dataFile simple version. File name: " << file_name << std::endl;
fs << "# Vertices: " << nr_points << std::endl;
fs << "# Faces: " <<nr_faces << std::endl;
fs << "# Material information:" << std::endl;
fs << "mtllib " << mtl_file_name_nopath << std::endl;
fs << "####" << std::endl;
// Write vertex coordinates
fs << "# Vertices" << std::endl;
for (int i = 0; i < nr_points; ++i)
{
int xyz = 0;
// "v" just be written one
bool v_written = false;
for (size_t d = 0; d < tex_mesh.cloud.fields.size (); ++d)
{
int count = tex_mesh.cloud.fields[d].count;
if (count == 0)
count = 1; // we simply cannot tolerate 0 counts (coming from older converter code)
int c = 0;
// adding vertex
if ((tex_mesh.cloud.fields[d].datatype == pcl::PCLPointField::FLOAT32) /*sensor_msgs::PointField::FLOAT32)*/ && (
tex_mesh.cloud.fields[d].name == "x" ||
tex_mesh.cloud.fields[d].name == "y" ||
tex_mesh.cloud.fields[d].name == "z"))
{
if (!v_written)
{
// write vertices beginning with v
fs << "v ";
v_written = true;
}
float value;
memcpy (&value, &tex_mesh.cloud.data[i * point_size + tex_mesh.cloud.fields[d].offset + c * sizeof (float)], sizeof (float));
fs << value;
if (++xyz == 3)
break;
fs << " ";
}
}
if (xyz != 3)
{
PCL_ERROR ("[pcl::io::saveOBJFile] Input point cloud has no XYZ data!\n");
return (-2);
}
fs << std::endl;
}
fs << "# "<< nr_points <<" vertices" << std::endl;
// // Write vertex normals
// for (int i = 0; i < nr_points; ++i)
// {
// int xyz = 0;
// // "vn" just be written one
// bool v_written = false;
// for (size_t d = 0; d < tex_mesh.cloud.fields.size (); ++d)
// {
// int count = tex_mesh.cloud.fields[d].count;
// if (count == 0)
// count = 1; // we simply cannot tolerate 0 counts (coming from older converter code)
// int c = 0;
// // adding vertex
// if ((tex_mesh.cloud.fields[d].datatype == pcl::PCLPointField::FLOAT32) && (
// tex_mesh.cloud.fields[d].name == "normal_x" ||
// tex_mesh.cloud.fields[d].name == "normal_y" ||
// tex_mesh.cloud.fields[d].name == "normal_z"))
// {
// if (!v_written)
// {
// // write vertices beginning with vn
// fs << "vn ";
// v_written = true;
// }
// float value;
// memcpy (&value, &tex_mesh.cloud.data[i * point_size + tex_mesh.cloud.fields[d].offset + c * sizeof (float)], sizeof (float));
// fs << value;
// if (++xyz == 3)
// break;
// fs << " ";
// }
// }
// if (xyz != 3)
// {
// //PCL_ERROR ("[pcl::io::saveOBJFile] Input point cloud has no normals!\n");
// //return (-2);
// }
// fs << std::endl;
// }
// Write vertex texture with "vt" (adding latter)
for (int m = 0; m < nr_meshes; ++m)
{
if(tex_mesh.tex_coordinates.size() == 0)
continue;
//PCL_INFO ("%d vertex textures in submesh %d\n", tex_mesh.tex_coordinates[m].size (), m);
fs << "# " << tex_mesh.tex_coordinates[m].size() << " vertex textures in submesh " << m << std::endl;
for (size_t i = 0; i < tex_mesh.tex_coordinates[m].size (); ++i)
{
fs << "vt ";
fs << tex_mesh.tex_coordinates[m][i][0] << " " << tex_mesh.tex_coordinates[m][i][1] << std::endl;
}
}
int f_idx = 0;
// int idx_vt =0;
//PCL_INFO ("Writting faces...\n");
for (int m = 0; m < nr_meshes; ++m)
{
if (m > 0)
f_idx += tex_mesh.tex_polygons[m-1].size ();
if(tex_mesh.tex_materials.size() !=0)
{
fs << "# The material will be used for mesh " << m << std::endl;
//TODO pbl here with multi texture and unseen faces
fs << "usemtl " << tex_mesh.tex_materials[m].tex_name << std::endl;
fs << "# Faces" << std::endl;
}
for (size_t i = 0; i < tex_mesh.tex_polygons[m].size(); ++i)
{
// Write faces with "f"
fs << "f";
size_t j = 0;
// There's one UV per vertex per face, i.e., the same vertex can have
// different UV depending on the face.
for (j = 0; j < tex_mesh.tex_polygons[m][i].vertices.size (); ++j)
{
unsigned int idx = tex_mesh.tex_polygons[m][i].vertices[j] + 1;
fs << " " << idx
<< "/" << 3*(i+f_idx) +j+1;
//<< "/" << idx; // vertex index in obj file format starting with 1
}
fs << std::endl;
}
//PCL_INFO ("%d faces in mesh %d \n", tex_mesh.tex_polygons[m].size () , m);
fs << "# "<< tex_mesh.tex_polygons[m].size() << " faces in mesh " << m << std::endl;
}
fs << "# End of File";
// Close obj file
//PCL_INFO ("Closing obj file\n");
fs.close ();
/* Write material defination for OBJ file*/
// Open file
//PCL_INFO ("Writing material files\n");
//dont do it if no material to write
if(tex_mesh.tex_materials.size() ==0)
return (0);
std::ofstream m_fs;
m_fs.precision (precision);
m_fs.open (mtl_file_name.c_str ());
//std::cout << "MTL file is located at_ " << mtl_file_name << std::endl;
// default
m_fs << "#" << std::endl;
m_fs << "# Wavefront material file" << std::endl;
m_fs << "#" << std::endl;
for(int m = 0; m < nr_meshes; ++m)
{
m_fs << "newmtl " << tex_mesh.tex_materials[m].tex_name << std::endl;
m_fs << "Ka "<< tex_mesh.tex_materials[m].tex_Ka.r << " " << tex_mesh.tex_materials[m].tex_Ka.g << " " << tex_mesh.tex_materials[m].tex_Ka.b << std::endl; // defines the ambient color of the material to be (r,g,b).
m_fs << "Kd "<< tex_mesh.tex_materials[m].tex_Kd.r << " " << tex_mesh.tex_materials[m].tex_Kd.g << " " << tex_mesh.tex_materials[m].tex_Kd.b << std::endl; // defines the diffuse color of the material to be (r,g,b).
m_fs << "Ks "<< tex_mesh.tex_materials[m].tex_Ks.r << " " << tex_mesh.tex_materials[m].tex_Ks.g << " " << tex_mesh.tex_materials[m].tex_Ks.b << std::endl; // defines the specular color of the material to be (r,g,b). This color shows up in highlights.
m_fs << "d " << tex_mesh.tex_materials[m].tex_d << std::endl; // defines the transparency of the material to be alpha.
m_fs << "Ns "<< tex_mesh.tex_materials[m].tex_Ns << std::endl; // defines the shininess of the material to be s.
m_fs << "illum "<< tex_mesh.tex_materials[m].tex_illum << std::endl; // denotes the illumination model used by the material.
// illum = 1 indicates a flat material with no specular highlights, so the value of Ks is not used.
// illum = 2 denotes the presence of specular highlights, and so a specification for Ks is required.
m_fs << "map_Kd " << tex_mesh.tex_materials[m].tex_file << std::endl;
m_fs << "###" << std::endl;
}
m_fs.close ();
return (0);
}
bool getPixelCoordinates(const pcl::PointXYZ &pt, const pcl::TextureMapping<pcl::PointXYZ>::Camera &cam, pcl::PointXY &UV_coordinates)
{
if (pt.z > 0)
{
// compute image center and dimension
double sizeX = cam.width;
double sizeY = cam.height;
double cx, cy;
if (cam.center_w > 0)
cx = cam.center_w;
else
cx = sizeX / 2.0;
if (cam.center_h > 0)
cy = cam.center_h;
else
cy = sizeY / 2.0;
double focal_x, focal_y;
if (cam.focal_length_w > 0)
focal_x = cam.focal_length_w;
else
focal_x = cam.focal_length;
if (cam.focal_length_h > 0)
focal_y = cam.focal_length_h;
else
focal_y = cam.focal_length;
// project point on camera's image plane
UV_coordinates.x = static_cast<float> ((focal_x * (pt.x / pt.z) + cx)); //horizontal
UV_coordinates.y = static_cast<float> ((focal_y * (pt.y / pt.z) + cy)); //vertical
// point is visible!
if (UV_coordinates.x >= 15.0 && UV_coordinates.x <= (sizeX - 15.0) && UV_coordinates.y >= 15.0 && UV_coordinates.y <= (sizeY - 15.0))
{
return (true); // point was visible by the camera
}
}
// point is NOT visible by the camera
UV_coordinates.x = -1.0f;
UV_coordinates.y = -1.0f;
return (false); // point was not visible by the camera
}
bool isFaceProjected (const pcl::TextureMapping<pcl::PointXYZ>::Camera &camera, const pcl::PointXYZ &p1, const pcl::PointXYZ &p2, const pcl::PointXYZ &p3, pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3)
{
return (getPixelCoordinates(p1, camera, proj1) && getPixelCoordinates(p2, camera, proj2) && getPixelCoordinates(p3, camera, proj3));
}
void getTriangleCircumscribedCircleCentroid( const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius)
{
// compute centroid's coordinates (translate back to original coordinates)
circumcenter.x = static_cast<float> (p1.x + p2.x + p3.x ) / 3;
circumcenter.y = static_cast<float> (p1.y + p2.y + p3.y ) / 3;
double r1 = (circumcenter.x - p1.x) * (circumcenter.x - p1.x) + (circumcenter.y - p1.y) * (circumcenter.y - p1.y) ;
double r2 = (circumcenter.x - p2.x) * (circumcenter.x - p2.x) + (circumcenter.y - p2.y) * (circumcenter.y - p2.y) ;
double r3 = (circumcenter.x - p3.x) * (circumcenter.x - p3.x) + (circumcenter.y - p3.y) * (circumcenter.y - p3.y) ;
// radius
radius = std::sqrt( std::max( r1, std::max( r2, r3) )) ;
}
bool checkPointInsideTriangle(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, const pcl::PointXY &pt)
{
// Compute vectors
Eigen::Vector2d v0, v1, v2;
v0(0) = p3.x - p1.x; v0(1) = p3.y - p1.y; // v0= C - A
v1(0) = p2.x - p1.x; v1(1) = p2.y - p1.y; // v1= B - A
v2(0) = pt.x - p1.x; v2(1) = pt.y - p1.y; // v2= P - A
// Compute dot products
double dot00 = v0.dot(v0); // dot00 = dot(v0, v0)
double dot01 = v0.dot(v1); // dot01 = dot(v0, v1)
double dot02 = v0.dot(v2); // dot02 = dot(v0, v2)
double dot11 = v1.dot(v1); // dot11 = dot(v1, v1)
double dot12 = v1.dot(v2); // dot12 = dot(v1, v2)
// Compute barycentric coordinates
double invDenom = 1.0 / (dot00*dot11 - dot01*dot01);
double u = (dot11*dot02 - dot01*dot12) * invDenom;
double v = (dot00*dot12 - dot01*dot02) * invDenom;
// Check if point is in triangle
return ((u >= 0) && (v >= 0) && (u + v < 1));
}

Wyświetl plik

@ -1,20 +0,0 @@
#pragma once
// STL
#include <iostream>
#include <fstream>
// PCL
#include <pcl/point_types.h>
#include <pcl/surface/texture_mapping.h>
#include <pcl/io/ply_io.h>
int saveOBJFile(const std::string &file_name, const pcl::TextureMesh &tex_mesh, unsigned precision);
bool getPixelCoordinates(const pcl::PointXYZ &pt, const pcl::TextureMapping<pcl::PointXYZ>::Camera &cam, pcl::PointXY &UV_coordinates);
bool isFaceProjected (const pcl::TextureMapping<pcl::PointXYZ>::Camera &camera, const pcl::PointXYZ &p1, const pcl::PointXYZ &p2, const pcl::PointXYZ &p3, pcl::PointXY &proj1, pcl::PointXY &proj2, pcl::PointXY &proj3);
void getTriangleCircumscribedCircleCentroid(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, pcl::PointXY &circumcenter, double &radius);
bool checkPointInsideTriangle(const pcl::PointXY &p1, const pcl::PointXY &p2, const pcl::PointXY &p3, const pcl::PointXY &pt);

128
pages/about.html 100644
Wyświetl plik

@ -0,0 +1,128 @@
<!DOCTYPE html>
<html>
<head>
<title>OpenDroneMap About</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link href="../css/map_styles.css" rel="stylesheet">
<link href="../css/cssmenu.css" rel="stylesheet">
<style>
html, body, #map {
height: 100%;
padding: 0;
margin: 0;
}
</style>
<link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/themes/css/cartodb.css" />
</head>
<body>
<div id='cssmenu'>
<div id="logo"><a href="https://opendronemap.github.io/odm/"><img src="../img/logo.svg"></a></div>
<ul>
<li><a href='#'><span>About</span></a></li>
<li><a href='https://github.com/OpenDroneMap/OpenDroneMap' target="_blank"><span>Code on GitHub</span></a></li>
<li class='active has-sub'><a href='#'><span>Example Data</span></a>
<ul>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/benchmark' target="_blank"><span>Benchmark</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/pacifica' target="_blank"><span>Pacifica (Beach)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/langley' target="_blank"><span>Langley (Town Center)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/apt' target="_blank"><span>Corridor (Trail)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/seneca' target="_blank"><span>Seneca (Color Infrared Farm)</span></a></li> </ul>
</li>
<li><a href='contact.html'><span>Contact</span></a></li>
</ul>
</div>
<div id="container">
<h1 class="main-header"><a href="#"><img src="../img/logo_full.svg"></a></h1>
<h1 id="what-is-it">What is it?</h1>
<p>OpenDroneMap is a toolchain for processing raw civilian UAS imagery to other useful products. What kind of products?</p>
<ol>
<li>Point Clouds</li>
<li>Digital Surface Models</li>
<li>Textured Digital Surface Models</li>
<li>Orthorectified Imagery</li>
<li>Classified Point Clouds</li>
<li>Digital Elevation Models</li>
<li>etc.</li>
</ol>
<p>So far, it does step 1 through 4: Point Clouds, meshes, textured meshes and orthophotography.</p>
<h1 id="steps-to-get-opendronemap-running">Steps to get OpenDroneMap running:</h1>
<p>(Requires Ubuntu 12.04 32-bit at this time. May also work with Ubuntu
12.04 64-bit. See https://github.com/OpenDroneMap/odm_vagrant for
running on Windows in a VM)</p>
<p>Run install.sh to build.</p>
<p><code>./install.sh</code></p>
<p>From a directory full of your images, run</p>
<p><code>./run.pl</code></p>
<hr>
<p>From Meshlab 1.3.3:</p>
<pre><code>* Open Project file, navigate to:
* &lt;project_location&gt;/reconstruction-with-image-size-1200/bundle/bundle.out
* It will prompt for the image list file
* &lt;project_location&gt;/reconstruction-with-image-size-1200/list.txt
* Control-L and delete "0 model"
* Import dense point cloud:
* e.g. &lt;project_location&gt;/reconstruction-with-image-size-1200-results/option-0000.ply
* (there may be multiple ply files)
* Make a mesh:
* Filters:Remeshing, Simplification and Reconstruction:Surface Reconstruction Poisson
* Texture the mesh
* Parameterization + texturing from registered rasters
</code></pre>
<hr>
<p>Example data can be found at https://github.com/OpenDroneMap/odm_data</p>
<hr>
<p>Long term, the aim is for the toolchain to also be able to optionally
push to a variety of online data repositories, pushing hi-resolution
aerials to <a href="http://opentopography.org/">OpenAerialMap</a>, point clouds to <a href="http://opentopography.org/">OpenTopography</a>,
and pushing digital elevation models to an emerging global repository
(yet to be named...). That leaves only digital surface model meshes and
UV textured meshes with no global repository home.</p>
<hr>
<h1 id="troubleshooting">Troubleshooting:</h1>
<p>If you run ODM with your own camera, it is possible you will see something like this:</p>
<pre><code> - configuration:
--cmvs-maxImages: 100
--end-with: pmvs
--match-size: 200
--matcher-ratio: 0.6
--matcher-threshold: 2
--pmvs-csize: 2
--pmvs-level: 1
--pmvs-minImageNum: 3
--pmvs-threshold: 0.7
--pmvs-wsize: 7
--resize-to: 1200
--start-with: resize
- source files - Fri Sep 19 13:47:42 UTC 2014
no CCD width or focal length found for DSC05391.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05392.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05393.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05394.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05395.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05396.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05397.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05398.JPG - camera: "SONY DSC-HX5V"
no CCD width or focal length found for DSC05399.JPG - camera: "SONY DSC-HX5V"
found no usable images - quitting
Died at ../../OpenDroneMap/./run.pl line 364.
</code></pre>
<p>This means that your camera is not in the database, https://github.com/OpenDroneMap/OpenDroneMap/blob/gh-pages/ccd_defs.pl</p>
<p>This problem is easily remedied. We need to know CCD size in the
camera. We'll get these for our Sony Cyber-shot DSC-HX5 from dpreview:
http://www.dpreview.com/products/sony/compacts/sony_dschx5/specifications</p>
<p>So, we'll add the following line to our ccd_defs.pl:</p>
<pre><code> "SONY DSC-HX5V" =&gt; 6.104, # 1/2.4"
</code></pre>
<p>And so others can use it, we'll do a pull request to add it to our array for everyone else.</p>
</body>
</html>

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 78 KiB

49
pages/contact.html 100644
Wyświetl plik

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<title>OpenDroneMap About</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link href="../css/map_styles.css" rel="stylesheet">
<link href="../css/cssmenu.css" rel="stylesheet">
<style>
html, body, #map {
height: 100%;
padding: 0;
margin: 0;
}
</style>
<link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/themes/css/cartodb.css" />
</head>
<body>
<div id='cssmenu'>
<div id="logo"><a href="https://opendronemap.github.io/odm/"><img src="../img/logo.svg"></a></div>
<ul>
<li><a href='about.html'><span>About</span></a></li>
<li><a href='https://github.com/OpenDroneMap/OpenDroneMap' target="_blank"><span>Code on GitHub</span></a></li>
<li class='active has-sub'><a href='#'><span>Example Data</span></a>
<ul>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/benchmark' target="_blank"><span>Benchmark</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/pacifica' target="_blank"><span>Pacifica (Beach)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/langley' target="_blank"><span>Langley (Town Center)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/apt' target="_blank"><span>Corridor (Trail)</span></a></li>
<li><a href='https://github.com/OpenDroneMap/odm_data/tree/master/seneca' target="_blank"><span>Seneca (Color Infrared Farm)</span></a></li> </ul>
</li>
<li><a href='#'><span>Contact</span></a></li>
</ul>
</div>
<div id="container">
<h1 class="main-header"><a href="#"><img src="../img/logo_full.svg"></a></h1>
<h1 id="main-header">Contact</h1>
<p><a href='http://lists.osgeo.org/cgi-bin/mailman/listinfo/opendronemap-users'<span>OpenDroneMap Users Mailing List</span></a></p>
<p><a href='http://lists.osgeo.org/cgi-bin/mailman/listinfo/opendronemap-dev'<span>OpenDroneMap Developer Mailing List</span></a></p>
<p><a href='https://github.com/OpenDroneMap/OpenDroneMap/issues'><span>Contact via GitHub Issue</span></a></p>
<p><a href='https://github.com/OpenDroneMap/OpenDroneMap/pulls'><span>Pull Requests</span></a></p>
<h1 id="main-header">(also)</h1>
<p><a href='https://twitter.com/smathermather'><span>Twitter</span></a></p>
</body>
</html>

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -1 +0,0 @@
<HTML><HEAD><TITLE> Web Authentication Redirect</TITLE><META http-equiv="Cache-control" content="no-cache"><META http-equiv="Pragma" content="no-cache"><META http-equiv="Expires" content="-1"><META http-equiv="refresh" content="1; URL=http://1.1.1.1/login.html?redirect=google.com/"></HEAD></HTML>

1008
run.py

Plik diff jest za duży Load Diff

@ -1 +0,0 @@
Subproject commit b34cc5dcd54345272028b68f82fa4d0ae8a103c9

Wyświetl plik

@ -1 +0,0 @@
24aa11d25f9716b9f6367bc9c19f6048a7f27a1f