Merge branch 'upstream--gh-pages' into opensfm

Conflicts:
	run.pl
pull/167/head
Pau Gargallo 2015-08-26 14:30:45 +02:00
commit 163dcda3e1
28 zmienionych plików z 3623 dodań i 717 usunięć

1
.dockerignore 100644
Wyświetl plik

@ -0,0 +1 @@
Dockerfile

3
.gitignore vendored
Wyświetl plik

@ -5,7 +5,8 @@ lib/
logs/
share/
src/
odm_texturing-build/
*.user
cmvs.tar.gz
parallel.tar.bz2
pcl.tar.gz

48
Dockerfile 100644
Wyświetl plik

@ -0,0 +1,48 @@
FROM ubuntu:14.04
MAINTAINER Danilo Bargen <mail@dbrgn.ch>
# Env variables
ENV DEBIAN_FRONTEND noninteractive
# Install git
RUN apt-get update \
&& apt-get install -y git
# Install dependencies
RUN 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.pl"]

Wyświetl plik

@ -15,24 +15,44 @@ OpenDroneMap is a toolchain for processing raw civilian UAS imagery to other use
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
Steps to get OpenDroneMap running:
==================================
<del>(Requires Ubuntu 12.04 32-bit at this time. May also work with Ubuntu 12.04 64-bit.</del>
(Requires Ubuntu 12.04 or later, see https://github.com/OpenDroneMap/odm_vagrant for running on Windows in a VM)
Run install.sh to build.
``` ./install.sh ```
./install.sh
From a directory full of your images, run
``` ./run.pl ```
./run.pl
An overview of installing and running OpenDroneMap on Ubuntu can be found here: https://www.youtube.com/watch?v=e2qp3o8caPs
Now that texturing is in the code base, you can access the full textured meshes using MeshLab. Open MeshLab, and 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
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`
---
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.pl` script, simply pass it as arguments to the `docker run` command.
---
@ -44,14 +64,23 @@ Long term, the aim is for the toolchain to also be able to optionally push to a
---
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: 100
--cmvs-maxImages: 500
--end-with: pmvs
--match-size: 200
--matcher-ratio: 0.6
@ -84,12 +113,25 @@ 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.pl
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.pl:
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.pl
If it prints the message 'CCD_DEFS compiles OK', then you can commit your changes.
"SONY DSC-HX5V" => 6.104, # 1/2.4"
And so others can use it, we'll do a pull request to add it to our array for everyone else.
---
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.

317
ccd_defs.json 100644
Wyświetl plik

@ -0,0 +1,317 @@
{
"Apple iPhone 5s": 8.46,
"Asahi Optical Co.,Ltd. PENTAX Optio330RS": 7.176,
"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 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 S100": 7.44,
"Canon Canon PowerShot S110": 5.27,
"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,
"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 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-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,
"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 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 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
}

Wyświetl plik

@ -1,302 +0,0 @@
#!/usr/bin/perl
%ccdWidths = (
"Asahi Optical Co.,Ltd. PENTAX Optio330RS" => 7.176, # 1/1.8"
"Canon Canon DIGITAL IXUS 400" => 7.176, # 1/1.8"
"Canon Canon DIGITAL IXUS 40" => 5.76, # 1/2.5"
"Canon Canon DIGITAL IXUS 430" => 7.176, # 1/1.8"
"Canon Canon DIGITAL IXUS 500" => 7.176, # 1/1.8"
"Canon Canon DIGITAL IXUS 50" => 5.76, # 1/2.5"
"Canon Canon DIGITAL IXUS 55" => 5.76, # 1/2.5"
"Canon Canon DIGITAL IXUS 60" => 5.76, # 1/2.5"
"Canon Canon DIGITAL IXUS 65" => 5.76, # 1/2.5"
"Canon Canon DIGITAL IXUS 700" => 7.176, # 1/1.8"
"Canon Canon DIGITAL IXUS 750" => 7.176, # 1/1.8"
"Canon Canon DIGITAL IXUS 800 IS" => 5.76, # 1/2.5"
"Canon Canon DIGITAL IXUS II" => 5.27, # 1/2.7"
"Canon Canon DIGITAL IXUS 430" => 6.18, # 1/2.3"
"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 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, # 1/1.8"
"Canon Canon PowerShot A10" => 5.23, # 1/1.8"
"Canon Canon PowerShot A20" => 7.176, # 1/1.8"
"Canon Canon PowerShot A400" => 4.54, # 1/3.2"
"Canon Canon PowerShot A40" => 5.27, # 1/2.7"
"Canon Canon PowerShot A510" => 5.76, # 1/2.5"
"Canon Canon PowerShot A520" => 5.76, # 1/2.5"
"Canon Canon PowerShot A530" => 5.76, # 1/2.5"
"Canon Canon PowerShot A60" => 5.27, # 1/2.7"
"Canon Canon PowerShot A620" => 7.176, # 1/1.8"
"Canon Canon PowerShot A630" => 7.176, # 1/1.8"
"Canon Canon PowerShot A640" => 7.176, # 1/1.8"
"Canon Canon PowerShot A700" => 5.76, # 1/2.5"
"Canon Canon PowerShot A70" => 5.27, # 1/2.7"
"Canon Canon PowerShot A710 IS" => 5.76, # 1/2.5"
"Canon Canon PowerShot A75" => 5.27, # 1/2.7"
"Canon Canon PowerShot A80" => 7.176, # 1/1.8"
"Canon Canon PowerShot A85" => 5.27, # 1/2.7"
"Canon Canon PowerShot A95" => 7.176, # 1/1.8"
"Canon Canon PowerShot G1" => 7.176, # 1/1.8"
"Canon Canon PowerShot G2" => 7.176, # 1/1.8"
"Canon Canon PowerShot G3" => 7.176, # 1/1.8"
"Canon Canon PowerShot G5" => 7.176, # 1/1.8"
"Canon Canon PowerShot G6" => 7.176, # 1/1.8"
"Canon Canon PowerShot G7" => 7.176, # 1/1.8"
"Canon Canon PowerShot G9" => 7.600, # 1/1.7"
"Canon Canon PowerShot Pro1" => 8.8, # 2/3"
"Canon Canon PowerShot S100" => 7.44, # 1/1.7"
"Canon Canon PowerShot S110" => 5.27, # 1/2.7"
"Canon Canon PowerShot S1 IS" => 5.27, # 1/2.7"
"Canon Canon PowerShot S200" => 5.27, # 1/2.7"
"Canon Canon PowerShot S2 IS" => 5.76, # 1/2.5"
"Canon Canon PowerShot S30" => 7.176, # 1/1.8"
"Canon Canon PowerShot S3 IS" => 5.76, # 1/2.5"
"Canon Canon PowerShot S400" => 7.176, # 1/1.8"
"Canon Canon PowerShot S40" => 7.176, # 1/1.8"
"Canon Canon PowerShot S410" => 7.176, # 1/1.8"
"Canon Canon PowerShot S45" => 7.176, # 1/1.8"
"Canon Canon PowerShot S500" => 7.176, # 1/1.8"
"Canon Canon PowerShot S50" => 7.176, # 1/1.8"
"Canon Canon PowerShot S60" => 7.176, # 1/1.8"
"Canon Canon PowerShot S70" => 7.176, # 1/1.8"
"Canon Canon PowerShot S80" => 7.176, # 1/1.8"
"Canon Canon PowerShot SD1000" => 5.75, # 1/2.5"
"Canon Canon PowerShot SD100" => 5.27, # 1/2.7"
"Canon Canon PowerShot SD10" => 5.75, # 1/2.5"
"Canon Canon PowerShot SD110" => 5.27, # 1/2.7"
"Canon Canon PowerShot SD200" => 5.76, # 1/2.5"
"Canon Canon PowerShot SD300" => 5.76, # 1/2.5"
"Canon Canon PowerShot SD400" => 5.76, # 1/2.5"
"Canon Canon PowerShot SD450" => 5.76, # 1/2.5"
"Canon Canon PowerShot SD500" => 7.176, # 1/1.8"
"Canon Canon PowerShot SD550" => 7.176, # 1/1.8"
"Canon Canon PowerShot SD600" => 5.76, # 1/2.5"
"Canon Canon PowerShot SD630" => 5.76, # 1/2.5"
"Canon Canon PowerShot SD700 IS" => 5.76, # 1/2.5"
"Canon Canon PowerShot SD750" => 5.75, # 1/2.5"
"Canon Canon PowerShot SD800 IS" => 5.76, # 1/2.5"
"Canon Canon PowerShot SX260 HS" => 6.2, # 1/2.3"
"Canon EOS 300D DIGITAL" => 22.66,
"Canon EOS DIGITAL REBEL" => 22.66,
"Canon PowerShot A510" => 5.76, # 1/2.5" ???
"Canon PowerShot S30" => 7.176, # 1/1.8"
"CASIO COMPUTER CO.,LTD. EX-S500" => 5.76, # 1/2.5"
"CASIO COMPUTER CO.,LTD. EX-Z1000" => 7.716, # 1/1.8"
"CASIO COMPUTER CO.,LTD EX-Z30" => 5.76, # 1/2.5 "
"CASIO COMPUTER CO.,LTD. EX-Z600" => 5.76, # 1/2.5"
"CASIO COMPUTER CO.,LTD. EX-Z60" => 7.176, # 1/1.8"
"CASIO COMPUTER CO.,LTD EX-Z750" => 7.176, # 1/1.8"
"CASIO COMPUTER CO.,LTD. EX-Z850" => 7.176,
"DJI PHANTOM VISION FC200" => 6.17,
"EASTMAN KODAK COMPANY KODAK CX7330 ZOOM DIGITAL CAMERA" => 5.27, # 1/2.7"
"EASTMAN KODAK COMPANY KODAK CX7530 ZOOM DIGITAL CAMERA" => 5.76, # 1/2.5"
"EASTMAN KODAK COMPANY KODAK DX3900 ZOOM DIGITAL CAMERA" => 7.176, # 1/1.8"
"EASTMAN KODAK COMPANY KODAK DX4900 ZOOM DIGITAL CAMERA" => 7.176, # 1/1.8"
"EASTMAN KODAK COMPANY KODAK DX6340 ZOOM DIGITAL CAMERA" => 5.27, # 1/2.7"
"EASTMAN KODAK COMPANY KODAK DX6490 ZOOM DIGITAL CAMERA" => 5.76, # 1/2.5"
"EASTMAN KODAK COMPANY KODAK DX7630 ZOOM DIGITAL CAMERA" => 7.176, # 1/1.8"
"EASTMAN KODAK COMPANY KODAK Z650 ZOOM DIGITAL CAMERA" => 5.76, # 1/2.5"
"EASTMAN KODAK COMPANY KODAK Z700 ZOOM DIGITAL CAMERA" => 5.76, # 1/2.5"
"EASTMAN KODAK COMPANY KODAK Z740 ZOOM DIGITAL CAMERA" => 5.76, # 1/2.5"
"EASTMAN KODAK COMPANY KODAK Z740 ZOOM DIGITAL CAMERA" => 5.76, # 1/2.5" ?
"FUJIFILM FinePix2600Zoom" => 5.27, # 1/2.7"
"FUJIFILM FinePix40i" => 7.600, # 1/1.7"
"FUJIFILM FinePix A310" => 5.27, # 1/2.7"
"FUJIFILM FinePix A330" => 5.27, # 1/2.7"
"FUJIFILM FinePix A600" => 7.600, # 1/1.7"
"FUJIFILM FinePix E500" => 5.76, # 1/2.5"
"FUJIFILM FinePix E510" => 5.76, # 1/2.5"
"FUJIFILM FinePix E550" => 7.600, # 1/1.7"
"FUJIFILM FinePix E900" => 7.78, # 1/1.6"
"FUJIFILM FinePix F10" => 7.600, # 1/1.7"
"FUJIFILM FinePix F30" => 7.600, # 1/1.7"
"FUJIFILM FinePix F450" => 5.76, # 1/2.5"
"FUJIFILM FinePix F601 ZOOM" => 7.600, # 1/1.7"
"FUJIFILM FinePix S3Pro" => 23.0,
"FUJIFILM FinePix S5000" => 5.27, # 1/2.7"
"FUJIFILM FinePix S5200" => 5.76, # 1/2.5"
"FUJIFILM FinePix S5500" => 5.27, # 1/2.7"
"FUJIFILM FinePix S6500fd" => 7.600, # 1/1.7"
"FUJIFILM FinePix S7000" => 7.600, # 1/1.7"
"FUJIFILM FinePix Z2" => 5.76, # 1/2.5"
"Hewlett-Packard hp 635 Digital Camera" => 4.54, # 1/3.2"
"Hewlett-Packard hp PhotoSmart 43x series" => 5.27, # 1/2.7"
"Hewlett-Packard HP PhotoSmart 618 (V1.1)" => 5.27, # 1/2.7"
"Hewlett-Packard HP PhotoSmart C945 (V01.61)" => 7.176, # 1/1.8"
"Hewlett-Packard HP PhotoSmart R707 (V01.00)" => 7.176, # 1/1.8"
"KONICA MILOLTA DYNAX 5D" => 23.5,
"Konica Minolta Camera, Inc. DiMAGE A2" => 8.80, # 2/3"
"KONICA MINOLTA CAMERA, Inc. DiMAGE G400" => 5.76, # 1/2.5"
"Konica Minolta Camera, Inc. DiMAGE Z2" => 5.76, # 1/2.5"
"KONICA MINOLTA DiMAGE A200" => 8.80, # 2/3"
"KONICA MINOLTA DiMAGE X1" => 7.176, # 1/1.8"
"KONICA MINOLTA DYNAX 5D" => 23.5,
"Minolta Co., Ltd. DiMAGE F100" => 7.176, # 1/2.7"
"Minolta Co., Ltd. DiMAGE Xi" => 5.27, # 1/2.7"
"Minolta Co., Ltd. DiMAGE Xt" => 5.27, # 1/2.7"
"Minolta Co., Ltd. DiMAGE Z1" => 5.27, # 1/2.7"
"NIKON CORPORATION NIKON 1 J4" => 13.2, # 1"
"NIKON COOLPIX L3" => 5.76, # 1/2.5"
"NIKON COOLPIX P2" => 7.176, # 1/1.8"
"NIKON COOLPIX S4" => 5.76, # 1/2.5"
"NIKON COOLPIX S7c" => 5.76, # 1/2.5"
"NIKON COOLPIX S8000" => 6.17, # 1/2.3"
"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 D70" => 23.7,
"NIKON CORPORATION NIKON D70s" => 23.7,
"NIKON CORPORATION NIKON D80" => 23.6,
"NIKON CORPORATION NIKON D700" => 36.0,
"NIKON D5100" => 23.6, # APS-C (23.6 x 15.7 mm)
"NIKON E2500" => 5.27, # 1/2.7"
"NIKON E2500" => 5.27, # 1/2.7"
"NIKON E3100" => 5.27, # 1/2.7"
"NIKON E3200" => 5.27,
"NIKON E3700" => 5.27, # 1/2.7"
"NIKON E4200" => 7.176, # 1/1.8"
"NIKON E4300" => 7.18,
"NIKON E4500" => 7.176, # 1/1.8"
"NIKON E4600" => 5.76, # 1/2.5"
"NIKON E5000" => 8.80, # 2/3"
"NIKON E5200" => 7.176, # 1/1.8"
"NIKON E5400" => 7.176, # 1/1.8"
"NIKON E5600" => 5.76, # 1/2.5"
"NIKON E5700" => 8.80, # 2/3"
"NIKON E5900" => 7.176, # 1/1.8"
"NIKON E7600" => 7.176, # 1/1.8"
"NIKON E775" => 5.27, # 1/2.7"
"NIKON E7900" => 7.176, # 1/1.8"
"NIKON E7900" => 7.176, # 1/1.8"
"NIKON E8800" => 8.80, # 2/3"
"NIKON E990" => 7.176, # 1/1.8"
"NIKON E995" => 7.176, # 1/1.8"
"NIKON S1" => 5.76, # 1/2.5"
"Nokia N80" => 5.27, # 1/2.7"
"Nokia N80" => 5.27, # 1/2.7"
"Nokia N93" => 4.536, # 1/3.1"
"Nokia N95" => 5.7, # 1/2.7"
"OLYMPUS CORPORATION C-5000Z" => 7.176, # 1/1.8"
"OLYMPUS CORPORATION C5060WZ" => 7.176, # 1/1.8"
"OLYMPUS CORPORATION C750UZ" => 5.27, # 1/2.7"
"OLYMPUS CORPORATION C765UZ" => 5.76, # 1//2.5"
"OLYMPUS CORPORATION C8080WZ" => 8.80, # 2/3"
"OLYMPUS CORPORATION X250,D560Z,C350Z" => 5.76, # 1/2.5"
"OLYMPUS CORPORATION X-3,C-60Z" => 7.176, # 1.8"
"OLYMPUS CORPORATION X400,D580Z,C460Z" => 5.27, # 1/2.7"
"OLYMPUS IMAGING CORP. E-500" => 17.3, # 4/3?
"OLYMPUS IMAGING CORP. E-510" => 17.3,
"OLYMPUS IMAGING CORP. FE115,X715" => 5.76, # 1/2.5"
"OLYMPUS IMAGING CORP. SP310" => 7.176, # 1/1.8"
"OLYMPUS IMAGING CORP. SP510UZ" => 5.75, # 1/2.5"
"OLYMPUS IMAGING CORP. SP550UZ" => 5.76, # 1/2.5"
"OLYMPUS IMAGING CORP. uD600,S600" => 5.75, # 1/2.5"
"OLYMPUS_IMAGING_CORP. X450,D535Z,C370Z" => 5.27, # 1/2.7"
"OLYMPUS IMAGING CORP. X550,D545Z,C480Z" => 5.76, # 1/2.5"
"OLYMPUS OPTICAL CO.,LTD C2040Z" => 6.40, # 1/2"
"OLYMPUS OPTICAL CO.,LTD C211Z" => 5.27, # 1/2.7"
"OLYMPUS OPTICAL CO.,LTD C2Z,D520Z,C220Z" => 4.54, # 1/3.2"
"OLYMPUS OPTICAL CO.,LTD C3000Z" => 7.176, # 1/1.8"
"OLYMPUS OPTICAL CO.,LTD C300Z,D550Z" => 5.4,
"OLYMPUS OPTICAL CO.,LTD C4100Z,C4000Z" => 7.176, # 1/1.8"
"OLYMPUS OPTICAL CO.,LTD C750UZ" => 5.27, # 1/2.7"
"OLYMPUS OPTICAL CO.,LTD X-2,C-50Z" => 7.176, # 1/1.8"
"OLYMPUS SP550UZ" => 5.76, # 1/2.5"
"OLYMPUS X100,D540Z,C310Z" => 5.27, # 1/2.7"
"Panasonic DMC-FX01" => 5.76, # 1/2.5"
"Panasonic DMC-FX07" => 5.75, # 1/2.5"
"Panasonic DMC-FX9" => 5.76, # 1/2.5"
"Panasonic DMC-FZ20" => 5.760, # 1/2.5"
"Panasonic DMC-FZ2" => 4.54, # 1/3.2"
"Panasonic DMC-FZ30" => 7.176, # 1/1.8"
"Panasonic DMC-FZ50" => 7.176, # 1/1.8"
"Panasonic DMC-FZ5" => 5.760, # 1/2.5"
"Panasonic DMC-FZ7" => 5.76, # 1/2.5"
"Panasonic DMC-LC1" => 8.80, # 2/3"
"Panasonic DMC-LC33" => 5.760, # 1/2.5"
"Panasonic DMC-LX1" => 8.50, # 1/6.5"
"Panasonic DMC-LZ2" => 5.76, # 1/2.5"
"Panasonic DMC-TZ1" => 5.75, # 1/2.5"
"Panasonic DMC-TZ3" => 5.68, # 1/2.35"
"Panasonic DMC-TZ5" => 6.12, # 1/2.33"
"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, # 1/1.8"
"PENTAX Corporation PENTAX Optio 550" => 7.176, # 1/1.8"
"PENTAX Corporation PENTAX Optio E10" => 5.76, # 1/2.5"
"PENTAX Corporation PENTAX Optio S40" => 5.76, # 1/2.5"
"PENTAX Corporation PENTAX Optio S4" => 5.76, # 1/2.5"
"PENTAX Corporation PENTAX Optio S50" => 5.76, # 1/2.5"
"PENTAX Corporation PENTAX Optio S5i" => 5.76, # 1/2.5"
"PENTAX Corporation PENTAX Optio S5z" => 5.76, # 1/2.5"
"PENTAX Corporation PENTAX Optio SV" => 5.76, # 1/2.5"
"PENTAX Corporation PENTAX Optio WP" => 5.75, # 1/2.5"
"RICOH CaplioG3 modelM" => 5.27, # 1/2.7"
"RICOH Caplio GX" => 7.176, # 1/1.8"
"RICOH Caplio R30" => 5.75, # 1/2.5"
"Samsung Digimax 301" => 5.27, # 1/2.7"
"Samsung Techwin <Digimax i5, Samsung #1>" => 5.76, # 1/2.5"
"SAMSUNG TECHWIN Pro 815" => 8.80, # 2/3"
"SONY SLT-A55" => 23.5, # APS-C
"SONY SLT-A57" => 23.5, # APS-C
"SONY SLT-A65" => 23.5, # APS-C
"SONY SLT-A77" => 23.5, # APS-C
"SONY SLT-A77V" => 23.5, # APS-C
"SONY SLT-A77 II" => 23.5, # APS-C
"SONY SLT-A99" => 35.8, # Full-frame
"SONY DSC-F828" => 8.80, # 2/3"
"SONY DSC-H1" => 6.104, # 1/2.4"
"SONY DSC-H2" => 5.744, # 1/2.5"
"SONY DSC-H3" => 5.744, # 1/2.5"
"SONY DSC-H5" => 5.744, # 1/2.5"
"SONY DSC-H7" => 5.744, # 1/2.5"
"SONY DSC-H9" => 5.744, # 1/2.5"
"SONY DSC-N12" => 7.176, # 1/1.8"
"SONY DSC-P100" => 7.176, # 1/1.8"
"SONY DSC-P10" => 7.176, # 1/1.8"
"SONY DSC-P12" => 7.176, # 1/1.8"
"SONY DSC-P150" => 7.176, # 1/1.8"
"SONY DSC-P200" => 7.176, # 1/1.8"
"SONY DSC-P52" => 5.27, # 1/2.7"
"SONY DSC-P72" => 5.27, # 1/2.7"
"SONY DSC-P73" => 5.27,
"SONY DSC-P8" => 5.27, # 1/2.7"
"SONY DSC-R1" => 21.5,
"SONY DSC-S40" => 5.27, # 1/2.7"
"SONY DSC-S600" => 5.760, # 1/2.5"
"SONY DSC-T9" => 7.18,
"SONY DSC-V1" => 7.176, # 1/1.8"
"SONY DSC-W1" => 7.176, # 1/1.8"
"SONY DSC-W30" => 5.760, # 1/2.5"
"SONY DSC-W50" => 5.75, # 1/2.5"
"SONY DSC-W5" => 7.176, # 1/1.8"
"SONY DSC-W7" => 7.176, # 1/1.8"
"SONY DSC-W80" => 5.75, # 1/2.5"
"SONY DSC-HX5V" => 6.104, # 1/2.4"
"SONY NEX-7" => 23.5, # APS-C"
"SONY A7" => 35.9, # Full-frame
"SONY A7R" => 35.9, # Full-frame
);

20
ccd_defs_check.pl 100755
Wyświetl plik

@ -0,0 +1,20 @@
#!/usr/bin/env perl
use strict;
use File::Basename qw( dirname );
use File::Spec;
use JSON;
my $dir = dirname($0);
my $ccd_defs = File::Spec->catfile($dir, 'ccd_defs.json');
open my $fh, $ccd_defs
or die "Unable to open $ccd_defs : $!";
local $/;
my $json = <$fh>; # Slurp
close $fh;
decode_json($json);
print "CCD_DEFS compiles OK\n";
exit 0;

Wyświetl plik

@ -2,12 +2,14 @@
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, age, or religion.
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.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
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/)

22
hooks/pre-commit 100755
Wyświetl plik

@ -0,0 +1,22 @@
#!/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"
# 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)
perl $GIT_ROOT/ccd_defs_check.pl
fi
# non-zero exit fails the commit
exit 0

Plik binarny nie jest wyświetlany.

Przed

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

Po

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

Wyświetl plik

@ -111,6 +111,21 @@ 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 \
> "$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 \
@ -118,6 +133,7 @@ sudo apt-get install --assume-yes --install-recommends \
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 \
@ -125,7 +141,7 @@ sudo apt-get install --assume-yes --install-recommends \
libboost-python-dev \
python-numpy-dev python-pyexiv2 \
> "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1
fi
echo " < done - `date`"

Wyświetl plik

@ -0,0 +1,199 @@
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

@ -0,0 +1,944 @@
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

@ -0,0 +1,26 @@
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

@ -13,6 +13,12 @@ add_definitions(-Wall -Wextra -Wconversion -pedantic)
# 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 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})
@ -25,4 +31,4 @@ aux_source_directory("./src" SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
# Link
target_link_libraries(${PROJECT_NAME} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_SURFACE_LIBRARIES} ${PROJ4_LIBRARY})
target_link_libraries(${PROJECT_NAME} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_SURFACE_LIBRARIES} ${PROJ4_LIBRARY} ${OpenCV_LIBS})

Wyświetl plik

@ -0,0 +1,203 @@
<?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

@ -2,6 +2,10 @@
#include <pcl/io/obj_io.h>
#include <pcl/common/transforms.h>
// OpenCV
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
// Modified PCL
#include "modifiedPclFunctions.hpp"
@ -10,18 +14,42 @@
std::ostream& operator<<(std::ostream &os, const GeorefSystem &geo)
{
return os << geo.system_ << " " << static_cast<int>(geo.falseEasting_) << " " << static_cast<int>(geo.falseNorthing_);
return os << geo.system_ << "\n" << static_cast<int>(geo.eastingOffset_) << " " << static_cast<int>(geo.northingOffset_);
}
GeorefGCP::GeorefGCP()
:x_(0.0), y_(0.0), z_(0.0), use_(false), localX_(0.0), localY_(0.0), localZ_(0.0),cameraIndex_(0), pixelX_(0), pixelY_(0.0), image_("")
{
}
GeorefGCP::~GeorefGCP()
{
}
void GeorefGCP::extractGCP(std::istringstream &gcpStream)
{
gcpStream >> x_ >> y_ >> z_ >> pixelY_ >> pixelX_ >> image_;
}
Vec3 GeorefGCP::getPos()
{
return Vec3(localX_,localY_,localZ_);
}
Vec3 GeorefGCP::getReferencedPos()
{
return Vec3(x_,y_,z_);
}
GeorefCamera::GeorefCamera()
:focalLength_(0.0), k1_(0.0), k2_(0.0), transform_(NULL), position_(NULL)
:focalLength_(0.0), k1_(0.0), k2_(0.0), transform_(NULL), position_(NULL), pose_(NULL)
{
}
GeorefCamera::GeorefCamera(const GeorefCamera &other)
: focalLength_(other.focalLength_), k1_(other.k1_), k2_(other.k2_),
easting_(other.easting_), northing_(other.northing_), altitude_(other.altitude_),
transform_(NULL), position_(NULL)
transform_(NULL), position_(NULL), pose_(NULL)
{
if(NULL != other.transform_)
{
@ -31,6 +59,10 @@ GeorefCamera::GeorefCamera(const GeorefCamera &other)
{
position_ = new Eigen::Vector3f(*other.position_);
}
if(pose_ != other.pose_)
{
pose_ = new Eigen::Affine3f(*other.pose_);
}
}
GeorefCamera::~GeorefCamera()
@ -45,6 +77,11 @@ GeorefCamera::~GeorefCamera()
delete position_;
position_ = NULL;
}
if(pose_ != NULL)
{
delete pose_;
pose_ = NULL;
}
}
void GeorefCamera::extractCamera(std::ifstream &bundleStream)
@ -55,6 +92,7 @@ void GeorefCamera::extractCamera(std::ifstream &bundleStream)
Eigen::Vector3f t;
Eigen::Matrix3f rot;
Eigen::Affine3f transform;
Eigen::Affine3f pose;
bundleStream >> transform(0,0); // Read rotation (0,0) from bundle file
bundleStream >> transform(0,1); // Read rotation (0,1) from bundle file
@ -72,6 +110,47 @@ void GeorefCamera::extractCamera(std::ifstream &bundleStream)
bundleStream >> t(1); // Read translation (1,3) from bundle file
bundleStream >> t(2); // Read translation (2,3) from bundle file
//
pose(0,0) = transform(0,0);
pose(0,1) = transform(0,1);
pose(0,2) = transform(0,2);
pose(1,0) = transform(1,0);
pose(1,1) = transform(1,1);
pose(1,2) = transform(1,2);
pose(2,0) = transform(2,0);
pose(2,1) = transform(2,1);
pose(2,2) = transform(2,2);
pose(0,3) = t(0);
pose(1,3) = t(1);
pose(2,3) = t(2);
pose(3,0) = 0.0;
pose(3,1) = 0.0;
pose(3,2) = 0.0;
pose(3,3) = 1.0;
pose = pose.inverse();
// Column negation
pose(0,2) = -1.0*pose(0,2);
pose(1,2) = -1.0*pose(1,2);
pose(2,2) = -1.0*pose(2,2);
pose(0,1) = -1.0*pose(0,1);
pose(1,1) = -1.0*pose(1,1);
pose(2,1) = -1.0*pose(2,1);
if (pose_ != NULL)
{
delete pose_;
pose_ = NULL;
}
pose_ = new Eigen::Affine3f(pose);
rot = transform.matrix().topLeftCorner<3,3>();
// Calculate translation according to -R't and store in vector.
@ -80,7 +159,8 @@ void GeorefCamera::extractCamera(std::ifstream &bundleStream)
transform(0,3) = t(0);
transform(1,3) = t(1);
transform(2,3) = t(2);
// Set transform and position.
if(NULL != transform_)
{
@ -136,10 +216,9 @@ std::ostream& operator<<(std::ostream &os, const GeorefCamera &cam)
return os;
}
Georef::Georef()
Georef::Georef() : log_(false)
{
log_.setIsPrintingInCout(true);
useGCP_ = false;
bundleFilename_ = "";
coordFilename_ = "";
inputObjFilename_ = "";
@ -155,16 +234,18 @@ int Georef::run(int argc, char *argv[])
try
{
parseArguments(argc, argv);
makeGeoreferencedModel();
createGeoreferencedModel();
}
catch (const GeorefException& 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 Georef:\n";
log_ << e.what() << "\n";
log_.print(logFile_);
@ -172,6 +253,7 @@ int Georef::run(int argc, char *argv[])
}
catch (...)
{
log_.setIsPrintingInCout(true);
log_ << "Unknown error, terminating:\n";
log_.print(logFile_);
return EXIT_FAILURE;
@ -185,6 +267,10 @@ int Georef::run(int argc, char *argv[])
void Georef::parseArguments(int argc, char *argv[])
{
bool outputSpecified = false;
bool imageListSpecified = false;
bool gcpFileSpecified = false;
bool imageLocation = false;
bool bundleResized = false;
logFile_ = std::string(argv[0]) + "_log.txt";
log_ << logFile_ << "\n";
@ -215,6 +301,21 @@ void Georef::parseArguments(int argc, char *argv[])
{
log_.setIsPrintingInCout(true);
}
else if (argument == "-logFile")
{
++argIndex;
if (argIndex >= argc)
{
throw GeorefException("Missing argument for '" + argument + "'.");
}
logFile_ = std::string(argv[argIndex]);
std::ofstream testFile(logFile_.c_str());
if (!testFile.is_open())
{
throw GeorefException("Argument '" + argument + "' has a bad value.");
}
log_ << "Log file path was set to: " << logFile_ << "\n";
}
else if(argument == "-bundleFile" && argIndex < argc)
{
argIndex++;
@ -245,6 +346,55 @@ void Georef::parseArguments(int argc, char *argv[])
inputObjFilename_ = std::string(argv[argIndex]);
log_ << "Reading textured mesh from: " << inputObjFilename_ << "\n";
}
else if(argument == "-gcpFile" && argIndex < argc)
{
argIndex++;
if (argIndex >= argc)
{
throw GeorefException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
gcpFilename_ = std::string(argv[argIndex]);
log_ << "Reading GCPs from: " << gcpFilename_ << "\n";
gcpFileSpecified = true;
}
else if(argument == "-imagesListPath" && argIndex < argc)
{
argIndex++;
if (argIndex >= argc)
{
throw GeorefException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
imagesListPath_ = std::string(argv[argIndex]);
log_ << "Reading image list from: " << imagesListPath_ << "\n";
imageListSpecified = true;
}
else if(argument == "-imagesPath" && argIndex < argc)
{
argIndex++;
if (argIndex >= argc)
{
throw GeorefException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
imagesLocation_ = std::string(argv[argIndex]);
log_ << "Images location is set to: " << imagesLocation_ << "\n";
imageLocation = true;
}
else if(argument == "-bundleResizedTo" && argIndex < argc)
{
argIndex++;
if (argIndex >= argc)
{
throw GeorefException("Argument '" + argument + "' expects 1 more input following it, but no more inputs were provided.");
}
std::stringstream ss(argv[argIndex]);
ss >> bundleResizedTo_;
if (ss.bad())
{
throw GeorefException("Argument '" + argument + "' has a bad value. (wrong type)");
}
log_ << "Bundle resize value is set to: " << bundleResizedTo_ << "\n";
bundleResized = true;
}
else if(argument == "-outputFile" && argIndex < argc)
{
argIndex++;
@ -263,9 +413,19 @@ void Georef::parseArguments(int argc, char *argv[])
}
}
if (imageListSpecified && gcpFileSpecified && imageLocation && bundleResized)
{
useGCP_ = true;
}
else
{
log_ << '\n';
log_ << "Missing input in order to use GCP for georeferencing. Using EXIF data instead.\n";
}
if(!outputSpecified)
{
makeDefaultOutput();
setDefaultOutput();
}
}
@ -277,7 +437,7 @@ void Georef::printHelp()
log_ << "Georef.exe\n\n";
log_ << "Purpose:" << "\n";
log_ << "Create an orthograpical photo from an oriented textured mesh." << "\n";
log_ << "Georeference a textured mesh with the use of ground control points or exif data from the images." << "\n";
log_ << "Usage:" << "\n";
log_ << "The program requires a path to a camera bundle file, a camera georeference coords file, and an input OBJ mesh file. All other input parameters are optional." << "\n\n";
@ -289,12 +449,26 @@ void Georef::printHelp()
log_ << "Parameters are specified as: \"-<argument name> <argument>\", (without <>), and the following parameters are configureable: " << "\n";
log_ << "\"-bundleFile <path>\" (mandatory)" << "\n";
log_ << "\"Input cameras bundle file.\n\n";
log_ << "\"-gcpFile <path>\" (mandatory if using ground control points)\n";
log_ << "Path to the file containing the ground control points used for georeferencing.\n";
log_ << "The file needs to be on the following line format:\n";
log_ << "easting northing height pixelrow pixelcol imagename\n\n";
log_ << "\"-coordFile <path>\" (mandatory)" << "\n";
log_ << "\"-coordFile <path>\" (mandatory if using exif data)" << "\n";
log_ << "\"Input cameras geroreferenced coords file.\n\n";
log_ << "\"-inputFile <path>\" (mandatory)" << "\n";
log_ << "\"Input obj file that must contain a textured mesh.\n\n";
log_ << "\"-imagesListPath <path>\" (mandatory if using ground control points)\n";
log_ << "Path to the list containing the image names used in the bundle.out file.\n\n";
log_ << "\"-imagesPath <path>\" (mandatory if using ground control points)\n";
log_ << "Path to the folder containing full resolution images.\n\n";
log_ << "\"-bundleResizedTo <integer>\" (mandatory if using ground control points)\n";
log_ << "The resized resolution used in bundler.\n\n";
log_ << "\"-outputFile <path>\" (optional, default <inputFile>_geo)" << "\n";
log_ << "\"Output obj file that will contain the georeferenced texture mesh.\n\n";
@ -302,7 +476,7 @@ void Georef::printHelp()
log_.setIsPrintingInCout(printInCoutPop);
}
void Georef::makeDefaultOutput()
void Georef::setDefaultOutput()
{
if(inputObjFilename_.empty())
{
@ -318,20 +492,32 @@ void Georef::makeDefaultOutput()
}
tmp = tmp.substr(0, findPos);
outputObjFilename_ = tmp + "_geo.obj";
log_ << "Writing output to: " << outputObjFilename_ << "\n";
}
void Georef::makeGeoreferencedModel()
void Georef::createGeoreferencedModel()
{
if (useGCP_)
{
createGeoreferencedModelFromGCPData();
}
else
{
createGeoreferencedModelFromExifData();
}
}
void Georef::readCameras()
{
// Read translations from bundle file
std::ifstream bundleStream(bundleFilename_.c_str());
if (!bundleStream.good())
{
throw GeorefException("Failed opening " + bundleFilename_ + " for reading." + '\n');
throw GeorefException("Failed opening bundle file " + bundleFilename_ + " for reading." + '\n');
}
// Read Cameras.
std::string bundleLine;
std::getline(bundleStream, bundleLine); // Read past bundle version comment
@ -342,6 +528,340 @@ void Georef::makeGeoreferencedModel()
cameras_.push_back(GeorefCamera());
cameras_.back().extractCamera(bundleStream);
}
}
void Georef::readGCPs()
{
std::ifstream imageListStream(imagesListPath_.c_str());
if (!imageListStream.good())
{
throw GeorefException("Failed opening " + imagesListPath_ + " for reading.\n");
}
for (size_t i=0; i<cameras_.size(); ++i)
{
std::string imageName;
imageListStream >> imageName;
imageList_.push_back(imageName);
}
// Number of GCPs read
size_t nrGCPs = 0;
std::ifstream gcpStream(gcpFilename_.c_str());
if (!gcpStream.good())
{
throw GeorefException("Failed opening " + gcpFilename_ + " for reading.\n");
}
std::string gcpString;
// Read the first line in the file as the format of the projected coordinates
std::getline(gcpStream, georefSystem_.system_);
log_ << '\n';
log_<< "Reading following GCPs from file:\n";
// Read all GCPs
while(std::getline(gcpStream, gcpString))
{
std::istringstream istr(gcpString);
GeorefGCP gcp;
gcp.extractGCP(istr);
gcps_.push_back(gcp);
++nrGCPs;
log_<<"x_: "<<gcp.x_<<" y_: "<<gcp.y_<<" z_: "<<gcp.z_<<" pixelX_: "<<gcp.pixelX_<<" pixelY_: "<<gcp.pixelY_<<" image: "<<gcp.image_<<"\n";
}
// Check if the GCPs have corresponding images in the bundle files and if they don't, remove them from the GCP-list
for (size_t gcpIndex = 0; gcpIndex<gcps_.size(); ++gcpIndex)
{
bool imageExists = false;
for (size_t cameraIndex = 0; cameraIndex < cameras_.size(); ++cameraIndex)
{
size_t found = imageList_[cameraIndex].find(gcps_[gcpIndex].image_);
if (found != std::string::npos)
{
gcps_[gcpIndex].cameraIndex_ = cameraIndex;
imageExists = true;
}
}
if (!imageExists)
{
log_ <<"Can't find image "<<gcps_[gcpIndex].image_<<". The corresponding GCP will not be used for georeferencing.\n";
gcps_.erase(gcps_.begin() + gcpIndex);
--gcpIndex;
}
}
}
void Georef::calculateGCPOffset()
{
// Offsets
double eastingOffset = 0;
double northingOffset = 0;
// Add all GCPs to weight an offset
for (size_t gcpIndex = 0; gcpIndex<gcps_.size(); ++gcpIndex)
{
eastingOffset += (gcps_[gcpIndex].x_)/static_cast<double>(gcps_.size());
northingOffset += (gcps_[gcpIndex].y_)/static_cast<double>(gcps_.size());
}
georefSystem_.eastingOffset_ = static_cast<int>(std::floor(eastingOffset));
georefSystem_.northingOffset_ = static_cast<int>(std::floor(northingOffset));
log_ << '\n';
log_<<"The calculated easting offset for the georeferenced system: "<<georefSystem_.eastingOffset_<<"\n";
log_<<"The calculated northing offset for the georeferenced system: "<<georefSystem_.northingOffset_<<"\n";
log_ << '\n';
log_ << "Recalculated GCPs with offset:\n";
// Subtract the offset from all GCPs
for (size_t gcpIndex = 0; gcpIndex<gcps_.size(); ++gcpIndex)
{
gcps_[gcpIndex].x_ -= static_cast<double>(georefSystem_.eastingOffset_);
gcps_[gcpIndex].y_ -= static_cast<double>(georefSystem_.northingOffset_);
log_<<"x_: "<<gcps_[gcpIndex].x_<<" y_: "<<gcps_[gcpIndex].y_<<" z_: "<<gcps_[gcpIndex].z_<<"\n";
}
}
pcl::PointXYZ Georef::barycentricCoordinates(pcl::PointXY point, pcl::PointXYZ vert0, pcl::PointXYZ vert1, pcl::PointXYZ vert2, pcl::PointXY p0, pcl::PointXY p1, pcl::PointXY p2)
{
// Shorthands
double x0 = p0.x; double y0 = p0.y;
double x1 = p1.x; double y1 = p1.y;
double x2 = p2.x; double y2 = p2.y;
double x = point.x; double y = point.y;
double q1x = x1 - x0;
double q1y = y1 - y0;
double q2x = x2 - x0;
double q2y = y2 - y0;
double norm = q1x * q2y - q1y * q2x;
double l1 = q2y*(x - x0) - q2x*(y - y0);
l1 /= norm;
double l2 = -q1y*(x - x0) + q1x*(y - y0);
l2 /= norm;
pcl::PointXYZ res;
res.x = (1.0 - l1 - l2)*vert0.x + l1*vert1.x + l2*vert2.x;
res.y = (1.0 - l1 - l2)*vert0.y + l1*vert1.y + l2*vert2.y;
res.z = (1.0 - l1 - l2)*vert0.z + l1*vert1.z + l2*vert2.z;
return res;
}
void Georef::performGeoreferencingWithGCP()
{
log_ << '\n';
log_ << "Reading mesh file " << inputObjFilename_ <<"\n";
log_ << '\n';
pcl::TextureMesh mesh;
if (pcl::io::loadOBJFile(inputObjFilename_, mesh) == -1)
{
throw GeorefException("Error when reading model from:\n" + inputObjFilename_ + "\n");
}
else
{
log_ << "Successfully loaded " << inputObjFilename_ << ".\n";
}
// Convert vertices to pcl::PointXYZ cloud
pcl::PointCloud<pcl::PointXYZ>::Ptr meshCloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::fromPCLPointCloud2 (mesh.cloud, *meshCloud);
// The number of GCP that is usable
int nrGCPUsable = 0;
for (size_t gcpIndex = 0; gcpIndex < gcps_.size(); ++gcpIndex)
{
// Bool to check if the GCP is intersecting any triangle
bool exists = false;
// Translate the GeoreferenceCamera to pcl-format in order to use pcl-functions
pcl::TextureMapping<pcl::PointXYZ>::Camera cam;
cam.focal_length = cameras_[gcps_[gcpIndex].cameraIndex_].focalLength_;
cam.pose = *(cameras_[gcps_[gcpIndex].cameraIndex_].pose_);
cam.texture_file = imagesLocation_ + '/' + gcps_[gcpIndex].image_;
cv::Mat image = cv::imread(cam.texture_file);
cam.height = static_cast<double>(image.rows);
cam.width = static_cast<double>(image.cols);
cam.focal_length *= static_cast<double>(cam.width)/bundleResizedTo_;
// The pixel position for the GCP in pcl-format in order to use pcl-functions
pcl::PointXY gcpPos;
gcpPos.x = static_cast<float>(gcps_[gcpIndex].pixelX_);
gcpPos.y = static_cast<float>(gcps_[gcpIndex].pixelY_);
// Move vertices in mesh into the camera coordinate system
pcl::PointCloud<pcl::PointXYZ>::Ptr cameraCloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::transformPointCloud (*meshCloud, *cameraCloud, cam.pose.inverse());
// The vertex indicies to be used in order to calculate the GCP in the models coordinates
size_t vert0Index = 0; size_t vert1Index = 0; size_t vert2Index = 0;
pcl::PointXY bestPixelPos0; pcl::PointXY bestPixelPos1; pcl::PointXY bestPixelPos2;
// The closest distance of a triangle to the camera
double bestDistance = std::numeric_limits<double>::infinity();
// Loop through all submeshes in model
for (size_t meshIndex = 0; meshIndex < mesh.tex_polygons.size(); ++meshIndex)
{
// Loop through all faces in submesh and check if inside polygon
for (size_t faceIndex = 0; faceIndex < mesh.tex_polygons[meshIndex].size(); ++faceIndex)
{
// Variables for the vertices in face as projections in the camera plane
pcl::PointXY pixelPos0; pcl::PointXY pixelPos1; pcl::PointXY pixelPos2;
if (isFaceProjected(cam,
cameraCloud->points[mesh.tex_polygons[meshIndex][faceIndex].vertices[0]],
cameraCloud->points[mesh.tex_polygons[meshIndex][faceIndex].vertices[1]],
cameraCloud->points[mesh.tex_polygons[meshIndex][faceIndex].vertices[2]],
pixelPos0, pixelPos1, pixelPos2))
{
// If the pixel position of the GCP is inside the current triangle
if (checkPointInsideTriangle(pixelPos0, pixelPos1, pixelPos2, gcpPos))
{
// Extract distances for all vertices for face to camera
double d0 = cameraCloud->points[mesh.tex_polygons[meshIndex][faceIndex].vertices[0]].z;
double d1 = cameraCloud->points[mesh.tex_polygons[meshIndex][faceIndex].vertices[1]].z;
double d2 = cameraCloud->points[mesh.tex_polygons[meshIndex][faceIndex].vertices[2]].z;
// Calculate largest distance and store in distance variable
double distance = std::max(d0, std::max(d1,d2));
// If the triangle is closer to the camera use this triangle
if (distance < bestDistance)
{
// Update variables for the closest polygon
bestDistance = distance;
vert0Index = mesh.tex_polygons[meshIndex][faceIndex].vertices[0];
vert1Index = mesh.tex_polygons[meshIndex][faceIndex].vertices[1];
vert2Index = mesh.tex_polygons[meshIndex][faceIndex].vertices[2];
bestPixelPos0 = pixelPos0;
bestPixelPos1 = pixelPos1;
bestPixelPos2 = pixelPos2;
exists = true;
++nrGCPUsable;
}
}
}
}
}
if(exists)
{
// Shorthands for the vertices
pcl::PointXYZ v0 = meshCloud->points[vert0Index];
pcl::PointXYZ v1 = meshCloud->points[vert1Index];
pcl::PointXYZ v2 = meshCloud->points[vert2Index];
// Use barycentric coordinates to calculate position for the polygon intersection
pcl::PointXYZ gcpLocal = barycentricCoordinates(gcpPos, v0, v1, v2, bestPixelPos0, bestPixelPos1, bestPixelPos2);
log_ << "Position in model for gcp " << gcpIndex + 1<< ": x=" <<gcpLocal.x<<" y="<<gcpLocal.y<<" z="<<gcpLocal.z<<"\n";
gcps_[gcpIndex].localX_ = gcpLocal.x;
gcps_[gcpIndex].localY_ = gcpLocal.y;
gcps_[gcpIndex].localZ_ = gcpLocal.z;
gcps_[gcpIndex].use_ = true;
}
}
if (nrGCPUsable < 3)
{
throw GeorefException("Less than 3 GCPs have correspondences in the generated model.");
}
size_t gcp0; size_t gcp1; size_t gcp2;
log_ << '\n';
log_ << "Choosing optimal gcp triplet...\n";
chooseBestGCPTriplet(gcp0, gcp1, gcp2);
log_ << "Optimal gcp triplet chosen: ";
log_ << gcp0 << ", " << gcp1 << ", " << gcp2 << '\n';
log_ << '\n';
FindTransform transFinal;
transFinal.findTransform(gcps_[gcp0].getPos(), gcps_[gcp1].getPos(), gcps_[gcp2].getPos(),
gcps_[gcp0].getReferencedPos(), gcps_[gcp1].getReferencedPos(), gcps_[gcp2].getReferencedPos());
log_ << "Final transform:\n";
log_ << transFinal.transform_ << '\n';
// The tranform used to transform model into the georeferenced system.
Eigen::Transform<float, 3, Eigen::Affine> transform;
transform(0, 0) = static_cast<float>(transFinal.transform_.r1c1_);
transform(1, 0) = static_cast<float>(transFinal.transform_.r2c1_);
transform(2, 0) = static_cast<float>(transFinal.transform_.r3c1_);
transform(3, 0) = static_cast<float>(transFinal.transform_.r4c1_);
transform(0, 1) = static_cast<float>(transFinal.transform_.r1c2_);
transform(1, 1) = static_cast<float>(transFinal.transform_.r2c2_);
transform(2, 1) = static_cast<float>(transFinal.transform_.r3c2_);
transform(3, 1) = static_cast<float>(transFinal.transform_.r4c2_);
transform(0, 2) = static_cast<float>(transFinal.transform_.r1c3_);
transform(1, 2) = static_cast<float>(transFinal.transform_.r2c3_);
transform(2, 2) = static_cast<float>(transFinal.transform_.r3c3_);
transform(3, 2) = static_cast<float>(transFinal.transform_.r4c3_);
transform(0, 3) = static_cast<float>(transFinal.transform_.r1c4_);
transform(1, 3) = static_cast<float>(transFinal.transform_.r2c4_);
transform(2, 3) = static_cast<float>(transFinal.transform_.r3c4_);
transform(3, 3) = static_cast<float>(transFinal.transform_.r4c4_);
log_ << '\n';
log_ << "Applying transform to mesh...\n";
// Move the mesh into position.
pcl::transformPointCloud(*meshCloud, *meshCloud, transform);
log_ << ".. mesh transformed.\n";
// Update the mesh.
pcl::toPCLPointCloud2 (*meshCloud, mesh.cloud);
// Iterate over each part of the mesh (one per material), to make texture file paths relative the .mtl file.
for(size_t t = 0; t < mesh.tex_materials.size(); ++t)
{
// The material of the current submesh.
pcl::TexMaterial& material = mesh.tex_materials[t];
size_t find = material.tex_file.find_last_of("/\\");
if(std::string::npos != find)
{
material.tex_file = material.tex_file.substr(find + 1);
}
}
log_ << '\n';
if (saveOBJFile(outputObjFilename_, mesh, 8) == -1)
{
throw GeorefException("Error when saving model:\n" + outputObjFilename_ + "\n");
}
else
{
log_ << "Successfully saved model.\n";
}
printGeorefSystem();
}
void Georef::createGeoreferencedModelFromGCPData()
{
readCameras();
readGCPs();
calculateGCPOffset();
performGeoreferencingWithGCP();
}
void Georef::createGeoreferencedModelFromExifData()
{
readCameras();
// Read coords from coord file generated by extract_utm tool
std::ifstream coordStream(coordFilename_.c_str());
@ -353,10 +873,10 @@ void Georef::makeGeoreferencedModel()
std::string coordString;
std::getline(coordStream, georefSystem_.system_); // System
{
std::getline(coordStream, coordString); // Flase easting & northing.
std::getline(coordStream, coordString);
std::stringstream ss(coordString);
ss >> georefSystem_.falseEasting_ >> georefSystem_.falseNorthing_;
ss >> georefSystem_.eastingOffset_ >> georefSystem_.northingOffset_;
}
log_ << '\n';
@ -371,7 +891,7 @@ void Georef::makeGeoreferencedModel()
{
if(nGeorefCameras >= cameras_.size())
{
throw GeorefException("Error to many cameras in \'" + coordFilename_ + "\' coord file.\n");
throw GeorefException("Error, to many cameras in \'" + coordFilename_ + "\' coord file.\n");
}
std::istringstream istr(coordString);
@ -404,25 +924,17 @@ void Georef::makeGeoreferencedModel()
// The tranform used to move the chosen area into the ortho photo.
Eigen::Transform<float, 3, Eigen::Affine> transform;
transform(0, 0) = static_cast<float>(transFinal.transform_.r1c1_);
transform(1, 0) = static_cast<float>(transFinal.transform_.r2c1_);
transform(2, 0) = static_cast<float>(transFinal.transform_.r3c1_);
transform(3, 0) = static_cast<float>(transFinal.transform_.r4c1_);
transform(0, 0) = static_cast<float>(transFinal.transform_.r1c1_); transform(1, 0) = static_cast<float>(transFinal.transform_.r2c1_);
transform(2, 0) = static_cast<float>(transFinal.transform_.r3c1_); transform(3, 0) = static_cast<float>(transFinal.transform_.r4c1_);
transform(0, 1) = static_cast<float>(transFinal.transform_.r1c2_);
transform(1, 1) = static_cast<float>(transFinal.transform_.r2c2_);
transform(2, 1) = static_cast<float>(transFinal.transform_.r3c2_);
transform(3, 1) = static_cast<float>(transFinal.transform_.r4c2_);
transform(0, 1) = static_cast<float>(transFinal.transform_.r1c2_); transform(1, 1) = static_cast<float>(transFinal.transform_.r2c2_);
transform(2, 1) = static_cast<float>(transFinal.transform_.r3c2_); transform(3, 1) = static_cast<float>(transFinal.transform_.r4c2_);
transform(0, 2) = static_cast<float>(transFinal.transform_.r1c3_);
transform(1, 2) = static_cast<float>(transFinal.transform_.r2c3_);
transform(2, 2) = static_cast<float>(transFinal.transform_.r3c3_);
transform(3, 2) = static_cast<float>(transFinal.transform_.r4c3_);
transform(0, 2) = static_cast<float>(transFinal.transform_.r1c3_); transform(1, 2) = static_cast<float>(transFinal.transform_.r2c3_);
transform(2, 2) = static_cast<float>(transFinal.transform_.r3c3_); transform(3, 2) = static_cast<float>(transFinal.transform_.r4c3_);
transform(0, 3) = static_cast<float>(transFinal.transform_.r1c4_);
transform(1, 3) = static_cast<float>(transFinal.transform_.r2c4_);
transform(2, 3) = static_cast<float>(transFinal.transform_.r3c4_);
transform(3, 3) = static_cast<float>(transFinal.transform_.r4c4_);
transform(0, 3) = static_cast<float>(transFinal.transform_.r1c4_); transform(1, 3) = static_cast<float>(transFinal.transform_.r2c4_);
transform(2, 3) = static_cast<float>(transFinal.transform_.r3c4_); transform(3, 3) = static_cast<float>(transFinal.transform_.r4c4_);
log_ << '\n';
log_ << "Reading mesh file...\n";
@ -466,6 +978,50 @@ void Georef::makeGeoreferencedModel()
printGeorefSystem();
}
void Georef::chooseBestGCPTriplet(size_t &gcp0, size_t &gcp1, size_t &gcp2)
{
double minTotError = std::numeric_limits<double>::infinity();
for(size_t t = 0; t < gcps_.size(); ++t)
{
if (gcps_[t].use_)
{
for(size_t s = t; s < gcps_.size(); ++s)
{
if (gcps_[s].use_)
{
for(size_t p = s; p < gcps_.size(); ++p)
{
if (gcps_[p].use_)
{
FindTransform trans;
trans.findTransform(gcps_[t].getPos(), gcps_[s].getPos(), gcps_[p].getPos(),
gcps_[t].getReferencedPos(), gcps_[s].getReferencedPos(), gcps_[p].getReferencedPos());
// The total error for the curren camera triplet.
double totError = 0.0;
for(size_t r = 0; r < gcps_.size(); ++r)
{
totError += trans.error(gcps_[r].getPos(), gcps_[r].getReferencedPos());
}
if(minTotError > totError)
{
minTotError = totError;
gcp0 = t;
gcp1 = s;
gcp2 = p;
}
}
}
}
}
}
}
log_ << "Mean georeference error " << minTotError / static_cast<double>(cameras_.size()) << '\n';
}
void Georef::chooseBestCameraTriplet(size_t &cam0, size_t &cam1, size_t &cam2)
{
double minTotError = std::numeric_limits<double>::infinity();
@ -528,3 +1084,4 @@ void Georef::printGeorefSystem()
log_ << "... georeference system saved.\n";
}

Wyświetl plik

@ -21,12 +21,50 @@
struct GeorefSystem
{
std::string system_; /**< The name of the system. **/
double falseEasting_; /**< The false easting of the cameras. **/
double falseNorthing_; /**< The false northing of the cameras. **/
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.
*/
@ -47,7 +85,7 @@ struct GeorefCamera
void extractCameraGeoref(std::istringstream &coordStream);
/*!
* \brief getReferencedPos Get the local position of the camera.
* \brief getPos Get the local position of the camera.
*/
Vec3 getPos();
@ -66,12 +104,13 @@ struct GeorefCamera
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 OdmOrthoPhoto class is used to transform a mesh into a georeferenced system.
* \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.
@ -90,8 +129,8 @@ private:
/*!
* \brief parseArguments Parses command line arguments.
* \param argc Application argument count.
* \param argv Argument values.
* \param argc Application argument count.
* \param argv Argument values.
*/
void parseArguments(int argc, char* argv[]);
@ -101,17 +140,57 @@ private:
void printHelp();
/*!
* \brief makeDefaultOutput Setup the output file name given the input file name.
* \brief setDefaultOutput Setup the output file name given the input file name.
*/
void makeDefaultOutput();
void setDefaultOutput();
/*!
* \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 makeGeoreferencedModel Makes the input file georeferenced and saves it to the output file.
* \brief chooseBestGCPTriplet Chooses the best triplet of GCPs to use when making the model georeferenced.
*/
void makeGeoreferencedModel();
void chooseBestGCPTriplet(size_t &gcp0, size_t &gcp1, size_t &gcp2);
/*!
* \brief chooseBestCameraTriplet Chooses the best triplet of cameras to use when makin gthe model georeferenced.
* \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);
@ -125,10 +204,18 @@ private:
std::string bundleFilename_; /**< The path to the cameras bundle file. **/
std::string coordFilename_; /**< The path to the cameras georeference 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. **/
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. **/
};

Wyświetl plik

@ -281,7 +281,7 @@ bool getPixelCoordinates(const pcl::PointXYZ &pt, const pcl::TextureMapping<pcl:
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))
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
}

0
odm_orthophoto/CMakeLists.txt 100644 → 100755
Wyświetl plik

Wyświetl plik

@ -0,0 +1,203 @@
<?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>

2
odm_orthophoto/src/Logger.cpp 100644 → 100755
Wyświetl plik

@ -27,5 +27,3 @@ void Logger::setIsPrintingInCout(bool isPrintingInCout)
{
isPrintingInCout_ = isPrintingInCout;
}

0
odm_orthophoto/src/Logger.hpp 100644 → 100755
Wyświetl plik

686
odm_orthophoto/src/OdmOrthoPhoto.cpp 100644 → 100755
Wyświetl plik

@ -1,20 +1,57 @@
// C++
#include <math.h>
#include <sstream>
// 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";
resolution_ = 0.0f;
boundryPoint1_[0] = 0.0f; boundryPoint1_[1] = 0.0f;
boundryPoint2_[0] = 0.0f; boundryPoint2_[1] = 0.0f;
boundryPoint3_[0] = 0.0f; boundryPoint3_[1] = 0.0f;
boundryPoint4_[0] = 0.0f; boundryPoint4_[1] = 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()
@ -30,12 +67,14 @@ int OdmOrthoPhoto::run(int argc, char *argv[])
}
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_);
@ -43,6 +82,7 @@ int OdmOrthoPhoto::run(int argc, char *argv[])
}
catch (...)
{
log_.setIsPrintingInCout(true);
log_ << "Unknown error, terminating:\n";
log_.print(logFile_);
return EXIT_FAILURE;
@ -56,7 +96,7 @@ int OdmOrthoPhoto::run(int argc, char *argv[])
void OdmOrthoPhoto::parseArguments(int argc, char *argv[])
{
logFile_ = std::string(argv[0]) + "_log.txt";
log_ << logFile_ << "\n";
log_ << logFile_ << "\n\n";
// If no arguments were passed, print help.
if (argc == 1)
@ -91,28 +131,75 @@ void OdmOrthoPhoto::parseArguments(int argc, char *argv[])
ss >> resolution_;
log_ << "Resolution count was set to: " << resolution_ << "pixels/meter\n";
}
else if(argument == "-boundry")
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 >> boundryPoint1_[0] >> boundryPoint1_[1] >> boundryPoint2_[0] >> boundryPoint2_[1] >> boundryPoint3_[0] >> boundryPoint3_[1] >> boundryPoint4_[0] >> boundryPoint4_[1];
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_;
log_ << "Boundry point 1 was set to: " << boundryPoint1_[0] << ", " << boundryPoint1_[1] << '\n';
log_ << "Boundry point 2 was set to: " << boundryPoint2_[0] << ", " << boundryPoint2_[1] << '\n';
log_ << "Boundry point 3 was set to: " << boundryPoint3_[0] << ", " << boundryPoint3_[1] << '\n';
log_ << "Boundry point 4 was set to: " << boundryPoint4_[0] << ", " << boundryPoint4_[1] << '\n';
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 == "-inputFile" && argIndex < argc)
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)
@ -122,7 +209,17 @@ void OdmOrthoPhoto::parseArguments(int argc, char *argv[])
inputFile_ = std::string(argv[argIndex]);
log_ << "Reading textured mesh from: " << inputFile_ << "\n";
}
else if(argument == "-outputFile" && argIndex < argc)
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)
@ -138,37 +235,44 @@ void OdmOrthoPhoto::parseArguments(int argc, char *argv[])
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";
log_ << "Usage:" << "\n";
log_ << "The program requires a path to an input OBJ mesh file, resolution and boundry points to define the area. All other input parameters are optional." << "\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_ << "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_ << "\"-outputFile <path>\" (optional, default: ortho.jpg)" << "\n";
log_ << "\"-inputGeoRefFile <path>\" (optional, if specified boundary points are assumed to be givan 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_ << "\"-resolution <pixels/m>\" (mandatory)" << "\n";
log_ << "\"-resolution <pixels/m>\" (mandatory)\n";
log_ << "\"The number of pixels used per meter.\n\n";
log_ << "\"-boundry <Point1x Point1y Point2x Point2y Point3x Point3y Point4x Point4y >\" (mandatory)" << "\n";
log_ << "\"Describes the area which should be covered in the ortho photo. The area will be a bounding box containing all four points.\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);
}
@ -177,19 +281,37 @@ void OdmOrthoPhoto::createOrthoPhoto()
if(inputFile_.empty())
{
throw OdmOrthoPhotoException("Failed to create ortho photo, no texture mesh given.");
return;
}
log_ << '\n';
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";
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.
@ -198,26 +320,34 @@ void OdmOrthoPhoto::createOrthoPhoto()
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.");
}
}
// The minimum and maximum boundry values.
if(!boundaryDefined_)
{
// Determine boundary from model.
adjustBoundsForEntireModel(mesh);
}
// The minimum and maximum boundary values.
float xMax, xMin, yMax, yMin;
xMin = std::min(std::min(boundryPoint1_[0], boundryPoint2_[0]), std::min(boundryPoint3_[0], boundryPoint4_[0]));
xMax = std::max(std::max(boundryPoint1_[0], boundryPoint2_[0]), std::max(boundryPoint3_[0], boundryPoint4_[0]));
yMin = std::min(std::min(boundryPoint1_[1], boundryPoint2_[1]), std::min(boundryPoint3_[1], boundryPoint4_[1]));
yMax = std::max(std::max(boundryPoint1_[1], boundryPoint2_[1]), std::max(boundryPoint3_[1], boundryPoint4_[1]));
log_ << "Ortho photo area x : " << xMin << " -> " << xMax << '\n';
log_ << "Ortho photo area y : " << yMin << " -> " << yMax << '\n';
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_*xDiff));
int colRes = static_cast<int>(std::ceil(resolution_*yDiff));
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)
@ -232,40 +362,39 @@ void OdmOrthoPhoto::createOrthoPhoto()
}
log_ << "New ortho photo resolution, width x height : " << colRes << "x" << rowRes << '\n';
}
// Init ortho photo
photo_ = cv::Mat::zeros(rowRes, colRes, CV_8UC3) + cv::Scalar(255, 255, 255);
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";
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_ << '\n';
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)
{
@ -281,16 +410,16 @@ void OdmOrthoPhoto::createOrthoPhoto()
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);
}
@ -298,38 +427,163 @@ void OdmOrthoPhoto::createOrthoPhoto()
log_ << "Material " << t << " rendered.\n";
}
log_ << "...ortho photo rendered\n";
log_ << '\n';
log_ << "Writing ortho photo to " << outputFile_ << "\n";
cv::imwrite(outputFile_, photo_);
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 false easting and northing
int falseEasting, falseNorthing;
// Parse file
std::getline(geoRefStream, system);
if(!(geoRefStream >> falseEasting))
{
throw OdmOrthoPhotoException("Could not extract geographical reference system from \n" + inputGeoRefFile_ + "\nCould not extract false easting.");
}
if(!(geoRefStream >> falseNorthing))
{
throw OdmOrthoPhotoException("Could not extract geographical reference system from \n" + inputGeoRefFile_ + "\nCould not extract false northing.");
}
log_ << "Georeference system\n";
log_ << system << "\n";
log_ << "False easting " << falseEasting << "\n";
log_ << "False northing " << falseNorthing << "\n";
// Adjust boundary points.
boundaryPoint1_[0] = static_cast<float>(worldPoint1_.eastInteger_ - falseEasting) + worldPoint1_.eastFractional_;
boundaryPoint1_[1] = static_cast<float>(worldPoint1_.northInteger_ - falseNorthing) + worldPoint1_.northFractional_;
boundaryPoint2_[0] = static_cast<float>(worldPoint2_.eastInteger_ - falseEasting) + worldPoint2_.eastFractional_;
boundaryPoint2_[1] = static_cast<float>(worldPoint2_.northInteger_ - falseNorthing) + worldPoint2_.northFractional_;
boundaryPoint3_[0] = static_cast<float>(worldPoint3_.eastInteger_ - falseEasting) + worldPoint3_.eastFractional_;
boundaryPoint3_[1] = static_cast<float>(worldPoint3_.northInteger_ - falseNorthing) + worldPoint3_.northFractional_;
boundaryPoint4_[0] = static_cast<float>(worldPoint4_.eastInteger_ - falseEasting) + worldPoint4_.eastFractional_;
boundaryPoint4_[1] = static_cast<float>(worldPoint4_.northInteger_ - falseNorthing) + 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_;
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_;
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_;
transform(1, 3) = -yMin*resolution_;
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;
}
@ -339,37 +593,37 @@ void OdmOrthoPhoto::drawTexturedTriangle(const cv::Mat &texture, const pcl::Vert
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.
// 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];
@ -382,36 +636,36 @@ void OdmOrthoPhoto::drawTexturedTriangle(const cv::Mat &texture, const pcl::Vert
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; // Outside to the right.
return; // Completly outside to the right.
}
int xMax = static_cast<int>(std::max(std::max(v1x, v2x), v3x));
if(xMax < 0)
{
return; // Outside to the left.
return; // Completly outside to the left.
}
int yMin = static_cast<int>(std::min(std::min(v1y, v2y), v3y));
if(yMin > photo_.rows)
{
return; // Outside to the top.
return; // Completly outside to the top.
}
int yMax = static_cast<int>(std::max(std::max(v1y, v2y), v3y));
if(yMax < 0)
{
return; // Outside to the bottom.
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)
{
@ -461,136 +715,202 @@ void OdmOrthoPhoto::drawTexturedTriangle(const cv::Mat &texture, const pcl::Vert
}
else
{
// 3 -> 2 -> 1
// 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);
// Describes the offset from the pixel coordiante to the triangle point.
float rRoundOff = topR - std::floor(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 = static_cast<int>(std::floor(topR))+1; rq <= static_cast<int>(std::floor(midR)); ++rq)
for(int rq = rqStart; rq < rqEnd; ++rq)
{
// Set the current column positions.
ctm = topC + ctmdr*(static_cast<float>(rq)-topR);
ctb = topC + ctbdr*(static_cast<float>(rq)-topR);
// Describes the offset from the pixel coordiante to the triangle point.
float cRoundOff = std::min(ctm, ctb) - std::floor(std::min(ctm, ctb));
for(int cq = static_cast<int>(std::floor(std::min(ctm, ctb))); cq < static_cast<int>(std::floor(std::max(ctm, ctb))); ++cq)
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)
{
if(0 <= rq && rq < photo_.rows && 0 <= cq && cq < photo_.cols)
// 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)
{
// Get barycentric coordinates for the current point.
getBarycentricCoordiantes(v1, v2, v3, static_cast<float>(cq)+cRoundOff, static_cast<float>(rq)+rRoundOff, l1, l2, l3);
// 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 last, 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;
// Nearest neighbour texture interpolation.
int uq = static_cast<int>(u*fCols);
int vq = static_cast<int>((1.0f-v)*fRows);
photo_.at<cv::Vec3b>(rq,cq) = texture.at<cv::Vec3b>(vq, uq);
// Update depth buffer.
depth_.at<float>(rq, cq) = z;
//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;
// Describes the offset from the pixel coordiante to the triangle point.
float rRoundOff = midR - std::floor(midR);
// 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 = static_cast<int>(std::floor(midR))+1; rq <= static_cast<int>(std::floor(botR)); ++rq)
for(int rq = rqStart; rq < rqEnd; ++rq)
{
// Set the current column positions.
ctb = topC + ctbdr*(static_cast<float>(rq)-topR);
cmb = midC + cmbdr*(static_cast<float>(rq)-midR);
// Describes the offset from the pixel coordiante to the triangle point.
float cRoundOff = std::min(cmb, ctb) - std::floor(std::min(cmb, ctb));
for(int cq = static_cast<int>(std::floor(std::min(cmb, ctb))); cq < static_cast<int>(std::floor(std::max(cmb, ctb))); ++cq)
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)
{
if(0 <= rq && rq < photo_.rows && 0 <= cq && cq < photo_.cols)
// 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)
{
// Get barycentric coordinates for the current point.
getBarycentricCoordiantes(v1, v2, v3, static_cast<float>(cq)+cRoundOff, static_cast<float>(rq)+rRoundOff, l1, l2, l3);
// 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 last, 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;
// Nearest neighbour texture interpolation.
int uq = static_cast<int>(u*fCols);
int vq = static_cast<int>((1.0f-v)*fRows);
photo_.at<cv::Vec3b>(rq,cq) = texture.at<cv::Vec3b>(vq, uq);
// Update depth buffer.
depth_.at<float>(rq, cq) = z;
//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::Vec3b>(row,col) = cv::Vec3b(static_cast<unsigned char>(b), static_cast<unsigned char>(g), static_cast<unsigned char>(r));
}
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.
@ -613,13 +933,13 @@ void OdmOrthoPhoto::getBarycentricCoordiantes(pcl::PointXYZ v1, pcl::PointXYZ v2
}
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);
}

Wyświetl plik

@ -2,6 +2,8 @@
// C++
#include <limits.h>
#include <istream>
#include <ostream>
// PCL
#include <pcl/io/obj_io.h>
@ -21,6 +23,36 @@
// 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.
@ -47,6 +79,7 @@ private:
/*!
* \brief parseArguments Parses command line arguments.
*
* \param argc Application argument count.
* \param argv Argument values.
*/
@ -62,6 +95,23 @@ private:
*/
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.
*/
@ -69,6 +119,9 @@ private:
/*!
* \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.
@ -77,8 +130,20 @@ private:
*/
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.
@ -92,6 +157,7 @@ private:
/*!
* \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.
@ -100,26 +166,36 @@ private:
/*!
* \brief Check if the model is suitable for ortho photo generation.
* \param mesh The
*
* \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 logFile_; /**< Path to the log file. */
float resolution_; /**< The number of pixels per meter in the ortho photo. */
Eigen::Vector2f boundryPoint1_; /**< The first boundry point for the ortho photo. */
Eigen::Vector2f boundryPoint2_; /**< The second boundry point for the ortho photo. */
Eigen::Vector2f boundryPoint3_; /**< The third boundry point for the ortho photo. */
Eigen::Vector2f boundryPoint4_; /**< The fourth boundry point for 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. **/
};

0
odm_orthophoto/src/main.cpp 100644 → 100755
Wyświetl plik

Wyświetl plik

@ -342,13 +342,30 @@ void OdmTexturing::loadCameras()
cam.pose = transform;
std::getline(imageListFile, dummyLine);
cam.texture_file = imagesPath_ + dummyLine.substr(2,dummyLine.length());
size_t firstWhitespace = dummyLine.find_first_of(" ");
if (firstWhitespace != std::string::npos)
{
cam.texture_file = imagesPath_ + "/" + dummyLine.substr(2,firstWhitespace-2);
}
else
{
cam.texture_file = imagesPath_ + "/" + dummyLine.substr(2);
}
// Read image to get full resolution size
cv::Mat image = cv::imread(cam.texture_file);
if (image.empty())
{
throw OdmTexturingException("Failed to read image:\n'" + cam.texture_file + "'\n");
}
double imageWidth = static_cast<double>(image.cols);
double textureWithWidth = static_cast<double>(textureWithSize_);
// Calculate scale factor to texture with textureWithSize
double factor = textureWithSize_/static_cast<double>(image.cols);
double factor = textureWithWidth/imageWidth;
if (factor > 1.0f)
{
factor = 1.0f;
@ -380,6 +397,11 @@ void OdmTexturing::triangleToImageAssignment()
// Vector containing information if the face has been given an optimal camera or not
std::vector<bool> hasOptimalCamera = std::vector<bool>(mesh_->tex_polygons[0].size());
//Vector containing minimal distances to optimal camera
std::vector<double> tTIA_distances(mesh_->tex_polygons[0].size(),DBL_MAX);
//Vector containing minimal angles of face to cameraplane normals
std::vector<double> tTIA_angles(mesh_->tex_polygons[0].size(),DBL_MAX);
// Set default value that no face has an optimal camera
for (size_t faceIndex = 0; faceIndex < hasOptimalCamera.size(); ++faceIndex)
{
@ -467,7 +489,8 @@ void OdmTexturing::triangleToImageAssignment()
}
std::vector<double> local_tTIA_distances(mesh_->tex_polygons[0].size(),DBL_MAX);
std::vector<double> local_tTIA_angles(mesh_->tex_polygons[0].size(),DBL_MAX);
// If any faces are visible in the current camera perform occlusion culling
if (countInsideFrustum > 0)
{
@ -501,16 +524,45 @@ void OdmTexturing::triangleToImageAssignment()
// Perform radius search in the acceleration structure
int radiusSearch = kdTree.radiusSearch(center, radius, neighbors, neighborsSquaredDistance);
// Extract distances for all vertices for face to camera
double d0 = cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[0]].z;
double d1 = cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[1]].z;
double d2 = cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[2]].z;
// Calculate largest distance and store in distance variable
double distance = std::max(d0, std::max(d1,d2));
//Get points
pcl::PointXYZ p0=cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[0]];
pcl::PointXYZ p1=cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[1]];
pcl::PointXYZ p2=cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[2]];
//Calculate face normal
pcl::PointXYZ diff0;
pcl::PointXYZ diff1;
diff0.x=p1.x-p0.x;
diff0.y=p1.y-p0.y;
diff0.z=p1.z-p0.z;
diff1.x=p2.x-p0.x;
diff1.y=p2.y-p0.y;
diff1.z=p2.z-p0.z;
pcl::PointXYZ normal;
normal.x=diff0.y*diff1.z-diff0.z*diff1.y;
normal.y=-(diff0.x*diff1.z-diff0.z*diff1.x);
normal.z=diff0.x*diff1.y-diff0.y*diff1.x;
double norm=sqrt(normal.x*normal.x+normal.y*normal.y+normal.z*normal.z);
//Angle of face to camera
double cos=-normal.z/norm;
//Save distance of faceIndex to current camera
local_tTIA_distances[faceIndex]=distance;
//Save angle of faceIndex to current camera
local_tTIA_angles[faceIndex]=sqrt(1.0-cos*cos);
// If other projections are found inside the radius
if (radiusSearch > 0)
{
// Extract distances for all vertices for face to camera
double d0 = cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[0]].z;
double d1 = cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[1]].z;
double d2 = cameraCloud->points[mesh_->tex_polygons[0][faceIndex].vertices[2]].z;
// Calculate largest distance and store in distance variable
double distance = std::max(d0, std::max(d1,d2));
// Compare distance to all neighbors inside radius
for (size_t i = 0; i < neighbors.size(); ++i)
@ -542,9 +594,14 @@ void OdmTexturing::triangleToImageAssignment()
{
if (visibility[faceIndex])
{
hasOptimalCamera[faceIndex] = true;
tTIA_[faceIndex] = cameraIndex;
++count;
if(local_tTIA_distances[faceIndex]<tTIA_distances[faceIndex]&&local_tTIA_angles[faceIndex]<tTIA_angles[faceIndex])
{
tTIA_angles[faceIndex]=local_tTIA_angles[faceIndex];
tTIA_distances[faceIndex]=local_tTIA_distances[faceIndex];
hasOptimalCamera[faceIndex] = true;
tTIA_[faceIndex] = cameraIndex;
++count;
}
}
}

351
run.pl
Wyświetl plik

@ -13,6 +13,7 @@ use Data::Dumper;
use Time::localtime;
use Switch;
use POSIX qw(strftime);
use JSON;
## the defs
@ -27,7 +28,18 @@ if(!File::Spec->file_name_is_absolute($BIN_PATH_REL)){
$BIN_PATH_ABS = File::Spec->rel2abs($BIN_PATH_REL);
}
require "$BIN_PATH_ABS/ccd_defs.pl";
sub getCcdWidths{
local $/;
my $ccdPath = "$BIN_PATH_ABS/ccd_defs.json";
open( my $fh, '<', $ccdPath);
my $ccdWidths = decode_json(<$fh>);
close($fh);
undef $/;
return $ccdWidths;
}
$ccdWidths = getCcdWidths();
$BIN_PATH = $BIN_PATH_ABS."/bin";
$OPENSFM_PATH = $BIN_PATH_ABS."/src/OpenSfM";
@ -54,7 +66,7 @@ $jobOptions{srcDir} = "$CURRENT_DIR";
sub run {
system($_[0]);
if($? != 0){
die "\n\nquitting cause: \n\t$_[0]\nreturned with code ".$?."\n";
}
@ -68,16 +80,16 @@ sub parseArgs {
## defaults
$args{"--match-size"} = "200";
$args{"--resize-to"} = "1200";
$args{"--resize-to"} = "2400";
$args{"--start-with"} = "resize";
$args{"--end-with"} = "odm_texturing";
$args{"--cmvs-maxImages"} = 100;
$args{"--end-with"} = "odm_orthophoto";
$args{"--cmvs-maxImages"} = 500;
$args{"--matcher-ratio"} = 0.6;
$args{"--matcher-threshold"} = 2.0;
$args{"--pmvs-level"} = 1;
$args{"--pmvs-csize"} = 2;
$args{"--pmvs-threshold"} = 0.7;
@ -91,11 +103,16 @@ sub parseArgs {
$args{"--odm_texturing-textureResolution"} = 4096;
$args{"--odm_texturing-textureWithSize"} = 3600;
$args{"--odm_georeferencing-gcpFile"} = "gcp_list.txt";
$args{"--odm_georeferencing-useGcp"} = "true";
$args{"--zip-results"} = "true";
for($i = 0; $i <= $#ARGV; $i++) {
if($ARGV[$i] =~ /^--[^a-z\-]*/){
$args{"$ARGV[$i]"} = true;
if(!($ARGV[$i+1] =~ /^--[^a-z\-]*/)) {
if($ARGV[$i] eq "--resize-to"){
if($ARGV[$i+1] eq "orig" || $ARGV[$i+1] =~ /^[0-9]*$/){
@ -105,23 +122,31 @@ sub parseArgs {
}
}
if($ARGV[$i] eq "--start-with"){
if($ARGV[$i+1] eq "resize" || $ARGV[$i+1] eq "getKeypoints" || $ARGV[$i+1] eq "match" || $ARGV[$i+1] eq "bundler" || $ARGV[$i+1] eq "cmvs" || $ARGV[$i+1] eq "pmvs"){$args{$ARGV[$i]} = $ARGV[$i+1];
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1]."\n\t valid values are \"resize\", \"getKeypoints\", \"match\", \"bundler\", \"cmvs\", \"pmvs\"";
if($ARGV[$i+1] eq "resize" || $ARGV[$i+1] eq "getKeypoints" || $ARGV[$i+1] eq "match" || $ARGV[$i+1] eq "bundler" || $ARGV[$i+1] eq "cmvs" || $ARGV[$i+1] eq "pmvs"
|| $ARGV[$i+1] eq "odm_meshing" || $ARGV[$i+1] eq "odm_texturing" || $ARGV[$i+1] eq "odm_georeferencing" || $ARGV[$i+1] eq "odm_orthophoto"){
$args{$ARGV[$i]} = $ARGV[$i+1];
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1]."\n\t valid values are \"resize\", \"getKeypoints\", \"match\", \"bundler\", \"cmvs\", \"pmvs\",
\"odm_meshing\", \"odm_texturing\", \"odm_georeferencing\", \"odm_orthophoto\"";
}
}
if($ARGV[$i] eq "--end-with"){
if($ARGV[$i+1] eq "resize" || $ARGV[$i+1] eq "getKeypoints" || $ARGV[$i+1] eq "match" || $ARGV[$i+1] eq "bundler" || $ARGV[$i+1] eq "cmvs" || $ARGV[$i+1] eq "pmvs"){
if($ARGV[$i+1] eq "resize" || $ARGV[$i+1] eq "getKeypoints" || $ARGV[$i+1] eq "match" || $ARGV[$i+1] eq "bundler" || $ARGV[$i+1] eq "cmvs" || $ARGV[$i+1] eq "pmvs"
|| $ARGV[$i+1] eq "odm_meshing" || $ARGV[$i+1] eq "odm_texturing" || $ARGV[$i+1] eq "odm_georeferencing" || $ARGV[$i+1] eq "odm_orthophoto"){
$args{$ARGV[$i]} = $ARGV[$i+1];
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1]."\n\t valid values are \"resize\", \"getKeypoints\", \"match\", \"bundler\", \"cmvs\", \"pmvs\""; }
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1]."\n\t valid values are \"resize\", \"getKeypoints\", \"match\", \"bundler\", \"cmvs\", \"pmvs\",
\"odm_meshing\", \"odm_texturing\", \"odm_georeferencing\", \"odm_orthophoto\"";
}
}
if($ARGV[$i] eq "--run-only"){
if($ARGV[$i+1] eq "resize" || $ARGV[$i+1] eq "getKeypoints" || $ARGV[$i+1] eq "match" || $ARGV[$i+1] eq "bundler" || $ARGV[$i+1] eq "cmvs" || $ARGV[$i+1] eq "pmvs"){
if($ARGV[$i+1] eq "resize" || $ARGV[$i+1] eq "getKeypoints" || $ARGV[$i+1] eq "match" || $ARGV[$i+1] eq "bundler" || $ARGV[$i+1] eq "cmvs" || $ARGV[$i+1] eq "pmvs"
|| $ARGV[$i+1] eq "odm_meshing" || $ARGV[$i+1] eq "odm_texturing" || $ARGV[$i+1] eq "odm_georeferencing" || $ARGV[$i+1] eq "odm_orthophoto"){
$args{"--start-with"} = $ARGV[$i+1];
$args{"--end-with"} = $ARGV[$i+1];
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1]."\n\t valid values are \"resize\", \"getKeypoints\", \"match\", \"bundler\", \"cmvs\", \"pmvs\"";
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1]."\n\t valid values are \"resize\", \"getKeypoints\", \"match\", \"bundler\", \"cmvs\", \"pmvs\",
\"odm_meshing\", \"odm_texturing\", \"odm_georeferencing\", \"odm_orthophoto\"";
}
}
if($ARGV[$i] eq "--matcher-threshold"){
@ -180,7 +205,7 @@ sub parseArgs {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1];
}
}
if($ARGV[$i] eq "--force-focal"){
if($ARGV[$i+1] =~ /^[0-9]*\.?[0-9]*$/){
$args{$ARGV[$i]} = $ARGV[$i+1];
@ -230,65 +255,83 @@ sub parseArgs {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1];
}
}
if($ARGV[$i] eq "--odm_texturing-textureWithSize"){
if($ARGV[$i] eq "--odm_texturing-textureWithSize"){
if($ARGV[$i+1] =~ /^[0-9]*$/){
$args{$ARGV[$i]} = $ARGV[$i+1];
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1];
}
}
if($ARGV[$i] eq "--odm_georeferencing-gcpFile"){
$args{$ARGV[$i]} = $ARGV[$i+1];
}
if($ARGV[$i] eq "--odm_georeferencing-useGcp"){
if($ARGV[$i+1] eq "true" || $ARGV[$i+1] eq "false"){
$args{$ARGV[$i]} = $ARGV[$i+1];
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1];
}
}
if($ARGV[$i] eq "--zip-results"){
if($ARGV[$i+1] eq "true" || $ARGV[$i+1] eq "false"){
$args{$ARGV[$i]} = $ARGV[$i+1];
} else {
die "\n invalid parameter for \"".$ARGV[$i]."\": ".$ARGV[$i+1];
}
}
}
}
}
if($args{"--help"}){
print "\nusgae: run.pl [options]";
if($args{"--help"}){
print "\nusage: run.pl [options]";
print "\nit should be run from the folder contining the images to which should reconstructed";
print "\n";
print "\noptions:";
print "\n --help: ";
print "\n prints this screen";
print "\n ";
print "\n --resize-to: <positive integer|\"orig\">";
print "\n default: 1200";
print "\n default: 2400";
print "\n will resize the images so that the maximum width/height of the images are smaller or equal to the specified number";
print "\n if \"--resize-to orig\" is used it will use the images without resizing";
print "\n ";
print "\n --start-with: <\"resize\"|\"getKeypoints\"|\"match\"|\"bundler\"|\"cmvs\"|\"pmvs\">";
print "\n default: resize";
print "\n will start the sript at the specified step";
print "\n ";
print "\n --end-with: <\"resize\"|\"getKeypoints\"|\"match\"|\"bundler\"|\"cmvs\"|\"pmvs\">";
print "\n default: pmvs";
print "\n will stop the sript after the specified step";
print "\n ";
print "\n --run-only: <\"resize\"|\"getKeypoints\"|\"match\"|\"bundler\"|\"cmvs\"|\"pmvs\">";
print "\n will only execute the specified step";
print "\n equal to --start-with <step> --end-with <step>";
print "\n ";
print "\n --force-focal: <positive float>";
print "\n override the focal length information for the images";
print "\n ";
print "\n --force-ccd: <positive float>";
print "\n override the ccd width information for the images";
print "\n ";
print "\n --matcher-threshold: <float> (percent)";
print "\n default: 2.0";
print "\n ignore matched keypoints if the two images share less then <float> percent of keypoints";
print "\n ";
print "\n --matcher-ratio: <float";
print "\n default: 0.6";
print "\n ratio of the distance to the next best matched keypoint";
print "\n ";
print "\n --align-gps: ";
print "\n align with the geotag information on the image";
print "\n ";
@ -302,47 +345,51 @@ sub parseArgs {
print "\n default: 100";
print "\n the maximum number of images per cluster";
print "\n ";
print "\n --pmvs-level: <positive integer>";
print "\n default: 1";
print "\n --pmvs-csize: <positive integer>";
print "\n default: 2";
print "\n --pmvs-threshold: <float: -1.0 <= x <= 1.0>";
print "\n default: 0.7";
print "\n --pmvs-wsize: <positive integer>";
print "\n default: 7";
print "\n --pmvs-minImageNum: <positive integer>";
print "\n default: 3";
print "\n see http://grail.cs.washington.edu/software/pmvs/documentation.html for an explanation of these parameters";
print "\n";
print "\n --odm_meshing-maxVertexCount: <positive integer>";
print "\n default: 100000";
print "\n The maximum vertex count of the output mesh.";
print "\n --odm_meshing-octreeDepth: <positive integer>";
print "\n default: 9";
print "\n Octree depth used in the mesh reconstruction, increase to get more vertices, recommended values are 8-12";
print "\n --odm_meshing-samplesPerNode: <float: 1.0 <= x>";
print "\n default: 1";
print "\n Number of points per octree node, recommended value: 1.0";
print "\n --zip-results: <true|false>";
print "\n default: true";
print "\n Set to false if you do not want to have gunzipped tarball of the results.";
exit;
}
print "\n - configuration:";
foreach $args_key (sort keys %args) {
if($args{$args_key} ne ""){
print "\n $args_key: $args{$args_key}";
}
}
print "\n";
print "\n";
}
@ -354,50 +401,50 @@ sub prepareObjects {
## get the source list
@source_files = `ls -1 | egrep "\.[jJ]{1}[pP]{1}[eE]{0,1}[gG]{1}"`;
print "\n - source files - "; now(); print "\n";
foreach $file (@source_files) {
chomp($file);
chomp($file_make = `jhead \"$file\" | grep "Camera make"`);
chomp($file_model = `jhead \"$file\" | grep "Camera model"`);
chomp($file_focal = `jhead \"$file\" | grep "Focal length"`);
chomp($file_ccd = `jhead \"$file\" | grep "CCD width"`);
chomp($file_resolution = `jhead \"$file\" | grep "Resolution"`);
my %fileObject = {};
chomp(($fileObject{src}) = $file);
chomp(($fileObject{base}) = $file);
$fileObject{base} =~ s/\.[^\.]*$//;
chomp(($fileObject{make}) = $file_make =~ /: ([^\n\r]*)/);
chomp(($fileObject{model}) = $file_model =~ /: ([^\n\r]*)/);
$fileObject{make} =~ s/^\s+//; $fileObject{make} =~ s/\s+$//;
$fileObject{model} =~ s/^\s+//; $fileObject{model} =~ s/\s+$//;
$fileObject{id} = $fileObject{make}." ".$fileObject{model};
($fileObject{width}, $fileObject{height}) = $file_resolution =~ /: ([0-9]*) x ([0-9]*)/;
if(!$args{"--force-focal"}){
($fileObject{focal}) = $file_focal =~ /:[\ ]*([0-9\.]*)mm/;
} else {
$fileObject{focal} = $args{"--force-focal"};
}
if(!$args{"--force-ccd"}){
($fileObject{ccd}) = $file_ccd =~ /:[\ ]*([0-9\.]*)mm/;
if(!$fileObject{ccd}){;
$fileObject{ccd} = $ccdWidths{$fileObject{id}};
$fileObject{ccd} = $ccdWidths->{$fileObject{id}};
}
} else {
$fileObject{ccd} = $args{"--force-ccd"};
}
if($fileObject{ccd} && $fileObject{focal} && $fileObject{width} && $fileObject{height}){
if($jobOptions{resizeTo} != "orig" && (($fileObject{width} > $jobOptions{resizeTo}) || ($fileObject{height} > $jobOptions{resizeTo}))) {
$fileObject{focalpx} = $jobOptions{resizeTo} * ($fileObject{focal} / $fileObject{ccd});
@ -406,69 +453,69 @@ sub prepareObjects {
} else {
$fileObject{focalpx} = $fileObject{height} * ($fileObject{focal} / $fileObject{ccd});
}
$fileObject{isOk} = true;
$objectStats{good}++;
print "\n using $fileObject{src} dimensions: $fileObject{width}x$fileObject{height} / focal: $fileObject{focal}mm / ccd: $fileObject{ccd}mm";
} else {
$fileObject{isOk} = false;
$objectStats{bad}++;
print "\n no CCD width or focal length found for $fileObject{src} - camera: \"$fileObject{id}\"";
}
$objectStats{count}++;
if($objectStats{minWidth} == 0) { $objectStats{minWidth} = $fileObject{width}; }
if($objectStats{minHeight} == 0) { $objectStats{minHeight} = $fileObject{height}; }
$objectStats{minWidth} = $objectStats{minWidth} < $fileObject{width} ? $objectStats{minWidth} : $fileObject{width};
$objectStats{minHeight} = $objectStats{minHeight} < $fileObject{height} ? $objectStats{minHeight} : $fileObject{height};
$objectStats{maxWidth} = $objectStats{maxWidth} > $fileObject{width} ? $objectStats{maxWidth} : $fileObject{width};
$objectStats{maxHeight} = $objectStats{maxHeight} > $fileObject{height} ? $objectStats{maxHeight} : $fileObject{height};
push(@objects, \%fileObject);
}
if(!$objectStats{good}){
print "\n\n found no usable images - quitting\n";
die;
} else {
print "\n\n found $objectStats{good} usable images";
}
print "\n";
$jobOptions{jobDir} = "$jobOptions{srcDir}/reconstruction-with-image-size-$jobOptions{resizeTo}";
$jobOptions{step_1_convert} = "$jobOptions{jobDir}/_convert.templist.txt";
$jobOptions{step_1_vlsift} = "$jobOptions{jobDir}/_vlsift.templist.txt";
$jobOptions{step_1_gzip} = "$jobOptions{jobDir}/_gzip.templist.txt";
$jobOptions{step_2_filelist} = "$jobOptions{jobDir}/_filelist.templist.txt";
$jobOptions{step_2_macthes_jobs} = "$jobOptions{jobDir}/_matches_jobs.templist.txt";
$jobOptions{step_2_matches_dir} = "$jobOptions{jobDir}/matches";
$jobOptions{step_2_matches} = "$jobOptions{jobDir}/matches.init.txt";
$jobOptions{step_3_filelist} = "$jobOptions{jobDir}/list.txt";
$jobOptions{step_3_bundlerOptions} = "$jobOptions{jobDir}/options.txt";
mkdir($jobOptions{jobDir});
foreach $fileObject (@objects) {
if($fileObject->{isOk}){
$fileObject->{step_0_resizedImage} = "$jobOptions{jobDir}/$fileObject->{base}.jpg";
$fileObject->{step_1_pgmFile} = "$jobOptions{jobDir}/$fileObject->{base}.pgm";
$fileObject->{step_1_keyFile} = "$jobOptions{jobDir}/$fileObject->{base}.key";
$fileObject->{step_1_gzFile} = "$jobOptions{jobDir}/$fileObject->{base}.key.gz";
}
}
# exit
}
@ -478,30 +525,30 @@ sub resize {
print "\n";
chdir($jobOptions{jobDir});
foreach $fileObject (@objects) {
if($fileObject->{isOk}){
unless (-e "$fileObject->{step_0_resizedImage}"){
if($jobOptions{resizeTo} != "orig" && (($fileObject->{width} > $jobOptions{resizeTo}) || ($fileObject->{height} > $jobOptions{resizeTo}))){
print "\n resizing $fileObject->{src} \tto $fileObject->{step_0_resizedImage}";
run("convert -resize $jobOptions{resizeTo}x$jobOptions{resizeTo} -quality 100 \"$jobOptions{srcDir}/$fileObject->{src}\" \"$fileObject->{step_0_resizedImage}\"");
} else {
print "\n copying $fileObject->{src} \tto $fileObject->{step_0_resizedImage}";
copy("$CURRENT_DIR/$fileObject->{src}", "$fileObject->{step_0_resizedImage}");
}
} else {
} else {
print "\n using existing $fileObject->{src} \tto $fileObject->{step_0_resizedImage}";
}
chomp($file_resolution = `jhead \"$fileObject->{step_0_resizedImage}\" | grep "Resolution"`);
($fileObject->{width}, $fileObject->{height}) = $file_resolution =~ /: ([0-9]*) x ([0-9]*)/;
print "\t ($fileObject->{width} x $fileObject->{height})";
}
}
if($args{"--end-with"} ne "resize"){
if($args{"--use-opensfm"}) {
opensfm();
@ -515,16 +562,16 @@ sub getKeypoints {
print "\n";
print "\n - finding keypoints - "; now(); print "\n";
print "\n\n";
chdir($jobOptions{jobDir});
$vlsiftJobs = "";
$c = 0;
foreach $fileObject (@objects) {
$c = $c+1;
if($fileObject->{isOk}){
if($args{"--lowe-sift"}){
$vlsiftJobs .= "echo -n \"$c/$objectStats{good} - \" && convert -format pgm \"$fileObject->{step_0_resizedImage}\" \"$fileObject->{step_1_pgmFile}\"";
@ -545,13 +592,15 @@ sub getKeypoints {
}
}
}
open (SIFT_DEST, ">$jobOptions{step_1_vlsift}");
print SIFT_DEST $vlsiftJobs;
close(SIFT_DEST);
run("\"$BIN_PATH/parallel\" --no-notice --halt-on-error 1 -j3 < \"$jobOptions{step_1_vlsift}\"");
run("\"$BIN_PATH/parallel\" --no-notice --halt-on-error 1 -j+0 < \"$jobOptions{step_1_vlsift}\"");
if($args{"--end-with"} ne "getKeypoints"){
match();
}
@ -564,41 +613,41 @@ sub match {
chdir($jobOptions{jobDir});
mkdir($jobOptions{step_2_matches_dir});
$matchesJobs = "";
my $c = 0;
my $t = ($objectStats{good}-1) * ($objectStats{good}/2);
for (my $i = 0; $i < $objectStats{good}; $i++) {
for (my $j = $i+1; $j < $objectStats{good}; $j++) {
$c++;
unless (-e "$jobOptions{step_2_matches_dir}/$i-$j.txt"){
unless (-e "$jobOptions{step_2_matches_dir}/$i-$j.txt"){
$matchesJobs .= "echo -n \".\" && touch \"$jobOptions{step_2_matches_dir}/$i-$j.txt\" && \"$BIN_PATH/KeyMatch\" \"@objects[$i]->{step_1_keyFile}\" \"@objects[$j]->{step_1_keyFile}\" \"$jobOptions{step_2_matches_dir}/$i-$j.txt\" $args{'--matcher-ratio'} $args{'--matcher-threshold'}\n";
}
}
}
open (MATCH_DEST, ">$jobOptions{step_2_macthes_jobs}");
print MATCH_DEST $matchesJobs;
close(MATCH_DEST);
run("\"$BIN_PATH/parallel\" --no-notice --halt-on-error 1 -j+0 < \"$jobOptions{step_2_macthes_jobs}\"");
run("rm -f \"$jobOptions{step_2_matches}\"");
for (my $i = 0; $i < $objectStats{good}; $i++) {
for (my $j = $i+1; $j < $objectStats{good}; $j++) {
$c++;
if (-e "$jobOptions{step_2_matches_dir}/$i-$j.txt" && (-s "$jobOptions{step_2_matches_dir}/$i-$j.txt") > 0) {
run("echo \"$i $j\" >> \"$jobOptions{step_2_matches}\" && cat \"$jobOptions{step_2_matches_dir}/$i-$j.txt\" >> \"$jobOptions{step_2_matches}\"");
}
}
}
foreach $fileObject (@objects) {
if($fileObject->{isOk}){
if($fileObject->{isOk}){
@ -606,13 +655,13 @@ sub match {
}
}
}
open (MATCH_DEST, ">$jobOptions{step_2_filelist}");
print MATCH_DEST $filesList;
close(MATCH_DEST);
# run("\"$BIN_PATH/KeyMatchFull\" \"$jobOptions{step_2_filelist}\" \"$jobOptions{step_2_matches}\" ");
if($args{"--end-with"} ne "match"){
bundler();
}
@ -622,13 +671,13 @@ sub bundler {
print "\n";
print "\n - running bundler - "; now(); print "\n";
print "\n";
chdir($jobOptions{jobDir});
mkdir($jobOptions{jobDir}."/bundle");
$filesList = "";
foreach $fileObject (@objects) {
if($fileObject->{isOk}){
if($fileObject->{isOk}){
@ -636,9 +685,9 @@ sub bundler {
}
}
}
chomp($filesList);
$bundlerOptions = "--match_table matches.init.txt\n";
$bundlerOptions .= "--output bundle.out\n";
$bundlerOptions .= "--output_all bundle_\n";
@ -649,13 +698,13 @@ sub bundler {
$bundlerOptions .= "--constrain_focal_weight 0.0\n";
$bundlerOptions .= "--estimate_distortion\n";
$bundlerOptions .= "--run_bundle";
system("echo \"$bundlerOptions\" > \"$jobOptions{step_3_bundlerOptions}\"");
open (BUNDLER_DEST, ">$jobOptions{step_3_filelist}");
print BUNDLER_DEST $filesList;
close(BUNDLER_DEST);
run("\"$BIN_PATH/bundler\" \"$jobOptions{step_3_filelist}\" --options_file \"$jobOptions{step_3_bundlerOptions}\" > bundle/out");
if($args{"--align-gps"}){
@ -740,24 +789,24 @@ sub bundlerToPmvs {
run("\"$BIN_PATH/Bundle2PMVS\" \"$jobOptions{step_3_filelist}\" \"$_[0]\"");
run("\"$BIN_PATH/RadialUndistort\" \"$jobOptions{step_3_filelist}\" \"$_[0]\" pmvs");
$i = 0;
foreach $fileObject (@objects) {
if($fileObject->{isOk}){
if($fileObject->{isOk}){
if (-e "pmvs/$fileObject->{base}.rd.jpg"){
$nr = sprintf("%08d", $i++);
system("mv pmvs/$fileObject->{base}.rd.jpg pmvs/visualize/$nr.jpg");
system("mv pmvs/$nr.txt pmvs/txt/$nr.txt");
}
}
}
}
system("\"$BIN_PATH/Bundle2Vis\" pmvs/bundle.rd.out pmvs/vis.dat");
if($args{"--end-with"} ne "bundler"){
cmvs();
}
@ -769,10 +818,10 @@ sub cmvs {
print "\n";
chdir($jobOptions{jobDir});
run("\"$BIN_PATH/cmvs\" pmvs/ $args{'--cmvs-maxImages'} $CORES");
run("\"$BIN_PATH/genOption\" pmvs/ $args{'--pmvs-level'} $args{'--pmvs-csize'} $args{'--pmvs-threshold'} $args{'--pmvs-wsize'} $args{'--pmvs-minImageNum'} $CORES");
if($args{"--end-with"} ne "cmvs"){
pmvs();
}
@ -780,15 +829,15 @@ sub cmvs {
sub pmvs {
print "\n";
print "\n - running pmvs - ";
print "\n - running pmvs - "; now(); print "\n";
print "\n";
chdir($jobOptions{jobDir});
run("\"$BIN_PATH/pmvs2\" pmvs/ option-0000");
system("cp -Rf \"$jobOptions{jobDir}/pmvs/models\" \"$jobOptions{jobDir}-results\"");
if($args{"--end-with"} ne "pmvs"){
odm_meshing();
}
@ -796,15 +845,15 @@ sub pmvs {
sub odm_meshing {
print "\n";
print "\n - running meshing - ";
print "\n - running meshing - "; now(); print "\n";
print "\n";
chdir($jobOptions{jobDir});
mkdir($jobOptions{jobDir}."/odm_meshing");
mkdir($jobOptions{jobDir}."/odm_meshing");
run("\"$BIN_PATH/odm_meshing\" -inputFile $jobOptions{jobDir}-results/option-0000.ply -outputFile $jobOptions{jobDir}-results/odm_mesh-0000.ply -logFile $jobOptions{jobDir}/odm_meshing/odm_meshing_log.txt -maxVertexCount $args{'--odm_meshing-maxVertexCount'} -octreeDepth $args{'--odm_meshing-octreeDepth'} -samplesPerNode $args{'--odm_meshing-samplesPerNode'}" );
if($args{"--end-with"} ne "odm_meshing"){
odm_texturing();
}
@ -812,16 +861,16 @@ sub odm_meshing {
sub odm_texturing {
print "\n";
print "\n - running texturing - ";
print "\n - running texturing - "; now(); print "\n";
print "\n";
chdir($jobOptions{jobDir});
mkdir($jobOptions{jobDir}."/odm_texturing");
mkdir("$jobOptions{jobDir}-results/odm_texturing");
mkdir($jobOptions{jobDir}."/odm_texturing");
mkdir("$jobOptions{jobDir}-results/odm_texturing");
run("\"$BIN_PATH/odm_texturing\" -bundleFile $jobOptions{jobDir}/pmvs/bundle.rd.out -imagesPath $jobOptions{srcDir}/ -imagesListPath $jobOptions{jobDir}/pmvs/list.rd.txt -inputModelPath $jobOptions{jobDir}-results/odm_mesh-0000.ply -outputFolder $jobOptions{jobDir}-results/odm_texturing/ -textureResolution $args{'--odm_texturing-textureResolution'} -bundleResizedTo $jobOptions{resizeTo} -textureWithSize $args{'--odm_texturing-textureWithSize'} -logFile $jobOptions{jobDir}/odm_texturing/odm_texturing_log.txt" );
if($args{"--end-with"} ne "odm_texturing"){
odm_georeferencing();
}
@ -830,16 +879,23 @@ sub odm_texturing {
sub odm_georeferencing {
print "\n";
print "\n - running georeferencing - ";
print "\n - running georeferencing - "; now(); print "\n";
print "\n";
chdir($jobOptions{jobDir});
mkdir($jobOptions{jobDir}."/odm_georeferencing");
run("\"$BIN_PATH/odm_extract_utm\" -imagesPath $jobOptions{srcDir}/ -imageListFile $jobOptions{jobDir}/pmvs/list.rd.txt -outputCoordFile $jobOptions{jobDir}/odm_georeferencing/coordFile.txt");
if($args{"--odm_georeferencing-useGcp"} ne "true") {
run("\"$BIN_PATH/odm_extract_utm\" -imagesPath $jobOptions{srcDir}/ -imageListFile $jobOptions{jobDir}/pmvs/list.rd.txt -outputCoordFile $jobOptions{jobDir}/odm_georeferencing/coordFile.txt");
run("\"$BIN_PATH/odm_georef\" -bundleFile $jobOptions{jobDir}/pmvs/bundle.rd.out -coordFile $jobOptions{jobDir}/odm_georeferencing/coordFile.txt -inputFile $jobOptions{jobDir}-results/odm_texturing/odm_textured_model.obj -outputFile $jobOptions{jobDir}-results/odm_texturing/odm_textured_model_geo.obj -logFile $jobOptions{jobDir}/odm_georeferencing/odm_georeferencing_log.txt");
} elsif (-e "$jobOptions{srcDir}/$args{'--odm_georeferencing-gcpFile'}") {
run("\"$BIN_PATH/odm_georef\" -bundleFile $jobOptions{jobDir}/pmvs/bundle.rd.out -gcpFile $jobOptions{srcDir}/$args{'--odm_georeferencing-gcpFile'} -imagesPath $jobOptions{srcDir}/ -imagesListPath $jobOptions{jobDir}/pmvs/list.rd.txt -bundleResizedTo $jobOptions{resizeTo} -inputFile $jobOptions{jobDir}-results/odm_texturing/odm_textured_model.obj -outputFile $jobOptions{jobDir}-results/odm_texturing/odm_textured_model_geo.obj -logFile $jobOptions{jobDir}/odm_georeferencing/odm_georeferencing_log.txt");
} else {
print "Warning: No GCP file. Consider rerunning with argument --odm_georeferencing-useGcp false --start-with odm_georeferencing\n";
print "Skipping orthophoto\n";
$args{"--end-with"} = "odm_georeferencing";
}
run("\"$BIN_PATH/odm_georef\" -bundleFile $jobOptions{jobDir}/pmvs/bundle.rd.out -coordFile $jobOptions{jobDir}/odm_georeferencing/coordFile.txt -inputFile $jobOptions{jobDir}-results/odm_texturing/odm_textured_model.obj -outputFile $jobOptions{jobDir}-results/odm_texturing/odm_textured_model_geo.obj");
if($args{"--end-with"} ne "odm_georeferencing"){
odm_orthophoto();
}
@ -849,25 +905,26 @@ sub odm_georeferencing {
sub odm_orthophoto {
print "\n";
print "\n - running orthophoto generation - ";
print "\n - running orthophoto generation - "; now(); print "\n";
print "\n";
chdir($jobOptions{jobDir});
mkdir($jobOptions{jobDir}."/odm_orthophoto");
run("\"$BIN_PATH/odm_orthophoto\" -inputFile $jobOptions{jobDir}-results/odm_texturing/odm_textured_model_geo.obj -outputFile $jobOptions{jobDir}-results/odm_orthphoto.png -resolution 20.0 -boundry -200 -200 -200 200 200 200 200 -200");
run("\"$BIN_PATH/odm_orthophoto\" -inputFile $jobOptions{jobDir}-results/odm_texturing/odm_textured_model_geo.obj -logFile $jobOptions{jobDir}/odm_orthophoto/odm_orthophoto_log.txt -outputFile $jobOptions{jobDir}-results/odm_orthphoto.png -resolution 20.0");
}
parseArgs();
prepareObjects();
chdir($jobOptions{jobDir});
switch ($args{"--start-with"}) {
case "resize" { resize(); }
case "getKeypoints" { getKeypoints(); }
case "getKeypoints" { getKeypoints(); }
case "match" { match(); }
case "bundler" { bundler(); }
case "cmvs" { cmvs(); }
@ -878,6 +935,12 @@ switch ($args{"--start-with"}) {
case "odm_orthophoto" { odm_orthophoto(); }
}
if($args{"--zip-results"} eq "true") {
print "\nCompressing results - "; now(); print "\n";
print "\n";
run("cd $jobOptions{jobDir}-results/ && tar -czf $jobOptions{jobDir}-results.tar.gz *");
}
print "\n";
print "\n - done - "; now(); print "\n";
print "\n";