This commit is contained in:
Laureηt 2022-10-28 16:25:45 +02:00
commit f61d4cfb48
No known key found for this signature in database
GPG key ID: D88C6B294FD40994
78 changed files with 52438 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
build/

110
BUILD.md Normal file
View file

@ -0,0 +1,110 @@
# An Augmented Reality application
## Building instructions
Required tools:
* C/C++ compiler (gcc >= 4.6 or visual studio or clang)
* cmake
* [optional] Doxygen and graphviz to generate the htlm documentation
### Dependencies
The project depends on:
- OpenCV 2.4.9
- OpenGL
- GLM ([webpage](http://devernay.free.fr/hacks/glm/)) which provides a more complete interface to the OBJ format (i.e. it manages textures, materials etc.).
If at any stage you get an error about missing ``Xi`` and ``Xmu`` library, you need to install them. In linux you can do
```shell
sudo apt-get install libxi-dev libxmu-dev.
```
### Setting up and building:
OpenCV and OpenGL are normally already installed on your machine. In case you may have a look at the next section to install OpenCV on your own machine. As for GLM, it comes with the project, so it will be compiled and built the first time it is needed.
In order to setting up the project, from the root of the project do:
```shell
mkdir build
cd build
cmake ..
```
Then each application can be compiled by simply doing a
```shell
make <filename_without_extension>
```
If you run
```shell
make help
```
a list of all possible targets is displayed.
Remember to set the ``LD_LIBRARY_PATH`` to allow your application to access the ``GLM`` library:
```shell
export $LD_LIBRARY_PATH=/home/<yourhome>/<path/to/code>/3dparty/glm/build/lib:$LD_LIBRARY_PATH
```
Also you may want to add the path to OpenCV if they are not installed in the system.
Finally, as usual, running
```shell
make clean
```
will delete all the executable and the compilation objects.
In case you want to try the code on a different machine, you need to first install the OpenCV libraries (see next section) and then do
```shell
cmake .. -DOpenCV_DIR=path/to/OpenCVConfig.cmake
```
in order to specify the directory where you build them. More in general, you need to provide the path to the file ``OpenCVConfig.cmake``, which you can find e.g. with
```shell
locate OpenCVConfig.cmake
```
from your shell.
#### Code Documentation
In order to generate the documentation you need have doxygen and graphviz installed. On linux:
```shell
sudo apt-get install doxygen graphviz.
```
On Mac OSX with homebrew
```shell
brew install doxygen graphviz.
```
Then a
```shell
make doc
```
will generate the documentation in the ``doc`` folder of your build.
#### Installing OpenCV
You can download the code from [here](http://opencv.org/downloads.html) or clone the [github repository](https://github.com/itseez/opencv)
Create a `build` directory where to build the library. It also advisable to set an non-system install directory, so that it will be easier to set up the environment later:
```
mkdir build && cd build && cmake .. -DCMAKE_INSTALL_PREFIX=`pwd`/install
make install -j n
```
You can even run ``ccmake ..`` to set up other options (eg. CUDA support).

191
CMakeLists.txt Normal file
View file

@ -0,0 +1,191 @@
cmake_minimum_required(VERSION 3.1)
include(ExternalProject)
project( TP_Interface_AR VERSION 2020.1.0 LANGUAGES CXX)
# guard against in-source builds
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds not allowed.")
endif()
# set the path where we can find the findXXX.cmake
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/.cmake)
# add a search path for the glm libraries
# it will work if they are already compiled in /3rdparty
if(NOT DEFINED GLM_DIR)
set(GLM_DIR ${PROJECT_SOURCE_DIR}/3rdparty/glm/build)
endif()
list(APPEND CMAKE_LIBRARY_PATH "${GLM_DIR}/lib")
list(APPEND CMAKE_INCLUDE_PATH "${GLM_DIR}/include")
# set the output path for the generated files
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib )
#########################################################
# SET COMPILATION FLAGS FOR C++11
#########################################################
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#########################################################
#
# EXTERNAL LIBRARIES
#
#########################################################
#########################################################
# LIB GLM
#########################################################
#try to find the libraries
find_package(GLM )
if(NOT GLM_FOUND)
# Fallback is only for *nix systems
if(MSVC)
message(FATAL_ERROR "You need to provide the location of the GLM library through the GLM_DIR
variable, e.g. -DGLM_DIR:PATH=<install path>")
endif()
#just to be sure
set(GLM_DIR ${PROJECT_SOURCE_DIR}/3rdparty/glm)
# set(EP_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/3rdpary)
# set_property(DIRECTORY PROPERTY EP_BASE ${PROJECT_SOURCE_DIR}/3rdparty)
ExternalProject_Add( glm
URL http://devernay.free.fr/hacks/glm/glm-0.3.2.tar.gz
PREFIX ${GLM_DIR}
BUILD_IN_SOURCE 1
INSTALL_DIR ${GLM_DIR}/build
CONFIGURE_COMMAND ./configure --prefix=${GLM_DIR}/build --enable-shared
BUILD_COMMAND make -j 4
INSTALL_COMMAND make install)
ExternalProject_Get_Property(glm install_dir)
message( "lib glm has not be found, it will be installed in: ${install_dir}")
set(LIBGLM_INCLUDE_DIRS ${install_dir}/include)
# message( "lib glm has not be found, it will be installed in: ${LIBGLM_INCLUDE_DIRS}")
add_library(glm_lib SHARED IMPORTED)
set_property(TARGET glm_lib PROPERTY IMPORTED_LOCATION ${install_dir}/lib/libglm${CMAKE_SHARED_LIBRARY_SUFFIX})
add_dependencies(glm_lib glm)
set(LIBGLM_LIBRARIES glm_lib)
set(GLM_FOUND ON)
else()
message( "-- Found glm" )
message( STATUS "LIBGLM_INCLUDE_DIRS ${LIBGLM_INCLUDE_DIRS}" )
message( STATUS "LIBGLM_LIBRARIES ${LIBGLM_LIBRARIES}" )
endif(NOT GLM_FOUND)
#########################################################
# FIND OPENCV
#########################################################
if(MSVC)
set(OpenCV_STATIC ON)
endif()
find_package(OpenCV 2.4 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIB_DIR})
add_definitions(${OpenCV_DEFINITIONS})
# message( STATUS "OpenCV_LIB_DIR ${OpenCV_LIB_DIR}" )
# message( STATUS "OpenCV_VERSION ${OpenCV_INCLUDE_DIRS}" )
# message( STATUS "OpenCV_VERSION ${OpenCV_VERSION}" )
# message( STATUS "OpenCV_FOUND ${OpenCV_FOUND}" )
if(NOT OpenCV_FOUND)
message(ERROR " OpenCV not found!")
else()
message( "-- Found OpenCV version: ${OpenCV_VERSION}" )
endif(NOT OpenCV_FOUND)
#########################################################
# FIND OPENGL
#########################################################
find_package(OpenGL REQUIRED)
include_directories(${OpenGL_INCLUDE_DIRS})
link_directories(${OpenGL_LIBRARY_DIRS})
add_definitions(${OpenGL_DEFINITIONS})
# MESSAGE( "${OPENGL_LIBRARIES}" )
# MESSAGE( "${OPENGL_LIBRARIES_DIRS}" )
# MESSAGE( "${OPENGL_DEFINITIONS}" )
if(NOT OPENGL_FOUND)
message(ERROR " OPENGL not found!")
endif(NOT OPENGL_FOUND)
#########################################################
# FIND GLUT
#########################################################
if(MSVC)
message(STATUS "GLUT_ROOT_PATH: ${GLUT_ROOT_PATH}")
endif()
find_package(GLUT REQUIRED)
message(STATUS "GLUT_FOUND: ${GLUT_FOUND}")
message(STATUS "GLUT_INCLUDE_DIR: ${GLUT_INCLUDE_DIR}")
message(STATUS "GLUT_LIBRARIES: ${GLUT_LIBRARIES}")
include_directories(${GLUT_INCLUDE_DIR})
link_directories(${GLUT_LIBRARY_DIRS})
add_definitions(${GLUT_DEFINITIONS})
# message( "glut ${GLUT_INCLUDE_DIR}" )
if(NOT GLUT_FOUND)
message(ERROR " GLUT not found!")
else()
message( "-- Found GLUT" )
endif(NOT GLUT_FOUND)
## FreeGLUT ?
# find_package(FreeGLUT REQUIRED)
# include_directories(${FreeGLUT_INCLUDE_DIRS})
# link_directories(${FreeGLUT_LIBRARY_DIRS})
# add_definitions(${FreeGLUT_DEFINITIONS})
# MESSAGE( "${FREEGLUT_INCLUDE_PATH}" )
# MESSAGE( "${FREEGLUT_LIBRARY}" )
# MESSAGE( "${FreeGLUT_DEFINITIONS}" )
# if(NOT FREEGLUT_FOUND)
# message(ERROR " FreeGLUT not found!")
# endif(NOT FREEGLUT_FOUND)
#########################################################
# Doxygen
#########################################################
# add a target to generate API documentation with Doxygen
find_package(Doxygen QUIET)
# message( "${DOXYGEN_EXECUTABLE}" )
if(DOXYGEN_FOUND)
set(CMAKE_DOC_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in ${CMAKE_DOC_OUTPUT_DIRECTORY}/Doxyfile @ONLY)
add_custom_target(doc
${DOXYGEN_EXECUTABLE} ${CMAKE_DOC_OUTPUT_DIRECTORY}/Doxyfile
WORKING_DIRECTORY ${CMAKE_DOC_OUTPUT_DIRECTORY}
COMMENT "Generating API documentation with Doxygen" VERBATIM)
endif(DOXYGEN_FOUND)
#########################################################
#
# PROJECT LIBRARIES
#
#########################################################
#########################################################
# TRACKER LIBRARY
#########################################################
add_subdirectory(src)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/tracker)

362
LICENSE Normal file
View file

@ -0,0 +1,362 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. "Contributor"
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. "Incompatible With Secondary Licenses"
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the terms of
a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in a
separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible, whether
at the time of the initial grant or subsequently, any and all of the
rights conveyed by this License.
1.10. "Modifications"
means any of the following:
a. any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the License,
by the making, using, selling, offering for sale, having made, import,
or transfer of either its Contributions or its Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, "control" means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights to
grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter the
recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty, or
limitations of liability) contained within the Source Code Form of the
Covered Software, except that You may alter any license notices to the
extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute,
judicial order, or regulation then You must: (a) comply with the terms of
this License to the maximum extent possible; and (b) describe the
limitations and the code they affect. Such description must be placed in a
text file included with all distributions of the Covered Software under
this License. Except to the extent prohibited by statute or regulation,
such description must be sufficiently detailed for a recipient of ordinary
skill to be able to understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing
basis, if such Contributor fails to notify You of the non-compliance by
some reasonable means prior to 60 days after You have come back into
compliance. Moreover, Your grants from a particular Contributor are
reinstated on an ongoing basis if such Contributor notifies You of the
non-compliance by some reasonable means, this is the first time You have
received notice of non-compliance with this License from such
Contributor, and You become compliant prior to 30 days after Your receipt
of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an "as is" basis,
without warranty of any kind, either expressed, implied, or statutory,
including, without limitation, warranties that the Covered Software is free
of defects, merchantable, fit for a particular purpose or non-infringing.
The entire risk as to the quality and performance of the Covered Software
is with You. Should any Covered Software prove defective in any respect,
You (not any Contributor) assume the cost of any necessary servicing,
repair, or correction. This disclaimer of warranty constitutes an essential
part of this License. No use of any Covered Software is authorized under
this License except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from
such party's negligence to the extent applicable law prohibits such
limitation. Some jurisdictions do not allow the exclusion or limitation of
incidental or consequential damages, so this exclusion and limitation may
not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts
of a jurisdiction where the defendant maintains its principal place of
business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions. Nothing
in this Section shall prevent a party's ability to bring cross-claims or
counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides that
the language of a contract shall be construed against the drafter shall not
be used to construe this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses If You choose to distribute Source Code Form that is
Incompatible With Secondary Licenses under the terms of this version of
the License, the notice described in Exhibit B of this License must be
attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file,
then You may include the notice in a location (such as a LICENSE file in a
relevant directory) where a recipient would be likely to look for such a
notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
This Source Code Form is "Incompatible
With Secondary Licenses", as defined by
the Mozilla Public License, v. 2.0.

52
README.md Normal file
View file

@ -0,0 +1,52 @@
An Augmented Reality application
===========================================
------------
Introduction
------------
The objective of these TP sessions is to build a simple augmented reality application using OpenCV for the camera tracking part and OpenGL for the rendering. The exercises that will be proposed are meant to gradually introduce you to the OpenCV libraries and build all the function that are needed for a camera tracker in an incremental way, so that you will be able to test and debug each function, before plugging all together in the camera tracker class.
The main idea is to use a chessboard as a marker and render on top of that the augmented reality. The final application should render an OpenGL teapot on top of the chessboard. We will get there step by step, first detecting the chessboard, then create some basic rendering in OpenCV, and at last plugging everything in the OpenGL pipeline.
-----------------
Code Organization
-----------------
The directories are organized as follows:
* ``doc`` contains a pdf copy of this text, a pdf copy of the reduced opencv tutorials, a pdf copy of the full, original opencv tutorial, and a pdf copy of the API reference manual of opencv (ie the copy of the online documentation).
* ``data`` contains some images, videos and other data that will be used through the TP.
* ``src`` contains the source files that you have to modify and complete; they are organize in directories:
* ``tutorials`` contains the code used in the tutorials, in case you need to try it;
* ``tp`` contains the files that you need to modify and complete through all the sessions of the TP.
* ``3dparty`` this directory contains a library that will be used at the end of the TP. You don't have to worry (or do anything...) about this directory.
--------
Building
--------
See [BUILD](BUILD.md) text file
-------
License
-------
See [LICENSE](LICENSE) text file
-------
Authors
-------
Simone Gasparini
---------
Contact
---------
Simone Gasparini simone.gasparini@enseeiht.fr

BIN
data/images/HappyFish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
data/images/cat.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
data/images/left01re.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
data/images/re_circles2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
data/images/re_circles3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
data/images/re_left01.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
data/images/re_left02.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
data/images/re_left06.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
data/images/re_left08.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

BIN
data/images/re_left30.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
data/images/re_left38.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
data/images/re_left39.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
data/images/re_left44.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

26
data/models/calib.xml Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<opencv_storage>
<calibration_time>"Mon 21 Oct 2013 07:16:31 PM CEST"</calibration_time>
<image_width>640</image_width>
<image_height>360</image_height>
<board_width>9</board_width>
<board_height>6</board_height>
<square_size>1.</square_size>
<!-- flags: +zero_tangent_dist -->
<flags>8</flags>
<camera_matrix type_id="opencv-matrix">
<rows>3</rows>
<cols>3</cols>
<dt>d</dt>
<data>
4.8428509485313901e+02 0. 3.2009932991075260e+02 0.
4.8365482958967795e+02 1.6283922248766723e+02 0. 0. 1.</data></camera_matrix>
<distortion_coefficients type_id="opencv-matrix">
<rows>5</rows>
<cols>1</cols>
<dt>d</dt>
<data>
-9.3396873795605365e-02 2.3550692129669618e-01 0. 0.
-3.8791765186556898e-01</data></distortion_coefficients>
<avg_reprojection_error>1.7869347177607542e-01</avg_reprojection_error>
</opencv_storage>

7886
data/models/cessna.obj Normal file

File diff suppressed because it is too large Load diff

BIN
data/models/knight.aoi Normal file

Binary file not shown.

29
data/models/knight.mtl Normal file
View file

@ -0,0 +1,29 @@
#Produced by Art of Illusion 2.8.1, Thu Apr 01 23:51:44 PDT 2010
newmtl Sword
Kd 1 1 1
Ks 0 0 0
Ka 1 1 1
illum 1
newmtl Armor
Kd 0.45 0.4275 0.225
Ks 1 1 1
Ka 0.45 0.4275 0.225
illum 2
Ns 57
newmtl Armor_3
Kd 0.45 0.405 0
Ks 1 1 1
Ka 0.45 0.405 0
illum 2
Ns 57
newmtl Face
Kd 0 0 0
Ks 0 0 0
Ka 0 0 0
illum 1
newmtl Armor_2
Kd 0.33 0.33 0.33
Ks 1 1 1
Ka 0.33 0.33 0.33
illum 2
Ns 50

2835
data/models/knight.obj Normal file

File diff suppressed because it is too large Load diff

8863
data/models/lamp.obj Normal file

File diff suppressed because it is too large Load diff

744
data/models/shuttle.obj Normal file
View file

@ -0,0 +1,744 @@
# Viewpoint Datalabs International, Inc. Copyright 1996
# mtllib ./vp.mtl
g
v 3.070224 -0.119728 0.996443
v 5.942016 -0.012019 4.157199
v 6.614015 -0.063428 4.157199
v 5.759114 0.000000 1.664500
v 3.070224 -0.449143 0.929434
v 5.000295 -0.539011 1.315104
v 3.070224 -0.604752 0.872464
v 3.070224 -0.866525 0.730690
v 3.070224 -0.959007 0.650256
v 3.070224 -1.053631 0.163277
v 2.983248 -1.080021 -0.880639
v 6.130317 -1.100022 -1.106943
v 3.739287 -4.334102 -0.876958
v 4.400283 -4.682100 -0.952940
v 3.038248 -4.334102 -0.811319
v 3.180259 -4.550090 -0.921939
v 2.700250 -4.334102 -0.947940
v 0.840214 -2.480049 -1.050312
v 1.208789 -1.060728 0.203820
v 1.208789 -1.054148 0.411073
v 1.208789 -0.958092 0.610367
v 1.208789 -0.875165 0.685964
v 1.208789 -0.621528 0.854704
v 1.208789 -0.467365 0.922276
v -4.649089 -1.039587 0.209476
v -4.649345 -0.922345 0.432259
v -4.649708 -0.652575 0.753550
v -4.999902 -1.012545 0.094530
v -4.999240 -0.870266 0.347384
v -4.999321 -0.802315 0.416133
v -4.906714 -0.620194 0.686502
v -4.999759 -0.491153 0.805206
v -5.568033 -0.119200 0.568687
v -5.349121 -0.814175 0.247113
v -5.348800 -0.938377 -0.030175
v -6.499984 -0.676000 -0.433500
v -6.499984 -0.610000 -0.164800
v -6.499984 -0.240000 0.109600
v -7.649984 0.000000 -0.620000
v 1.209237 -1.080021 -1.321617
v 3.070224 0.119728 0.996443
v 3.093016 0.040804 1.276300
v 6.614015 0.063428 4.157199
v 3.070224 0.449143 0.929434
v 5.000295 0.539011 1.315104
v 3.070224 0.604752 0.872464
v 3.070224 0.866525 0.730690
v 5.000295 1.149023 1.260104
v 3.070224 0.959007 0.650256
v 3.070224 1.053627 0.449897
v 5.000295 1.428028 0.442095
v 3.070224 1.053631 0.163277
v 2.983248 1.080021 -0.880639
v 5.000295 1.302926 -1.259946
v 3.739287 4.334102 -0.876958
v 4.400283 4.682100 -0.952940
v 3.038248 4.334102 -0.811319
v 3.180259 4.550090 -0.921939
v 1.209237 1.080021 -0.636414
v 2.700250 4.334102 -0.947940
v 0.169216 1.990039 -1.063281
v 1.208789 1.060728 0.203820
v 1.208789 1.054148 0.411073
v 1.208789 0.958092 0.610367
v 1.208789 0.875165 0.685964
v 1.208789 0.621528 0.854704
v 1.208789 0.467365 0.922276
v -4.649089 1.039587 0.209476
v -4.649345 0.922345 0.432259
v -4.649708 0.652575 0.753550
v -4.649856 0.514670 0.885149
v -4.649964 0.160748 0.994500
v -4.999902 1.012545 0.094530
v -4.999240 0.870266 0.347384
v -4.999321 0.802315 0.416133
v -4.999759 0.491153 0.805206
v -4.999948 0.160720 0.980689
v -5.299752 0.147914 0.811038
v -5.349121 0.814175 0.247113
v -5.348800 0.938377 -0.030175
v -6.499984 0.676000 -0.433500
v -6.499931 0.693962 -0.748535
v -6.499984 0.610000 -0.164800
v -6.499984 0.523000 -0.048800
v -6.499984 0.240000 0.109600
v 1.209237 1.080021 -1.321617
v -5.568033 0.119200 0.568687
v -5.299752 -0.147914 0.811038
v -4.999948 -0.160720 0.980689
v -4.649964 -0.160748 0.994500
v 1.208789 -0.130179 0.996071
v 1.208789 0.130179 0.996071
v 3.093016 -0.040804 1.276300
v 5.942016 0.012019 4.157199
v 7.043714 0.000000 4.157199
v 4.998233 -0.130896 1.193100
v 5.171283 -1.310384 -1.055942
v 6.130317 1.100022 -1.106943
v 2.983248 -1.080021 -1.351649
v 2.983248 1.080021 -1.351649
v -6.499931 -0.693962 -0.748535
v -4.999902 -1.000020 -0.943979
v 0.169216 -1.990039 -1.063281
v 5.000295 -1.510030 0.750093
v 5.000295 -0.874017 1.399122
v 5.000295 -1.149023 1.260104
v 5.000295 0.874017 1.399122
v -7.074984 -0.304058 -0.264426
v -7.074984 0.139529 -0.169387
v -7.074984 0.304058 -0.264426
v -7.074957 0.403450 -0.684268
v -7.074984 0.393008 -0.495246
v -7.074984 0.354637 -0.334026
v -7.074984 0.057454 -0.155083
v -7.074984 -0.354637 -0.334026
v -7.074984 -0.393008 -0.495246
v -7.074957 -0.403450 -0.684268
v -7.074984 -0.139529 -0.169387
v -7.074984 -0.057454 -0.155083
v 5.257180 -0.244260 -0.448877
v 5.275361 -0.389797 -0.446328
v 5.534085 -0.255527 -0.410058
v 5.858724 -0.171973 -0.364548
v 6.246687 -0.127423 -0.310161
v 6.245811 -0.209802 -0.310283
v 5.957494 -0.242908 -0.350702
v 5.684797 -0.367023 -0.388930
v 5.030259 -0.310424 -0.039389
v 5.218888 -0.403501 -0.175729
v 5.254566 -0.476272 -0.297997
v 5.497149 -0.409135 -0.146573
v 5.811742 -0.367356 -0.029404
v 6.194348 -0.345081 0.063191
v 6.203377 -0.386271 -0.007583
v 5.919040 -0.402825 -0.076394
v 5.661265 -0.464884 -0.221067
v 5.030257 -0.815056 -0.039376
v 5.218887 -0.721987 -0.175721
v 5.254566 -0.649223 -0.297993
v 5.497147 -0.716354 -0.146565
v 5.811740 -0.758129 -0.029394
v 6.194347 -0.780403 0.063202
v 6.203376 -0.739216 -0.007574
v 5.919039 -0.722663 -0.076386
v 5.661264 -0.660610 -0.221062
v 5.533661 -0.562752 -0.410117
v 5.257178 -0.881243 -0.448860
v 5.275359 -0.735706 -0.446319
v 5.534083 -0.869976 -0.410042
v 5.858722 -0.953530 -0.364528
v 6.246684 -0.998080 -0.310138
v 6.245809 -0.915701 -0.310265
v 5.957492 -0.882595 -0.350685
v 5.684796 -0.758480 -0.388920
v 5.151601 -0.815102 -0.904963
v 5.295470 -0.722016 -0.722016
v 5.296154 -0.649239 -0.594654
v 5.571022 -0.716382 -0.673535
v 5.905705 -0.758165 -0.699682
v 6.299025 -0.780442 -0.683500
v 6.288245 -0.739248 -0.612975
v 5.995947 -0.722692 -0.625000
v 5.708329 -0.660628 -0.556788
v 5.295474 -0.403530 -0.722041
v 5.296155 -0.476288 -0.594668
v 5.571025 -0.409163 -0.673559
v 5.905710 -0.367392 -0.699712
v 6.299029 -0.345120 -0.683534
v 6.288249 -0.386303 -0.613002
v 5.995951 -0.402854 -0.625025
v 5.708331 -0.464902 -0.556803
v 5.218888 0.403501 -0.175729
v 5.257180 0.244260 -0.448877
v 5.254566 0.476272 -0.297997
v 5.275361 0.389797 -0.446328
v 5.497149 0.409135 -0.146573
v 5.534085 0.255527 -0.410058
v 5.811742 0.367356 -0.029404
v 5.858724 0.171973 -0.364548
v 6.194348 0.345081 0.063191
v 6.246687 0.127423 -0.310161
v 6.203377 0.386271 -0.007583
v 6.245811 0.209802 -0.310283
v 5.919040 0.402825 -0.076394
v 5.957494 0.242908 -0.350702
v 5.661265 0.464884 -0.221067
v 5.684797 0.367023 -0.388930
v 5.218887 0.721987 -0.175721
v 5.254566 0.649223 -0.297993
v 5.497147 0.716354 -0.146565
v 5.811740 0.758129 -0.029394
v 6.194347 0.780403 0.063202
v 6.203376 0.739216 -0.007574
v 5.919039 0.722663 -0.076386
v 5.661264 0.660610 -0.221062
v 5.257178 0.881243 -0.448860
v 5.275359 0.735706 -0.446319
v 5.534083 0.869976 -0.410042
v 5.858722 0.953530 -0.364528
v 6.246684 0.998080 -0.310138
v 6.245809 0.915701 -0.310265
v 5.957492 0.882595 -0.350685
v 5.684796 0.758480 -0.388920
v 5.533661 0.562752 -0.410117
v 5.295470 0.722016 -0.722016
v 5.296154 0.649239 -0.594654
v 5.571022 0.716382 -0.673535
v 5.905705 0.758165 -0.699682
v 6.299025 0.780442 -0.683500
v 6.288245 0.739248 -0.612975
v 5.995947 0.722692 -0.625000
v 5.708329 0.660628 -0.556788
v 5.295474 0.403530 -0.722041
v 5.296155 0.476288 -0.594668
v 5.571025 0.409163 -0.673559
v 5.905710 0.367392 -0.699712
v 6.299029 0.345120 -0.683534
v 6.288249 0.386303 -0.613002
v 5.995951 0.402854 -0.625025
v 5.708331 0.464902 -0.556803
v 5.165639 -0.318491 0.637328
v 5.166101 -0.159250 0.913146
v 4.998497 -0.252327 1.074635
v 5.183997 -0.172954 0.637297
v 5.184248 -0.086480 0.787078
v 5.445252 -0.307224 0.636859
v 5.445698 -0.153617 0.902920
v 5.773065 -0.390779 0.636310
v 5.773632 -0.195395 0.974730
v 6.164821 -0.435329 0.635652
v 6.165453 -0.217671 1.012654
v 6.163937 -0.352950 0.635654
v 6.164450 -0.176480 0.941314
v 5.872800 -0.319843 0.636142
v 5.873264 -0.159926 0.913131
v 5.597437 -0.195729 0.636604
v 5.597722 -0.097867 0.806108
v 5.444824 0.000000 0.636860
v 5.166102 0.159236 0.913155
v 5.184248 0.086472 0.787083
v 5.445698 0.153603 0.902928
v 5.773632 0.195378 0.974740
v 6.165453 0.217651 1.012665
v 6.164450 0.176464 0.941323
v 5.873265 0.159912 0.913140
v 5.597722 0.097858 0.806113
v 5.165639 0.318491 0.637345
v 4.997765 0.504639 0.637636
v 5.183997 0.172954 0.637307
v 5.445252 0.307224 0.636875
v 5.773065 0.390779 0.636330
v 6.164821 0.435329 0.635675
v 6.163937 0.352950 0.635673
v 5.872800 0.319843 0.636159
v 5.597437 0.195729 0.636614
v 5.165176 0.159265 0.361518
v 4.997031 0.252350 0.200598
v 5.183746 0.086488 0.487521
v 5.444806 0.153631 0.370806
v 5.772497 0.195413 0.297899
v 6.164188 0.217691 0.258662
v 6.163424 0.176496 0.330003
v 5.872335 0.159941 0.359162
v 5.597153 0.097876 0.467105
v 5.165176 -0.159221 0.361493
v 4.997031 -0.252281 0.200558
v 5.183746 -0.086464 0.487507
v 5.444806 -0.153589 0.370782
v 5.772497 -0.195360 0.297868
v 6.164188 -0.217631 0.258628
v 6.163424 -0.176448 0.329975
v 5.872335 -0.159897 0.359136
v 5.597153 -0.097850 0.467090
v 5.090927 -1.067391 -0.472156
v 5.171283 1.310384 -1.055942
v 5.151606 0.310470 -0.905003
v 5.151606 -0.310470 -0.905003
v 5.030257 0.815056 -0.039376
v 5.030259 0.310424 -0.039389
v 5.090930 -0.058113 -0.472183
v 5.090930 0.058113 -0.472183
v 5.000295 -1.210004 0.173074
v 5.000295 1.210004 0.173074
v 5.000295 -1.428028 0.442095
v 4.997764 -0.504639 0.637610
v 4.998497 0.252304 1.074648
v 4.998233 0.130896 1.193100
v 5.000295 1.510030 0.750093
v 5.151601 0.815102 -0.904963
v 5.090927 1.067391 -0.472156
v 3.070224 -1.053627 0.449897
v -5.349205 0.737229 0.323968
v -5.349205 -0.737229 0.323968
v -5.349476 -0.470935 0.566062
v -6.499984 -0.098825 0.133439
v -6.499984 0.098825 0.133439
v -6.499984 -0.523000 -0.048800
v -5.349476 0.470935 0.566062
v -4.999902 1.000020 -0.943979
v 0.840214 2.480049 -1.050312
v 1.209237 -1.080021 -0.636414
v 3.804262 4.682100 -0.938960
v 5.000295 -1.302926 -1.259946
v 3.804262 -4.682100 -0.938960
v -4.649856 -0.514670 0.885149
v -4.999492 0.681710 0.569242
v -4.649417 0.860391 0.497003
v -4.906714 0.620194 0.686502
v -4.649417 -0.860391 0.497003
v -4.999492 -0.681710 0.569242
# 310 vertices
# 0 vertex parms
# 0 texture vertices
# 0 normals
g windows
# usemtl glass
s 1
f 310 32 294
f 76 308 306
f 294 88 33
f 310 31 32
f 88 294 32
f 87 33 88 78
f 87 78 298
f 298 76 306
f 298 78 76
g tail
# usemtl bone
s 4
f 95 3 96 4
f 4 287 43 95
f 94 2 3 43
f 3 2 93 96
f 41 1 93 42
f 41 42 287
f 43 3 95
f 287 42 94 43
f 42 93 2 94
f 96 93 1
g rearbody
s 6
f 275 98 54
f 96 223 286 287
f 97 277 155
f 276 281 280 277
f 276 275 289
f 283 282 128 279
f 283 290 275
f 257 51 248
f 282 303 97
f 96 6 106
f 303 12 97
f 104 285 223
f 97 155 274
f 284 282 266
f 286 288 287
f 137 128 282
f 283 279 278
f 248 288 286
f 6 105 106
f 275 54 283
f 284 266 285
f 96 287 4
f 284 285 104
f 248 51 288
f 283 278 290
f 274 137 282
f 289 275 290
f 97 12 98 275
f 48 107 45
f 96 106 104
f 282 283 257 266
f 97 275 276 277
f 104 223 96
f 257 283 51
f 97 274 282
f 128 280 281 279
f 287 288 48
f 287 48 45
g body
s 7
f 309 31 310
f 294 33 295
f 108 118 39
f 80 79 74 73
f 49 47 48
f 5 1 91 24
f 10 291 20 19
f 294 295 38
f 78 77 76
f 81 82 111 112
f 65 66 46 47
f 30 309 310
f 5 105 6
f 30 29 26 309
f 68 62 59 299
f 78 88 89 77
f 118 38 295 119
f 83 81 112 113
f 64 65 47 49
f 35 37 36
f 23 8 7
f 24 91 90 305
f 62 52 53 59
f 296 85 109 114
f 79 292 75 74
f 50 49 288
f 22 23 27
f 282 10 11 303
f 293 294 297
f 71 72 92 67
f 112 39 113
f 310 294 293
f 305 90 89
f 308 70 307
f 296 87 298
f 114 39 119
f 71 77 72
f 45 107 44
f 8 23 22
f 7 5 24 23
f 287 44 41
f 307 69 74 75
f 92 91 1 41
f 63 62 68
f 28 29 34 35
f 105 7 8 106
f 32 89 88
f 49 48 288
f 82 81 299
f 115 37 297 108
f 113 39 110
f 73 74 69 68
f 29 30 293 34
f 291 104 9
f 22 27 309
f 54 53 52 283
f 83 79 80
f 83 80 81
f 48 47 46 107
f 25 20 21 26
f 301 11 10 19
f 39 115 108
f 306 307 75
f 110 39 109
f 292 298 306
f 306 308 307
f 70 66 65
f 294 38 297
f 5 6 96
f 85 84 110 109
f 62 63 50 52
f 102 25 28
f 9 106 8
f 310 293 30
f 70 71 66
f 77 89 90 72
f 66 71 67
f 297 37 34 293
f 106 9 104
f 25 19 20
f 44 107 46
f 85 296 298
f 117 101 36 116
f 111 39 112
f 307 70 65
f 35 34 37
f 23 305 27
f 102 301 19 25
f 50 288 51
f 80 73 299
f 84 298 292
f 49 50 63 64
f 32 305 89
f 1 5 96
f 32 31 27 305
f 66 67 44 46
f 296 295 33 87
f 291 10 282
f 81 80 299
f 309 27 31
f 84 85 298
f 116 36 37 115
f 292 79 83 84
f 283 52 51
f 309 26 21 22
f 284 291 282
f 102 36 101
f 65 64 69 307
f 295 296 114 119
f 73 68 299
f 39 116 115
f 105 5 7
f 23 24 305
f 39 117 116
f 77 71 76
f 109 39 114
f 297 38 118 108
f 75 292 306
f 39 118 119
f 21 20 291 9
f 9 8 22 21
f 287 45 44
f 71 70 308 76
f 84 83 113 110
f 67 92 41 44
f 25 26 29 28
f 104 291 284
f 102 28 35
f 69 64 63 68
f 72 90 91 92
f 52 50 51
f 102 35 36
g wings
s 5
f 16 15 17
f 304 15 16
f 300 57 60
f 14 13 304
f 59 53 55 57
f 60 57 58
f 18 301 103
f 300 59 57
f 304 13 15
f 56 55 53 54
f 15 13 11 301
f 61 59 300
f 57 55 302
f 103 301 102
f 17 15 301
f 303 11 13 14
f 58 57 302
f 302 55 56
f 17 301 18
f 299 59 61
g tiles
# usemtl fldkdkgrey
s 3
f 302 56 54
f 18 103 40
f 16 17 99
f 86 61 300
f 99 304 16
f 303 14 304
f 99 303 304
f 17 18 99
f 302 54 100
f 58 302 100
f 100 86 300
f 18 40 99
f 100 60 58
f 100 300 60
f 101 117 111 82
f 102 101 82 299
f 117 39 111
f 99 100 54 303
f 303 54 98 12
f 86 100 99 40
f 40 103 61 86
f 299 61 103 102
g enginside
# usemtl redbrick
s 9
f 238 255 246
f 194 202 201 193
f 153 162 163 154
f 144 153 154 145
f 184 194 193 182
f 238 246 237
f 272 234 232 271
f 236 237 235 234
f 204 195 186
f 134 143 144 135
f 143 152 153 144
f 204 203 195
f 237 246 245 235
f 273 236 234 272
f 238 237 236
f 185 184 182 183
f 135 144 145 136
f 154 163 146
f 195 203 202 194
f 235 245 244 233
f 264 273 272 263
f 219 185 183 218
f 187 186 184 185
f 136 145 146
f 161 169 170 162
f 204 220 212
f 255 264 263 254
f 234 235 233 232
f 186 195 194 184
f 145 154 146
f 152 161 162 153
f 204 212 203
f 246 255 254 245
f 238 236 273
f 204 187 220
f 169 125 126 170
f 126 135 136 127
f 163 171 146
f 203 212 211 202
f 245 254 253 244
f 238 273 264
f 211 219 218 210
f 170 126 127 171
f 127 136 146
f 162 170 171 163
f 202 211 210 201
f 238 264 255
f 254 263 262 253
f 212 220 219 211
f 171 127 146
f 125 134 135 126
f 204 186 187
f 220 187 185 219
f 263 272 271 262
g engout
# usemtl black
f 251 260 259 250
f 209 217 216 208
f 157 165 166 158
f 132 141 142 133
f 179 178 176 177
f 215 177 175 214
f 270 230 228 269
f 227 241 240 225
f 191 199 198 190
f 150 159 160 151
f 131 140 141 132
f 177 176 174 175
f 230 231 229 228
f 269 228 226 268
f 229 242 241 227
f 192 200 199 191
f 139 148 149 140
f 130 139 140 131
f 180 192 191 178
f 228 229 227 226
f 268 226 224 267
f 231 243 242 229
f 176 190 189 174
f 140 149 150 141
f 149 158 159 150
f 190 198 197 189
f 243 252 251 242
f 259 268 267 258
f 216 179 177 215
f 181 180 178 179
f 121 130 131 122
f 167 123 124 168
f 208 216 215 207
f 250 259 258 249
f 252 261 260 251
f 198 207 206 197
f 158 166 167 159
f 123 132 133 124
f 166 122 123 167
f 207 215 214 206
f 261 270 269 260
f 241 250 249 240
f 199 208 207 198
f 159 167 168 160
f 122 131 132 123
f 165 121 122 166
f 217 181 179 216
f 260 269 268 259
f 242 251 250 241
f 200 209 208 199
f 148 157 158 149
f 141 150 151 142
f 178 191 190 176
f 226 227 225 224
g engmount
# usemtl brass
s 11
f 225 240 239 222
f 164 120 121 165
f 128 137 138 129
f 196 205 289 290
f 265 221 285 266
f 206 214 213 205
f 138 147 148 139
f 174 189 188 172
f 249 258 256 247
f 221 222 223 285
f 155 277 164 156
f 274 155 156 147
f 213 173 281 276
f 258 267 265 256
f 189 197 196 188
f 120 129 130 121
f 173 172 279 281
f 239 247 248 286
f 205 213 276 289
f 137 274 147 138
f 156 164 165 157
f 224 225 222 221
f 247 256 257 248
f 172 188 278 279
f 280 128 129 120
f 188 196 290 278
f 256 265 266 257
f 214 175 173 213
f 147 156 157 148
f 175 174 172 173
f 240 249 247 239
f 222 239 286 223
f 277 280 120 164
f 129 138 139 130
f 197 206 205 196
f 267 224 221 265
g engrim
# usemtl dkdkgrey
s off
f 233 244 243 231
f 124 133 134 125
f 262 271 270 261
f 142 151 152 143
f 253 262 261 252
f 151 160 161 152
f 244 253 252 243
f 160 168 169 161
f 201 210 209 200
f 271 232 230 270
f 133 142 143 134
f 232 233 231 230
f 183 182 180 181
f 218 183 181 217
f 182 193 192 180
f 210 218 217 209
f 193 201 200 192
f 168 124 125 169
# 393 elements

4095
data/models/skyscraper.obj Normal file

File diff suppressed because it is too large Load diff

4393
data/models/slot_machine.obj Normal file

File diff suppressed because it is too large Load diff

82
data/models/superman.mtl Normal file
View file

@ -0,0 +1,82 @@
# Blender3D MTL File:
# Material Count: 8
newmtl log1.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.320000 0.200784 0.379608
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
newmtl _DimGray_.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.329412 0.329412 0.329412
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
newmtl belt1.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.712157 0.727843 0.147451
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
newmtl blue1.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.021961 0.392157 0.762353
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
newmtl hairrrr1.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.040784 0.094118 0.090980
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
newmtl red1.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.652549 0.003138 0.150588
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
newmtl _Charcoal_.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.109804 0.109804 0.109804
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2
newmtl body1.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.693334 0.401569 0.272941
Ks 0.165000 0.165000 0.165000
Ni 1.000000
d 1.000000
illum 2

8755
data/models/superman.obj Normal file

File diff suppressed because it is too large Load diff

BIN
data/models/superman.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

960
data/models/vp.mtl Normal file
View file

@ -0,0 +1,960 @@
newmtl white
Ka 0.4000 0.4000 0.4000
Kd 1.0000 1.0000 1.0000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl red
Ka 0.4449 0.0000 0.0000
Kd 0.7714 0.0000 0.0000
Ks 0.8857 0.0000 0.0000
illum 2
Ns 136.4300
newmtl blue_pure
Ka 0.0000 0.0000 0.5000
Kd 0.0000 0.0000 1.0000
Ks 0.0000 0.0000 0.5000
illum 2
Ns 65.8900
newmtl lime
Ka 0.0000 0.5000 0.0000
Kd 0.0000 1.0000 0.0000
Ks 0.0000 0.5000 0.0000
illum 2
Ns 65.8900
newmtl green
Ka 0.0000 0.2500 0.0000
Kd 0.0000 0.2500 0.0000
Ks 0.0000 0.2500 0.0000
illum 2
Ns 65.8900
newmtl yellow
Ka 1.0000 0.6667 0.0000
Kd 1.0000 0.6667 0.0000
Ks 1.0000 0.6667 0.0000
illum 2
Ns 65.8900
newmtl purple
Ka 0.5000 0.0000 1.0000
Kd 0.5000 0.0000 1.0000
Ks 0.5000 0.0000 1.0000
illum 2
Ns 65.8900
newmtl orange
Ka 1.0000 0.1667 0.0000
Kd 1.0000 0.1667 0.0000
Ks 1.0000 0.1667 0.0000
illum 2
Ns 65.8900
newmtl grey
Ka 0.5000 0.5000 0.5000
Kd 0.1837 0.1837 0.1837
Ks 0.5000 0.5000 0.5000
illum 2
Ns 65.8900
newmtl rubber
Ka 0.0000 0.0000 0.0000
Kd 0.0100 0.0100 0.0100
Ks 0.1000 0.1000 0.1000
illum 2
Ns 65.8900
newmtl flaqua
Ka 0.0000 0.4000 0.4000
Kd 0.0000 0.5000 0.5000
illum 1
newmtl flblack
Ka 0.0000 0.0000 0.0000
Kd 0.0041 0.0041 0.0041
illum 1
newmtl flblue_pure
Ka 0.0000 0.0000 0.5592
Kd 0.0000 0.0000 0.7102
illum 1
newmtl flgrey
Ka 0.2163 0.2163 0.2163
Kd 0.5000 0.5000 0.5000
illum 1
newmtl fllime
Ka 0.0000 0.3673 0.0000
Kd 0.0000 1.0000 0.0000
illum 1
newmtl florange
Ka 0.6857 0.1143 0.0000
Kd 1.0000 0.1667 0.0000
illum 1
newmtl flpurple
Ka 0.2368 0.0000 0.4735
Kd 0.3755 0.0000 0.7510
illum 1
newmtl flred
Ka 0.4000 0.0000 0.0000
Kd 1.0000 0.0000 0.0000
illum 1
newmtl flyellow
Ka 0.7388 0.4925 0.0000
Kd 1.0000 0.6667 0.0000
illum 1
newmtl pink
Ka 0.9469 0.0078 0.2845
Kd 0.9878 0.1695 0.6702
Ks 0.7429 0.2972 0.2972
illum 2
Ns 106.2000
newmtl flbrown
Ka 0.0571 0.0066 0.0011
Kd 0.1102 0.0120 0.0013
illum 1
newmtl brown
Ka 0.1020 0.0185 0.0013
Kd 0.0857 0.0147 0.0000
Ks 0.1633 0.0240 0.0000
illum 2
Ns 65.8900
newmtl glass
Ka 1.0000 1.0000 1.0000
Kd 0.5020 0.5020 0.5020
Ks 1.0000 1.0000 1.0000
illum 2
Ns 192.2500
newmtl flesh
Ka 0.4612 0.3638 0.2993
Kd 0.5265 0.4127 0.3374
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl aqua
Ka 0.0000 0.4000 0.4000
Kd 0.0000 0.5000 0.5000
Ks 0.5673 0.5673 0.5673
illum 2
Ns 60.0000
newmtl black
Ka 0.0000 0.0000 0.0000
Kd 0.0020 0.0020 0.0020
Ks 0.5184 0.5184 0.5184
illum 2
Ns 157.3600
newmtl silver
Ka 0.9551 0.9551 0.9551
Kd 0.6163 0.6163 0.6163
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl dkblue_pure
Ka 0.0000 0.0000 0.0449
Kd 0.0000 0.0000 0.1347
Ks 0.0000 0.0000 0.5673
illum 2
Ns 65.8900
newmtl fldkblue_pure
Ka 0.0000 0.0000 0.0449
Kd 0.0000 0.0000 0.1347
illum 1
newmtl dkgreen
Ka 0.0000 0.0122 0.0000
Kd 0.0058 0.0245 0.0000
Ks 0.0000 0.0490 0.0000
illum 2
Ns 60.0000
newmtl dkgrey
Ka 0.4000 0.4000 0.4000
Kd 0.0245 0.0245 0.0245
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl ltbrown
Ka 0.1306 0.0538 0.0250
Kd 0.2776 0.1143 0.0531
Ks 0.3000 0.1235 0.0574
illum 2
Ns 60.0000
newmtl fldkgreen
Ka 0.0000 0.0122 0.0000
Kd 0.0058 0.0245 0.0000
illum 1
newmtl flltbrown
Ka 0.1306 0.0538 0.0250
Kd 0.2776 0.1143 0.0531
illum 1
newmtl tan
Ka 0.4000 0.3121 0.1202
Kd 0.6612 0.5221 0.2186
Ks 0.5020 0.4118 0.2152
illum 2
Ns 60.0000
newmtl fltan
Ka 0.4000 0.3121 0.1202
Kd 0.6612 0.4567 0.1295
illum 1
newmtl brzskin
Ka 0.4408 0.2694 0.1592
Kd 0.3796 0.2898 0.2122
Ks 0.3000 0.3000 0.3000
illum 2
Ns 25.0000
newmtl lips
Ka 0.4408 0.2694 0.1592
Kd 0.9265 0.2612 0.2898
Ks 0.3000 0.3000 0.3000
illum 2
Ns 25.0000
newmtl redorange
Ka 0.2653 0.0160 0.0097
Kd 0.7551 0.0327 0.0146
Ks 0.7510 0.0816 0.0490
illum 2
Ns 132.5600
newmtl blutan
Ka 0.4408 0.2694 0.1592
Kd 0.0776 0.2571 0.2041
Ks 0.1467 0.1469 0.0965
illum 2
Ns 25.0000
newmtl bluteal
Ka 0.0041 0.1123 0.1224
Kd 0.0776 0.2571 0.2041
Ks 0.1467 0.1469 0.0965
illum 2
Ns 25.0000
newmtl pinktan
Ka 0.4408 0.2694 0.1592
Kd 0.6857 0.2571 0.2163
Ks 0.1467 0.1469 0.0965
illum 2
Ns 25.0000
newmtl areola3
Ka 0.8122 0.3510 0.1551
Kd 0.5469 0.0749 0.0749
Ks 0.8490 0.2898 0.3184
illum 2
Ns 20.9300
newmtl brnhair
Ka 0.0612 0.0174 0.0066
Kd 0.0898 0.0302 0.0110
Ks 0.1306 0.0819 0.0352
illum 2
Ns 60.4700
newmtl blondhair
Ka 0.4449 0.2632 0.0509
Kd 0.5714 0.3283 0.0443
Ks 0.7755 0.4602 0.0918
illum 2
Ns 4.6500
newmtl flblonde
Ka 0.4449 0.2632 0.0509
Kd 0.5714 0.3283 0.0443
illum 1
newmtl yelloworng
Ka 0.5837 0.1715 0.0000
Kd 0.8857 0.2490 0.0000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl bone
Ka 0.3633 0.2179 0.1142
Kd 0.9000 0.6229 0.2278
Ks 0.4612 0.4193 0.2673
illum 2
Ns 200.0000
#newmtl bone
newmtl teeth
Ka 0.6408 0.5554 0.3845
Kd 0.9837 0.7959 0.4694
illum 1
newmtl brass
Ka 0.2490 0.1102 0.0000
Kd 0.4776 0.1959 0.0000
Ks 0.5796 0.5796 0.5796
illum 2
Ns 134.8800
newmtl china
Kd 1.0000 1.0000 1.0000
illum 0
map_Kd china.tif
newmtl dkred
Ka 0.0939 0.0000 0.0000
Kd 0.2286 0.0000 0.0000
Ks 0.2490 0.0000 0.0000
illum 2
Ns 60.0000
newmtl taupe
Ka 0.1061 0.0709 0.0637
Kd 0.2041 0.1227 0.1058
Ks 0.3000 0.3000 0.3000
illum 2
Ns 84.5000
newmtl dkteal
Ka 0.0000 0.0245 0.0163
Kd 0.0000 0.0653 0.0449
Ks 0.3000 0.3000 0.3000
illum 2
Ns 55.0400
newmtl dkdkgrey
Ka 0.0000 0.0000 0.0000
Kd 0.0122 0.0122 0.0122
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl dkblue
Ka 0.0000 0.0029 0.0408
Kd 0.0000 0.0041 0.0571
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl gold
Ka 0.5265 0.2735 0.0122
Kd 1.0000 0.5184 0.0286
Ks 0.3000 0.3000 0.3000
illum 2
Ns 123.2600
newmtl redbrick
Ka 0.1102 0.0000 0.0000
Kd 0.4939 0.1469 0.0766
illum 1
newmtl flmustard
Ka 0.4490 0.2653 0.0000
Kd 0.7959 0.4082 0.0694
illum 1
newmtl flpinegreen
Ka 0.0367 0.0612 0.0204
Kd 0.1061 0.2163 0.0857
illum 1
newmtl fldkred
Ka 0.0939 0.0000 0.0000
Kd 0.2286 0.0082 0.0082
illum 1
newmtl fldkgreen2
Ka 0.0025 0.0122 0.0014
Kd 0.0245 0.0694 0.0041
illum 1
newmtl flmintgreen
Ka 0.0408 0.1429 0.0571
Kd 0.1306 0.2898 0.1673
illum 1
newmtl olivegreen
Ka 0.0167 0.0245 0.0000
Kd 0.0250 0.0367 0.0000
Ks 0.2257 0.2776 0.1167
illum 2
Ns 97.6700
newmtl skin
Ka 0.2286 0.0187 0.0187
Kd 0.1102 0.0328 0.0139
Ks 0.3000 0.3000 0.3000
illum 2
Ns 17.8300
newmtl redbrown
Ka 0.1469 0.0031 0.0000
Kd 0.2816 0.0060 0.0000
Ks 0.3714 0.3714 0.3714
illum 2
Ns 141.0900
newmtl deepgreen
Ka 0.0000 0.0050 0.0000
Kd 0.0000 0.0204 0.0050
Ks 0.3000 0.3000 0.3000
illum 2
Ns 113.1800
newmtl flltolivegreen
Ka 0.0167 0.0245 0.0000
Kd 0.0393 0.0531 0.0100
illum 1
newmtl faceim
Ka 0.0000 0.0000 0.0000
Kd 1.0000 1.0000 1.0000
Ks 0.0000 0.0000 0.0000
illum 2
Ns 60.0000
map_Kd richmap.rgb
newmtl faceimx
Ka 0.0000 0.0000 0.0000
Kd 1.0000 0.7306 0.7429
Ks 0.0000 0.0000 0.0000
illum 2
Ns 0.0000
map_Kd richmap.rgb
newmtl jetflame
Ka 0.7714 0.1469 0.0000
Kd 0.9510 0.4939 0.0980
Ks 0.8531 0.4041 0.0000
illum 2
Ns 132.5600
newmtl brownskn
Ka 0.0122 0.0041 0.0000
Kd 0.0204 0.0082 0.0000
Ks 0.0735 0.0508 0.0321
illum 2
Ns 20.1600
newmtl greenskn
Ka 0.0816 0.0449 0.0000
Kd 0.0000 0.0735 0.0000
Ks 0.0490 0.1224 0.0898
illum 3
Ns 46.5100
sharpness 146.5100
#bump -bm 2.000 -o -0.870 -0.260 0.870 -s -0.420 2.770 0.500 -t 0.010 0.500 0.490 /liberty/people/vp/Brian/Maps/ashwood.tga
#refl -type sphere /liberty/people/vp/Brian/Maps/evrgreen.tga
newmtl ltgrey
Ka 0.5000 0.5000 0.5000
Kd 0.3837 0.3837 0.3837
Ks 0.5000 0.5000 0.5000
illum 2
Ns 65.8900
newmtl bronze
Ka 0.0449 0.0204 0.0000
Kd 0.0653 0.0367 0.0122
Ks 0.0776 0.0408 0.0000
illum 3
Ns 137.2100
sharpness 125.5800
newmtl bone1
Ka 0.6408 0.5554 0.3845
Kd 0.9837 0.7959 0.4694
illum 1
newmtl flwhite1
Ka 0.9306 0.9306 0.9306
Kd 1.0000 1.0000 1.0000
illum 1
newmtl flwhite
Ka 0.1551 0.1471 0.1310
Kd 0.9837 0.9309 0.8392
Ks 0.8082 0.7290 0.5708
illum 2
Ns 200.0000
newmtl shadow
Kd 0.0350 0.0248 0.0194
illum 0
d 0.7500
newmtl fldkolivegreen
Ka 0.0056 0.0082 0.0000
Kd 0.0151 0.0204 0.0038
illum 1
newmtl fldkdkgrey
Ka 0.0000 0.0000 0.0000
Kd 0.0122 0.0122 0.0122
illum 1
newmtl lcdgreen
Ka 0.4000 0.4000 0.4000
Kd 0.5878 1.0000 0.5061
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl brownlips
Ka 0.1143 0.0694 0.0245
Kd 0.1429 0.0653 0.0408
Ks 0.3000 0.3000 0.3000
illum 2
Ns 25.0000
newmtl muscle
Ka 0.2122 0.0077 0.0154
Kd 0.4204 0.0721 0.0856
Ks 0.1184 0.1184 0.1184
illum 2
Ns 25.5800
newmtl flltgrey
Ka 0.5000 0.5000 0.5000
Kd 0.3837 0.3837 0.3837
illum 1
newmtl offwhite.warm
Ka 0.5184 0.4501 0.3703
Kd 0.8367 0.6898 0.4490
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl offwhite.cool
Ka 0.5184 0.4501 0.3703
Kd 0.8367 0.6812 0.5703
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl test2
Ka 1.0000 1.0000 1.0000
Kd 0.3336 0.6286 0.0000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 31.0100
map_Kd -mm -0.270 0.500 skincol1.tif
newmtl test3
Ka 1.0000 1.0000 1.0000
Kd 0.3336 0.6286 0.0000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 31.0100
map_Kd -mm -0.270 0.500 skincol1.tga
newmtl yellowbrt
Ka 0.4000 0.4000 0.4000
Kd 1.0000 0.7837 0.0000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl chappie
Ka 0.4000 0.4000 0.4000
Kd 0.5837 0.1796 0.0367
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl mess
Ka 1.0000 0.2000 0.2000
Kd 0.6694 0.0000 0.0000
Ks 0.0000 0.1592 0.1878
illum 2
Ns 60.0000
map_Ks marble5.txc
map_Ns -mm 1.680 1.000 tile.cxs
newmtl steg
Ka 1.0000 1.0000 1.0000
Kd 1.0000 1.0000 1.0000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
map_Ka steg.sgi
map_Kd steg.sgi
newmtl deleteme
Ka 0.1061 0.1061 0.1061
Kd 1.0000 1.0000 1.0000
Ks 0.0898 0.0898 0.0826
illum 2
Ns 30.0000
map_Ka helena1.tga
map_Kd helena1.tga
newmtl fox
Kd 0.9429 0.8731 0.7736
illum 0
map_Kd fox.tga
newmtl dkgreen_bm
Ka 0.0000 0.0122 0.0000
Kd 0.0058 0.0245 0.0000
Ks 0.0000 0.0490 0.0000
illum 2
Ns 60.0000
bump lime.tex
newmtl archwhite
Ka 0.2816 0.2816 0.2816
Kd 0.9959 0.9959 0.9959
illum 1
newmtl archwhite2
Ka 0.2816 0.2816 0.2816
Kd 0.8408 0.8408 0.8408
illum 1
newmtl lighttan
Ka 0.0980 0.0536 0.0220
Kd 0.7020 0.4210 0.2206
Ks 0.8286 0.8057 0.5851
illum 2
Ns 177.5200
newmtl lighttan2
Ka 0.0980 0.0492 0.0144
Kd 0.3143 0.1870 0.0962
Ks 0.8286 0.8057 0.5851
illum 2
Ns 177.5200
newmtl lighttan3
Ka 0.0980 0.0492 0.0144
Kd 0.1796 0.0829 0.0139
Ks 0.8286 0.8057 0.5851
illum 2
Ns 177.5200
newmtl lightyellow
Ka 0.0980 0.0492 0.0144
Kd 0.6122 0.4552 0.2074
Ks 0.8286 0.8057 0.5851
illum 2
Ns 177.5200
newmtl lighttannew
Ka 0.0980 0.0492 0.0144
Kd 0.7878 0.6070 0.3216
Ks 0.8286 0.8057 0.5851
illum 2
Ns 177.5200
newmtl buctx
Kd 0.8653 0.8653 0.8653
illum 0
map_Kd buctx.tga
newmtl default
Ka 0.4000 0.4000 0.4000
Kd 0.7102 0.7020 0.6531
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
newmtl ship
Ka 0.0000 0.0000 0.0000
Kd 1.0000 1.0000 1.0000
Ks 0.1143 0.1143 0.1143
illum 2
Ns 60.0000
map_Kd eshtex1.tif
newmtl ship2
Ka 0.0000 0.0000 0.0000
Kd 1.0000 1.0000 1.0000
Ks 0.1143 0.1143 0.1143
illum 2
Ns 60.0000
newmtl nwing.tex
Ka 0.0013 0.0204 0.0015
Kd 1.0000 1.0000 1.0000
Ks 0.1347 0.1347 0.1347
illum 2
Ns 119.3800
map_Kd /usr/projects/emil/ship/ewitex.tif
newmtl dkpurple
Ka 0.0082 0.0000 0.0163
Kd 0.0245 0.0000 0.0490
Ks 0.1266 0.0000 0.2531
illum 2
Ns 65.8900
newmtl dkorange
Ka 0.4041 0.0123 0.0000
Kd 0.7143 0.0217 0.0000
Ks 0.4857 0.0175 0.0000
illum 2
Ns 65.8900
newmtl mintgrn
Ka 0.0101 0.1959 0.0335
Kd 0.0245 0.4776 0.0816
Ks 0.0245 0.4776 0.0816
illum 2
Ns 65.8900
newmtl fgreen
Ka 0.0000 0.0449 0.0000
Kd 0.0000 0.0449 0.0004
Ks 0.0062 0.0694 0.0000
illum 2
Ns 106.2000
newmtl slvr1
Ka 0.9551 0.9551 0.9551
Kd 0.6163 0.6163 0.6163
Ks 0.3000 0.3000 0.3000
illum 3
Ns 60.0000
sharpness 60.0000
newmtl slvrscuff1
Ka 0.9551 0.9551 0.9551
Kd 0.6163 0.6163 0.6163
Ks 0.3000 0.3000 0.3000
illum 3
Ns 60.0000
sharpness 60.0000
bump 512.txb
newmtl slvrscuff2
Ka 0.9551 0.9551 0.9551
Kd 0.6163 0.6163 0.6163
Ks 0.3000 0.3000 0.3000
illum 3
Ns 60.0000
sharpness 60.0000
bump bulbs.tex
newmtl slvrscuff3
Ka 0.9551 0.9551 0.9551
Kd 0.6163 0.6163 0.6163
Ks 0.3000 0.3000 0.3000
illum 3
Ns 60.0000
sharpness 60.0000
bump football.mpb
newmtl glassblutint
Ka 0.4000 0.4000 0.4000
Kd 0.5551 0.8000 0.7730
Ks 0.7969 0.9714 0.9223
illum 4
d 0.3300
Ns 60.0000
sharpness 60.0000
newmtl candicel.mtl
Ka 0.4000 0.4000 0.4000
Kd 0.8000 0.8000 0.8000
Ks 0.6970 0.7673 0.6577
illum 2
d 0.9300
Ns 146.5100
map_Kd -mm -0.100 1.000 candicel.tga
newmtl bflesh
Ka 0.0041 0.0041 0.0041
Kd 0.0041 0.0011 0.0000
Ks 0.0531 0.0460 0.0153
illum 2
Ns 20.1600
newmtl utah
Ka 1.0000 1.0000 1.0000
Kd 1.0000 1.0000 1.0000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000
map_Kd /tmp_mnt/tools/data/sofa/bill/broker/imagewar/1atextue/ut24b.sgi
bump /tmp_mnt/tools/data/sofa/bill/broker/imagewar/1atextue/ut24b.tga
newmtl meh
Ka 0.4000 0.4000 0.4000
Kd 0.5551 0.8000 0.7730
Ks 0.7969 0.9714 0.9223
illum 4
d 0.7500
Ns 183.7200
sharpness 60.0000
newmtl navyblu
Ka 0.4000 0.4000 0.4000
Kd 0.1100 0.1000 0.6800
Ks 0.3000 0.3000 0.3000
illum 2
Ns 20.0000
newmtl testchrm
Ka 0.5101 0.5020 1.0000
Kd 0.6449 0.6826 1.0000
Ks 0.3000 0.3000 0.3000
illum 3
Ns 197.6700
sharpness 60.0000
newmtl iris
Ka 0.4000 0.4000 0.4000
Kd 0.8000 0.8000 0.8000
Ks 0.3000 0.3000 0.3000
illum 2
Ns 60.0000

BIN
data/models/wizard.aoi Normal file

Binary file not shown.

21
data/models/wizard.mtl Normal file
View file

@ -0,0 +1,21 @@
#Produced by Art of Illusion 2.8.1, Thu Apr 01 15:01:08 PDT 2010
newmtl hat
Kd 0.67 0.2948 0.2948
Ks 0 0 0
Ka 0.67 0.2948 0.2948
illum 1
newmtl coat
Kd 0.49834 0.3944 0.58
Ks 0 0 0
Ka 0.49834 0.3944 0.58
illum 1
newmtl skin
Kd 0.87 0.79309 0.7221
Ks 0 0 0
Ka 0.87 0.79309 0.7221
illum 1
newmtl staff
Kd 0.49 0.31438 0.2156
Ks 0 0 0
Ka 0.49 0.31438 0.2156
illum 1

View file

@ -0,0 +1,21 @@
#Produced by Art of Illusion 2.8.1, Thu Apr 01 15:00:48 PDT 2010
newmtl hat
Kd 0.67 0.2948 0.2948
Ks 0 0 0
Ka 0.67 0.2948 0.2948
illum 1
newmtl coat
Kd 0.49834 0.3944 0.58
Ks 0 0 0
Ka 0.49834 0.3944 0.58
illum 1
newmtl skin
Kd 0.87 0.79309 0.7221
Ks 0 0 0
Ka 0.87 0.79309 0.7221
illum 1
newmtl staff
Kd 0.49 0.31438 0.2156
Ks 0 0 0
Ka 0.49 0.31438 0.2156
illum 1

4568
data/models/wizard.obj Normal file

File diff suppressed because it is too large Load diff

BIN
data/video/calib.avi Normal file

Binary file not shown.

2380
doc/Doxyfile.in Normal file

File diff suppressed because it is too large Load diff

BIN
doc/OCVtutorials.pdf Normal file

Binary file not shown.

26
doc/directories.doxygen Executable file
View file

@ -0,0 +1,26 @@
/**
* @dir doc
* @brief DOxygen doc
*/
/**
* @dir data
* @brief data for unittests, image output, ...
*/
/**
* @dir tools
* @brief scons compilation tools
*/
/**
* @dir library
* @brief libraries for the MOOV3D project
*/
/**
* @dir moov3d
* @brief Base directory of the project. All includes begins here.
*/

144
doc/index.doxygen Executable file
View file

@ -0,0 +1,144 @@
/** @mainpage TP Interfaces Realité Augmentée
*
* @section intro Introduction
*
*The objective of these TP sessions is to build a simple augmented reality application using OpenCV for the camera tracking part and OpenGL for the rendering. The exercises that will be proposed are meant to gradually introduce you to the OpenCV libraries and build all the function that are needed for a camera tracker in an incremental way, so that you will be able to test and debug each function, before plugging all together in the camera tracker class.
The main idea is to use a chessboard as a marker and render on top of that the augmented reality. The final application should render an OpenGL teapot on top of the chessboard. We will get there step by step, first detecting the chessboard, then create some basic rendering in OpenCV, and at last plugging everything in the OpenGL pipeline.
*
*
* @section org Code Organization
*
* The directory is organized as follows:
*
* - ``doc`` contains a pdf copy of this text, a pdf copy of the reduced opencv tutorials, a pdf copy of the full, original opencv tutorial, and a pdf copy of the API reference manual of opencv (ie the copy of the online documentation).
*
* - ``data`` contains some images, videos and other data that will be used through the TP.
*
* - ``src`` contains the source files that you have to modify and complete; they are organize in directories:
*
* - ``tutorials`` contains the code used in the tutorials, in case you need to try it;
* - ``tp`` contains the files that you need to modify and complete through all the sessions of the TP.
*
* - ``3dparty`` this directory contains a library that will be used at the end of the TP. You don't have to worry (or do anything...) about this directory.
*
* @section indetails In details
* - @subpage installation
* - @subpage utilisation
* - @subpage history
*
*
* @section team Team
* - Simone Gasparini
* - Sylvie Chambon
*/
/** @page installation Installation
*
*
* @section install_linux Installation on Linux
*
### Dependencies
The project depends on:
- OpenCV
- OpenGL
- GLM ([webpage](http://devernay.free.fr/hacks/glm/)) which provides a more complete interface to the OBJ format (i.e. it manages textures, materials etc.).
If at any stage you get an error about missing ``Xi`` and ``Xmu`` library, you need to install them. In linux you can do
sudo apt-get install libxi-dev libxmu-dev.
### Setting up and building:
OpenCV and OpenGL are normally already installed on your machine. In case you may have a look at the next section to install OpenCV on your own machine. As for GLM, it comes with the project, so it will be compiled and built the first time it is needed.
In order to setting up the project, from the root of the project do:
mkdir build
cd build
cmake ..
Then each application can be compiled by simply doing a
make <filename_without_extension>
If you run
make help
a list of all possible targets is displayed. Finally, running
make clean
will delete all the executable and the compilation objects.
In case you want to try the code on a different machine, you need to first install the OpenCV libraries (from (here)[http://opencv.org/downloads.html]) and then do
cmake .. -DOpenCV_DIR=path/to/OpenCVConfig.cmake
in order to specify the directory where you build them. More in general, you need to provide the path to the file ``OpenCVConfig.cmake``, which you can find e.g. with
locate OpenCVConfig.cmake
from your shell.
In order to generate the documentation you need have doxygen and graphviz installed. On linux:
sudo apt-get install doxygen graphviz.
On Mac OSX with homebrew
brew install doxygen graphviz.
Then a
On Mac OSX with homebrew
make doc
will generate the documentation in the ``doc`` folder of your build.
#### Installing OpenCV
You can download the code from [here](http://opencv.org/downloads.html) or clone the [github repository](https://github.com/itseez/opencv)
Create a `build` directory where to build the library. It also advisable to set an non-system install directory, so that it will be easier to set up the environment later:
mkdir build && cd build && cmake .. -DCMAKE_INSTALL_PREFIX=`pwd`/install
make install -j n
You can even run ```ccmake ..``` to set up other options (eg. CUDA support).
*/
/** @page utilisation Utilisation
*
* Ech application can be compiled by simply doing a
make <filename_without_extension>
The executable will be in the ``bin`` folder of your build. If you run
make help
a list of all possible targets is displayed.
*
Remember to set the ``LD_LIBRARY_PATH`` to allow your application to access the project libraries:
export $LD_LIBRARY_PATH=/home/<yourhome>/<path/to/code>/3dparty/glm/build/lib:$LD_LIBRARY_PATH
Also you may want to add the path to OpenCV if they are not installed in the system.
*
*/
/** @page history history
* - October 2013 : First Version
* - October 2014 : First Version revised
*/

BIN
doc/opencv2refman.pdf Normal file

Binary file not shown.

BIN
doc/opencv_tutorials.pdf Normal file

Binary file not shown.

BIN
doc/sujetTP.pdf Normal file

Binary file not shown.

BIN
src/.DS_Store vendored Normal file

Binary file not shown.

3
src/CMakeLists.txt Normal file
View file

@ -0,0 +1,3 @@
add_subdirectory(tp)
add_subdirectory(ogl)
add_subdirectory(tutorials)

4
src/ogl/CMakeLists.txt Normal file
View file

@ -0,0 +1,4 @@
#include_directories( ${LIBGLM_INCLUDE_DIRS})
#add_executable( openglObj openglObj.cpp )
#target_link_libraries( openglObj ${LIBGLM_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} $)

523
src/ogl/openglObj.cpp Normal file
View file

@ -0,0 +1,523 @@
/*
*
* Demonstrates how to load and display an Wavefront OBJ file.
* Using triangles and normals as static object. No texture mapping.
*
* OBJ files must be triangulated!!!
* Non triangulated objects wont work!
* You can use Blender to triangulate
*
*/
//#include <windows.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
// #include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
// #include <GL/glu.h>
#include <GL/freeglut.h>
#endif
#include <glm.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>
#define KEY_ESCAPE 27
using namespace std;
/************************************************************************
Window
************************************************************************/
typedef struct
{
int width;
int height;
char* title;
float field_of_view_angle;
float z_near;
float z_far;
} glutWindow;
/***************************************************************************
OBJ Loading
***************************************************************************/
class Model_OBJ
{
public:
Model_OBJ( );
float* calculateNormal( float* coord1, float* coord2, float* coord3 );
int Load( char *filename ); // Loads the model
void Draw( ); // Draws the model on the screen
void Release( ); // Release the model
float* normals; // Stores the normals
float* Faces_Triangles; // Stores the triangles
float* vertexBuffer; // Stores the points which make the object
long TotalConnectedPoints; // Stores the total number of connected verteces
long TotalConnectedTriangles; // Stores the total number of connected triangles
};
#define POINTS_PER_VERTEX 3
#define TOTAL_FLOATS_IN_TRIANGLE 9
using namespace std;
Model_OBJ::Model_OBJ( )
{
this->TotalConnectedTriangles = 0;
this->TotalConnectedPoints = 0;
}
float* Model_OBJ::calculateNormal( float *coord1, float *coord2, float *coord3 )
{
/* calculate Vector1 and Vector2 */
float va[3], vb[3], vr[3], val;
va[0] = coord1[0] - coord2[0];
va[1] = coord1[1] - coord2[1];
va[2] = coord1[2] - coord2[2];
vb[0] = coord1[0] - coord3[0];
vb[1] = coord1[1] - coord3[1];
vb[2] = coord1[2] - coord3[2];
/* cross product */
vr[0] = va[1] * vb[2] - vb[1] * va[2];
vr[1] = vb[0] * va[2] - va[0] * vb[2];
vr[2] = va[0] * vb[1] - vb[0] * va[1];
/* normalization factor */
val = sqrt( vr[0] * vr[0] + vr[1] * vr[1] + vr[2] * vr[2] );
float norm[3];
norm[0] = vr[0] / val;
norm[1] = vr[1] / val;
norm[2] = vr[2] / val;
return norm;
}
int Model_OBJ::Load( char* filename )
{
string line;
ifstream objFile( filename );
if( objFile.is_open( ) ) // If obj file is open, continue
{
objFile.seekg( 0, ios::end ); // Go to end of the file,
long fileSize = objFile.tellg( ); // get file size
objFile.seekg( 0, ios::beg ); // we'll use this to register memory for our 3d model
vertexBuffer = ( float* ) malloc( fileSize ); // Allocate memory for the verteces
Faces_Triangles = ( float* ) malloc( fileSize * sizeof (float ) ); // Allocate memory for the triangles
normals = ( float* ) malloc( fileSize * sizeof (float ) ); // Allocate memory for the normals
int triangle_index = 0; // Set triangle index to zero
int normal_index = 0; // Set normal index to zero
while( !objFile.eof( ) ) // Start reading file data
{
getline( objFile, line ); // Get line from file
if( line.c_str( )[0] == 'v' ) // The first character is a v: on this line is a vertex stored.
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf
sscanf( line.c_str( ), "%f %f %f ", // Read floats from the line: v X Y Z
&vertexBuffer[TotalConnectedPoints],
&vertexBuffer[TotalConnectedPoints + 1],
&vertexBuffer[TotalConnectedPoints + 2] );
TotalConnectedPoints += POINTS_PER_VERTEX; // Add 3 to the total connected points
}
else if( line.c_str( )[0] == 'f' ) // The first character is an 'f': on this line is a point stored
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf
int vertexNumber[4] = {0, 0, 0};
if( ( line.find( "//" ) == std::string::npos ) && ( line.find( "/" ) == std::string::npos ) )
{
// cout << "reading from a b c" << endl;
sscanf( line.c_str( ), "%i%i%i", // Read integers from the line: f 1 2 3
&vertexNumber[0], // First point of our triangle. This is an
&vertexNumber[1], // pointer to our vertexBuffer list
&vertexNumber[2] ); // each point represents an X,Y,Z.
}
else if( line.find( "//" ) != std::string::npos )
{
// cout << "reading from //" << endl;
int a, b, c;
sscanf( line.c_str( ), "%i//%i %i//%i %i//%i", // Read integers from the line: f 1 2 3
&vertexNumber[0], &a, // First point of our triangle. This is an
&vertexNumber[1], &b, // pointer to our vertexBuffer list
&vertexNumber[2], &c ); // each point represents an X,Y,Z.
// cout << vertexNumber[0] << " " << a << " " << vertexNumber[1] << " " << b << " " << vertexNumber[2] << " " << c << " " << endl;
}
vertexNumber[0] -= 1; // OBJ file starts counting from 1
vertexNumber[1] -= 1; // OBJ file starts counting from 1
vertexNumber[2] -= 1; // OBJ file starts counting from 1
/********************************************************************
* Create triangles (f 1 2 3) from points: (v X Y Z) (v X Y Z) (v X Y Z).
* The vertexBuffer contains all verteces
* The triangles will be created using the verteces we read previously
*/
int tCounter = 0;
for( int i = 0; i < POINTS_PER_VERTEX; i++ )
{
Faces_Triangles[triangle_index + tCounter ] = vertexBuffer[3 * vertexNumber[i] ];
Faces_Triangles[triangle_index + tCounter + 1 ] = vertexBuffer[3 * vertexNumber[i] + 1 ];
Faces_Triangles[triangle_index + tCounter + 2 ] = vertexBuffer[3 * vertexNumber[i] + 2 ];
tCounter += POINTS_PER_VERTEX;
}
/*********************************************************************
* Calculate all normals, used for lighting
*/
float coord1[3] = {Faces_Triangles[triangle_index], Faces_Triangles[triangle_index + 1], Faces_Triangles[triangle_index + 2]};
float coord2[3] = {Faces_Triangles[triangle_index + 3], Faces_Triangles[triangle_index + 4], Faces_Triangles[triangle_index + 5]};
float coord3[3] = {Faces_Triangles[triangle_index + 6], Faces_Triangles[triangle_index + 7], Faces_Triangles[triangle_index + 8]};
float *norm = this->calculateNormal( coord1, coord2, coord3 );
tCounter = 0;
for( int i = 0; i < POINTS_PER_VERTEX; i++ )
{
normals[normal_index + tCounter ] = norm[0];
normals[normal_index + tCounter + 1] = norm[1];
normals[normal_index + tCounter + 2] = norm[2];
tCounter += POINTS_PER_VERTEX;
}
triangle_index += TOTAL_FLOATS_IN_TRIANGLE;
normal_index += TOTAL_FLOATS_IN_TRIANGLE;
TotalConnectedTriangles += TOTAL_FLOATS_IN_TRIANGLE;
}
}
cout << "TotalConnectedTriangles: " << TotalConnectedTriangles << endl;
objFile.close( ); // Close OBJ file
}
else
{
cout << "Unable to open file";
}
return 0;
}
void Model_OBJ::Release( )
{
free( this->Faces_Triangles );
free( this->normals );
free( this->vertexBuffer );
}
void Model_OBJ::Draw( )
{
glEnableClientState( GL_VERTEX_ARRAY ); // Enable vertex arrays
glEnableClientState( GL_NORMAL_ARRAY ); // Enable normal arrays
glVertexPointer( 3, GL_FLOAT, 0, Faces_Triangles ); // Vertex Pointer to triangle array
glNormalPointer( GL_FLOAT, 0, normals ); // Normal pointer to normal array
glDrawArrays( GL_TRIANGLES, 0, TotalConnectedTriangles ); // Draw the triangles
glDisableClientState( GL_VERTEX_ARRAY ); // Disable vertex arrays
glDisableClientState( GL_NORMAL_ARRAY ); // Disable normal arrays
}
/***************************************************************************
* Program code
***************************************************************************/
Model_OBJ obj;
GLMmodel *pmodel = NULL; /* the loaded model */
GLfloat modelDim[3];
float g_rotation;
glutWindow win;
GLuint mode = 0;
int wireframe = 0; /* Draw modes */
int show_axis = 1;
int smooth = 1;
int material = 1;
int textured = 0;
int two_sided = 1;
int lighting = 1;
void DrawModel( void )
{
mode = GLM_NONE; /* reset mode */
if( smooth )
mode = mode | GLM_SMOOTH;
else
mode = mode | GLM_FLAT;
if( two_sided )
mode = mode | GLM_2_SIDED;
if( material )
mode = mode | GLM_MATERIAL;
else
mode = mode | GLM_COLOR;
if( textured && material )
mode = mode | GLM_TEXTURE;
glPushMatrix( );
if( pmodel )
glmDraw( pmodel, mode );
glPopMatrix( );
}
void DrawAxis( float scale )
{
glPushMatrix( );
glDisable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
glScalef( scale, scale, scale );
glBegin( GL_LINES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( .8f, 0.05f, 0.0 );
glVertex3f( 1.0, 0.25f, 0.0 ); /* Letter X */
glVertex3f( 0.8f, .25f, 0.0 );
glVertex3f( 1.0, 0.05f, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 1.0, 0.0, 0.0 ); /* X axis */
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 0.0, 1.0, 0.0 ); /* Y axis */
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 0.0, 0.0, 1.0 ); /* Z axis */
glEnd( );
if( lighting )
glEnable( GL_LIGHTING );
if( lighting )
glEnable( GL_TEXTURE_2D );
glColor3f( 1.0, 1.0, 1.0 );
glPopMatrix( );
}
static void draw_axis( float scale )
{
glPushMatrix( );
glDisable( GL_LIGHTING );
glScalef( scale, scale, scale );
glBegin( GL_LINES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( .8f, 0.05f, 0.0 );
glVertex3f( 1.0, 0.25f, 0.0 ); // Letter X
glVertex3f( 0.8f, .25f, 0.0 );
glVertex3f( 1.0, 0.05f, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 1.0, 0.0, 0.0 ); // X axis
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 0.0, 1.0, 0.0 ); // Y axis
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 0.0, 0.0, 1.0 ); // Z axis
glEnd( );
glEnable( GL_LIGHTING );
glColor3f( 1.0, 1.0, 1.0 );
glPopMatrix( );
}
void display( )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity( );
// gluLookAt( 0, 1, 4, 0, 0, 0, 0, 1, 0 );
glPushMatrix( );
GLfloat gLightPos[] = {100.0, 200.0, 200.0, 0.0};
glEnable( GL_LIGHTING );
glLightfv( GL_LIGHT0, GL_POSITION, gLightPos );
glTranslatef( 0, 0, -1.95 );
glRotatef( g_rotation, 0, 1, 0 );
// glRotatef( 90, 0, 1, 0 );
g_rotation += 0.1;
// draw_axis( 1.0f );
// glScalef( 0.025, 0.025, 0.025 );
if( show_axis )
DrawAxis( 1.0f );
if( wireframe ) /* if Wireframe is checked */
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); /* draw wireframe */
else /* else */
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); /* draw filled polygons */
// glScalef( 0.25, 0.25, 0.25);
glTranslatef( 0, 0.5 * 0.25 * modelDim[1], 0 );
DrawModel( );
// glutSolidTeapot( 15 );
// obj.Draw( );
glPopMatrix( );
glutSwapBuffers( );
}
void initialize( )
{
glMatrixMode( GL_PROJECTION );
glViewport( 0, 0, win.width, win.height );
GLfloat aspect = ( GLfloat ) win.width / win.height;
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
gluPerspective( win.field_of_view_angle, aspect, win.z_near, win.z_far );
glMatrixMode( GL_MODELVIEW );
glShadeModel( GL_SMOOTH );
glClearColor( 0.1f, 0.1f, 0.1f, 0.5f );
glClearDepth( 1.0f );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
GLfloat amb_light[] = {0.9, 0.9, 0.9, 1.0};
GLfloat diffuse[] = {0.6, 0.6, 0.6, 1};
GLfloat specular[] = {0.7, 0.7, 0.3, 1};
GLfloat gLightPos[] = {100.0, 200.0, -200.0, 0.0};
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, amb_light );
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
glLightfv( GL_LIGHT0, GL_POSITION, gLightPos );
GLfloat mat_ambient[] = {0.7, 0.7, 0.7, 1.0};
GLfloat mat_diffuse[] = {0.8, 0.8, 0.8, 1.0};
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat high_shininess[] = {100.0};
glMaterialfv( GL_FRONT, GL_AMBIENT, mat_ambient );
glMaterialfv( GL_FRONT, GL_DIFFUSE, mat_diffuse );
glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );
glMaterialfv( GL_FRONT, GL_SHININESS, high_shininess );
glEnable( GL_LIGHT0 );
glEnable( GL_COLOR_MATERIAL );
glShadeModel( GL_SMOOTH );
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
glDepthFunc( GL_LEQUAL );
glEnable( GL_DEPTH_TEST );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
}
void keyboard( unsigned char key, int x, int y )
{
switch( key )
{
case 'w':
case 'W':
{
wireframe = !wireframe;
break;
}
case 'd':
case 'D':
{
two_sided = !two_sided;
break;
}
case 's':
case 'S':
{
smooth = !smooth;
break;
}
case 'm':
case 'M':
{
material = !material;
if( !material && textured )
textured = 0;
break;
}
case 't':
case 'T':
{
textured = !textured;
if( !material && textured )
material = 1;
break;
}
case KEY_ESCAPE:
exit( 0 );
break;
default:
break;
}
}
int main( int argc, char **argv )
{
// set window values
win.width = 640;
win.height = 480;
win.title = "OpenGL/GLUT OBJ Loader.";
win.field_of_view_angle = 45;
win.z_near = 1.0f;
win.z_far = 500.0f;
// initialize and run program
glutInit( &argc, argv ); // GLUT initialization
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); // Display Mode
glutInitWindowSize( win.width, win.height ); // set window size
glutCreateWindow( win.title ); // create Window
glutDisplayFunc( display ); // register Display Function
glutIdleFunc( display ); // register Idle Function
glutKeyboardFunc( keyboard ); // register Keyboard Handler
initialize( );
// load_obj(argv[1], suzanne_vertices, suzanne_normals, suzanne_elements);
obj.Load( argv[1] );
if( !pmodel )
{ /* load up the model */
pmodel = glmReadOBJ( argv[1] );
if( !pmodel )
{
printf( "\nUsage: objviewV2 <-s> <obj filename>\n" );
return EXIT_FAILURE;
}
glmUnitize( pmodel );
glmDimensions( pmodel, modelDim );
cerr << "Model dimensions WxHxD: " << modelDim[0] << " x " << modelDim[1] << " x " << modelDim[2] << endl;
glmScale( pmodel, 0.25 );
glmVertexNormals( pmodel, 90.0, GL_TRUE );
}
glutMainLoop( ); // run GLUT mainloop
return 0;
}

45
src/tp/CMakeLists.txt Normal file
View file

@ -0,0 +1,45 @@
add_subdirectory(tracker)
# Make sure the compiler can find include files from our tracker library.
#include_directories (${TP_Interface_AR_SOURCE_DIR}/src/tp/tracker)
include_directories (./tracker)
# Make sure the linker can find the tracker library once it is built.
link_directories (${TP_Interface_AR_BINARY_DIR}/lib)
add_executable( checkerboard checkerboard.cpp )
target_link_libraries( checkerboard ${OpenCV_LIBS} tracker )
add_executable( checkerboardvideo checkerboardvideo.cpp )
target_link_libraries( checkerboardvideo ${OpenCV_LIBS} tracker )
add_executable( checkerboardvideoRectified checkerboardvideoRectified.cpp )
target_link_libraries( checkerboardvideoRectified ${OpenCV_LIBS} tracker )
add_executable( checkerboardvideoUndistort checkerboardvideoUndistort.cpp )
target_link_libraries( checkerboardvideoUndistort ${OpenCV_LIBS} )
add_executable( tracking tracking.cpp )
target_link_libraries( tracking ${OpenCV_LIBS} tracker )
add_executable( trackingKLT trackingKLT.cpp )
target_link_libraries( trackingKLT ${OpenCV_LIBS} tracker )
add_executable( calibration calibration.cpp )
target_link_libraries( calibration ${OpenCV_LIBS} )
add_executable( videoOGL videoOGL.cpp )
target_link_libraries( videoOGL ${OpenCV_LIBS} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} tracker)
include_directories( ${LIBGLM_INCLUDE_DIRS})
add_executable( videoOGLTeapot videoOGLTeapot.cpp )
target_link_libraries( videoOGLTeapot ${LIBGLM_LIBRARIES} ${OpenCV_LIBS} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} tracker)
add_executable( videoOGLTracking videoOGLTracking.cpp )
target_link_libraries( videoOGLTracking ${LIBGLM_LIBRARIES} ${OpenCV_LIBS} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} tracker)
add_executable( videoOGLOBJ videoOGLOBJ.cpp )
target_link_libraries( videoOGLOBJ ${LIBGLM_LIBRARIES} ${OpenCV_LIBS} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} tracker)

71
src/tp/README.md Normal file
View file

@ -0,0 +1,71 @@
## Detecting the chessboard
In this first exercise we want to build a program that given an image as input, detect the a chessboard in the image and draw the detected chessboard corners
```bash
./bin/checkerboard -w 8 -h 6 ../data/images/left01re.jpg
```
## Detecting the chessboard on a video
Now that we can detect a chessboard on an image, lets move one step forward and write a program that detected the chessboard in a given video stream.
```bash
./bin/checkerboardVideo -w 9 -h 6 ../data/video/calib.avi
```
### Perspective rectification
In this exercise we will modify the previous code in order to estimate the homography in a robust way every time the chessboard is detected.
```bash
./bin/checkerboardvideoRectified -w 9 -h 6 ../data/video/calib.avi
```
## Camera calibration
In order to calibrate the camera we will rely on a program that comes with OpenCV.
```bash
./bin/calibration -w 9 -h 6 -V -n 10 -zt -o calib.xml ../data/video/calib.avi
```
### Removing the optical distortion
We want to implement a program that given a video and the relevant camera parameters as input, will remove the optical distortion and show the undistorted image.
```bash
./bin/checkerboardvideoUndistort -c calib.xml ../data/video/calib.avi
```
## The camera tracker
This first version of the camera tracker implements a tracking by detection method: each frame is processed independently to detect the chessboard and eventually compute the camera pose.
```bash
./bin/tracking -w 9 -h 6 -c calib.xml ../data/video/calib.avi
```
## The KLT version
In this exercise we will build a camera tracker that detect the chessboard and then track the corners using the Kanade-Lucas- Tomasi method (KLT).
```bash
./bin/trackingKLT -w 9 -h 6 -c calib.xml ../data/video/calib.avi
```
## Adding the OpenGL rendering
We will use OpenGL to render the 3D object on top of the chessboard.
```bash
./bin/videoOGLTeapotTP -w 9 -h 6 -c calib.xml ../data/video/calib.avi
```
## Rendering an OBJ 3D object
The last step of this TP is to replace the usual OpenGL teapot with a generic 3D object loaded from an Wavefront OBJ file.
```bash
./bin/videoOGLTracking -w 9 -h 6 -c calib.xml -o ../data/models/superma.obj ../data/video/calib.avi
```

590
src/tp/calibration.cpp Normal file
View file

@ -0,0 +1,590 @@
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <cctype>
#include <cstdio>
#include <cstring>
#include <ctime>
using namespace cv;
using namespace std;
const char * usage =
" \nexample command line for calibration from a live feed.\n"
" calibration -w 4 -h 5 -s 0.025 -o camera.yml -op -oe\n"
" \n"
" example command line for calibration from a list of stored images:\n"
" imagelist_creator image_list.xml *.png\n"
" calibration -w 4 -h 5 -s 0.025 -o camera.yml -op -oe image_list.xml\n"
" where image_list.xml is the standard OpenCV XML/YAML\n"
" use imagelist_creator to create the xml or yaml list\n"
" file consisting of the list of strings, e.g.:\n"
" \n"
"<?xml version=\"1.0\"?>\n"
"<opencv_storage>\n"
"<images>\n"
"view000.png\n"
"view001.png\n"
"<!-- view002.png -->\n"
"view003.png\n"
"view010.png\n"
"one_extra_view.jpg\n"
"</images>\n"
"</opencv_storage>\n";
const char* liveCaptureHelp =
"When the live video from camera is used as input, the following hot-keys may be used:\n"
" <ESC>, 'q' - quit the program\n"
" 'g' - start capturing images\n"
" 'u' - switch undistortion on/off\n"
" 't' - to take the shot if delay <=0\n";
static void help( )
{
printf( "This is a camera calibration sample.\n"
"Usage: calibration\n"
" -w <board_width> # the number of inner corners per one of board dimension\n"
" -h <board_height> # the number of inner corners per another board dimension\n"
" [-pt <pattern>] # the type of pattern: chessboard or circles' grid\n"
" [-n <number_of_frames>] # the number of frames to use for calibration\n"
" # (if not specified, it will be set to the number\n"
" # of board views actually available)\n"
" [-d <delay>] # a minimum delay in ms between subsequent attempts to capture a next view\n"
" # (used only for video capturing)\n"
" # if <=0, then the capture will be done manually by pressing 't'\n"
" [-s <squareSize>] # square size in some user-defined units (1 by default)\n"
" [-o <out_camera_params>] # the output filename for intrinsic [and extrinsic] parameters\n"
" [-op] # write detected feature points\n"
" [-oe] # write extrinsic parameters\n"
" [-zt] # assume zero tangential distortion\n"
" [-a <aspectRatio>] # fix aspect ratio (fx/fy)\n"
" [-p] # fix the principal point at the center\n"
" [-v] # flip the captured images around the horizontal axis\n"
" [-V] # use a video file, and not an image list, uses\n"
" # [input_data] string for the video file name\n"
" [-su] # show undistorted images after calibration\n"
" [input_data] # input data, one of the following:\n"
" # - text file with a list of the images of the board\n"
" # the text file can be generated with imagelist_creator\n"
" # - name of video file with a video of the board\n"
" # if input_data not specified, a live view from the camera is used\n"
"\n" );
printf( "\n%s", usage );
printf( "\n%s", liveCaptureHelp );
}
enum
{
DETECTION = 0, CAPTURING = 1, CALIBRATED = 2
};
enum Pattern
{
CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID
};
static double computeReprojectionErrors(
const vector<vector<Point3f> >& objectPoints,
const vector<vector<Point2f> >& imagePoints,
const vector<Mat>& rvecs, const vector<Mat>& tvecs,
const Mat& cameraMatrix, const Mat& distCoeffs,
vector<float>& perViewErrors )
{
vector<Point2f> imagePoints2;
int i, totalPoints = 0;
double totalErr = 0, err;
perViewErrors.resize( objectPoints.size( ) );
for( i = 0; i < ( int ) objectPoints.size( ); i++ )
{
projectPoints( Mat( objectPoints[i] ), rvecs[i], tvecs[i],
cameraMatrix, distCoeffs, imagePoints2 );
err = norm( Mat( imagePoints[i] ), Mat( imagePoints2 ), CV_L2 );
auto n = ( int ) objectPoints[i].size( );
perViewErrors[i] = ( float ) std::sqrt( err * err / n );
totalErr += err*err;
totalPoints += n;
}
return std::sqrt( totalErr / totalPoints );
}
static void calcChessboardCorners( Size boardSize, float squareSize, vector<Point3f>& corners, Pattern patternType = CHESSBOARD )
{
corners.resize( 0 );
switch( patternType )
{
case CHESSBOARD:
case CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
corners.push_back( Point3f(j * squareSize,
i * squareSize, 0 ) );
break;
case ASYMMETRIC_CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
corners.push_back( Point3f((2 * j + i % 2 ) * squareSize,
i * squareSize, 0 ) );
break;
default:
CV_Error( CV_StsBadArg, "Unknown pattern type\n" );
}
}
static bool runCalibration( const vector<vector<Point2f> > &imagePoints,
const Size &imageSize, const Size &boardSize, Pattern patternType,
float squareSize, float aspectRatio,
int flags, Mat& cameraMatrix, Mat& distCoeffs,
vector<Mat>& rvecs, vector<Mat>& tvecs,
vector<float>& reprojErrs,
double& totalAvgErr )
{
cameraMatrix = Mat::eye( 3, 3, CV_64F );
if( flags & CV_CALIB_FIX_ASPECT_RATIO )
cameraMatrix.at<double>( 0, 0 ) = aspectRatio;
distCoeffs = Mat::zeros( 8, 1, CV_64F );
vector<vector<Point3f> > objectPoints( 1 );
calcChessboardCorners( boardSize, squareSize, objectPoints[0], patternType );
objectPoints.resize( imagePoints.size( ), objectPoints[0] );
double rms = calibrateCamera( objectPoints, imagePoints, imageSize, cameraMatrix,
distCoeffs, rvecs, tvecs, flags | CV_CALIB_FIX_K4 | CV_CALIB_FIX_K5 );
///*|CV_CALIB_FIX_K3*/|CV_CALIB_FIX_K4|CV_CALIB_FIX_K5);
printf( "RMS error reported by calibrateCamera: %g\n", rms );
bool ok = checkRange( cameraMatrix ) && checkRange( distCoeffs );
totalAvgErr = computeReprojectionErrors( objectPoints, imagePoints,
rvecs, tvecs, cameraMatrix, distCoeffs, reprojErrs );
return ok;
}
static void saveCameraParams( const string& filename,
Size imageSize, Size boardSize,
float squareSize, float aspectRatio, int flags,
const Mat& cameraMatrix, const Mat& distCoeffs,
const vector<Mat>& rvecs, const vector<Mat>& tvecs,
const vector<float>& reprojErrs,
const vector<vector<Point2f> >& imagePoints,
double totalAvgErr )
{
FileStorage fs( filename, FileStorage::WRITE );
time_t tt;
time( &tt );
struct tm *t2 = localtime( &tt );
char buf[1024];
strftime( buf, sizeof (buf ) - 1, "%c", t2 );
fs << "calibration_time" << buf;
if( !rvecs.empty( ) || !reprojErrs.empty( ) )
fs << "nframes" << ( int ) std::max( rvecs.size( ), reprojErrs.size( ) );
fs << "image_width" << imageSize.width;
fs << "image_height" << imageSize.height;
fs << "board_width" << boardSize.width;
fs << "board_height" << boardSize.height;
fs << "square_size" << squareSize;
if( flags & CV_CALIB_FIX_ASPECT_RATIO )
fs << "aspectRatio" << aspectRatio;
if( flags != 0 )
{
sprintf( buf, "flags: %s%s%s%s",
flags & CV_CALIB_USE_INTRINSIC_GUESS ? "+use_intrinsic_guess" : "",
flags & CV_CALIB_FIX_ASPECT_RATIO ? "+fix_aspectRatio" : "",
flags & CV_CALIB_FIX_PRINCIPAL_POINT ? "+fix_principal_point" : "",
flags & CV_CALIB_ZERO_TANGENT_DIST ? "+zero_tangent_dist" : "" );
cvWriteComment( *fs, buf, 0 );
}
fs << "flags" << flags;
fs << "camera_matrix" << cameraMatrix;
fs << "distortion_coefficients" << distCoeffs;
fs << "avg_reprojection_error" << totalAvgErr;
if( !reprojErrs.empty( ) )
fs << "per_view_reprojection_errors" << Mat( reprojErrs );
if( !rvecs.empty( ) && !tvecs.empty( ) )
{
CV_Assert( rvecs[0].type( ) == tvecs[0].type( ) );
Mat bigmat( ( int ) rvecs.size( ), 6, rvecs[0].type( ) );
for( int i = 0; i < ( int ) rvecs.size( ); i++ )
{
Mat r = bigmat( Range( i, i + 1 ), Range( 0, 3 ) );
Mat t = bigmat( Range( i, i + 1 ), Range( 3, 6 ) );
CV_Assert( rvecs[i].rows == 3 && rvecs[i].cols == 1 );
CV_Assert( tvecs[i].rows == 3 && tvecs[i].cols == 1 );
//*.t() is MatExpr (not Mat) so we can use assignment operator
r = rvecs[i].t( );
t = tvecs[i].t( );
}
cvWriteComment( *fs, "a set of 6-tuples (rotation vector + translation vector) for each view", 0 );
fs << "extrinsic_parameters" << bigmat;
}
if( !imagePoints.empty( ) )
{
Mat imagePtMat( ( int ) imagePoints.size( ), ( int ) imagePoints[0].size( ), CV_32FC2 );
for( int i = 0; i < ( int ) imagePoints.size( ); i++ )
{
Mat r = imagePtMat.row( i ).reshape( 2, imagePtMat.cols );
Mat imgpti( imagePoints[i] );
imgpti.copyTo( r );
}
fs << "image_points" << imagePtMat;
}
}
static bool readStringList( const string& filename, vector<string>& l )
{
l.resize( 0 );
FileStorage fs( filename, FileStorage::READ );
if( !fs.isOpened( ) )
return false;
FileNode n = fs.getFirstTopLevelNode( );
if( n.type( ) != FileNode::SEQ )
return false;
FileNodeIterator it = n.begin( ), it_end = n.end( );
for(; it != it_end; ++it )
l.push_back( ( string ) * it );
return true;
}
static bool runAndSave( const string& outputFilename,
const vector<vector<Point2f> >& imagePoints,
const Size &imageSize, const Size &boardSize, Pattern patternType, float squareSize,
float aspectRatio, int flags, Mat& cameraMatrix,
Mat& distCoeffs, bool writeExtrinsics, bool writePoints )
{
vector<Mat> rvecs, tvecs;
vector<float> reprojErrs;
double totalAvgErr = 0;
bool ok = runCalibration( imagePoints, imageSize, boardSize, patternType, squareSize,
aspectRatio, flags, cameraMatrix, distCoeffs,
rvecs, tvecs, reprojErrs, totalAvgErr );
printf( "%s. avg reprojection error = %.2f\n",
ok ? "Calibration succeeded" : "Calibration failed",
totalAvgErr );
if( ok )
saveCameraParams( outputFilename, imageSize,
boardSize, squareSize, aspectRatio,
flags, cameraMatrix, distCoeffs,
writeExtrinsics ? rvecs : vector<Mat>( ),
writeExtrinsics ? tvecs : vector<Mat>( ),
writeExtrinsics ? reprojErrs : vector<float>( ),
writePoints ? imagePoints : vector<vector<Point2f> >( ),
totalAvgErr );
return ok;
}
int main( int argc, char** argv )
{
Size boardSize, imageSize;
float squareSize = 1.f, aspectRatio = 1.f;
Mat cameraMatrix, distCoeffs;
const char* outputFilename = "out_camera_data.yml";
const char* inputFilename = nullptr;
int i, nframes = 10;
bool writeExtrinsics = false, writePoints = false;
bool undistortImage = false;
int flags = 0;
VideoCapture capture;
bool flipVertical = false;
bool showUndistorted = false;
bool videofile = false;
int delay = 1000;
clock_t prevTimestamp = 0;
int mode = DETECTION;
int cameraId = 1;
vector<vector<Point2f> > imagePoints;
vector<string> imageList;
Pattern pattern = CHESSBOARD;
if( argc < 2 )
{
help( );
return 0;
}
for( i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
return fprintf( stderr, "Invalid board width\n" ), -1;
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
return fprintf( stderr, "Invalid board height\n" ), -1;
}
else if( strcmp( s, "-pt" ) == 0 )
{
i++;
if( !strcmp( argv[i], "circles" ) )
pattern = CIRCLES_GRID;
else if( !strcmp( argv[i], "acircles" ) )
pattern = ASYMMETRIC_CIRCLES_GRID;
else if( !strcmp( argv[i], "chessboard" ) )
pattern = CHESSBOARD;
else
return fprintf( stderr, "Invalid pattern type: must be chessboard or circles\n" ), -1;
}
else if( strcmp( s, "-s" ) == 0 )
{
if( sscanf( argv[++i], "%f", &squareSize ) != 1 || squareSize <= 0 )
return fprintf( stderr, "Invalid board square width\n" ), -1;
}
else if( strcmp( s, "-n" ) == 0 )
{
if( sscanf( argv[++i], "%u", &nframes ) != 1 || nframes <= 3 )
return printf( "Invalid number of images\n" ), -1;
}
else if( strcmp( s, "-a" ) == 0 )
{
if( sscanf( argv[++i], "%f", &aspectRatio ) != 1 || aspectRatio <= 0 )
return printf( "Invalid aspect ratio\n" ), -1;
flags |= CV_CALIB_FIX_ASPECT_RATIO;
}
else if( strcmp( s, "-d" ) == 0 )
{
if( sscanf( argv[++i], "%u", &delay ) != 1 )
return printf( "Invalid delay\n" ), -1;
}
else if( strcmp( s, "-op" ) == 0 )
{
writePoints = true;
}
else if( strcmp( s, "-oe" ) == 0 )
{
writeExtrinsics = true;
}
else if( strcmp( s, "-zt" ) == 0 )
{
flags |= CV_CALIB_ZERO_TANGENT_DIST;
}
else if( strcmp( s, "-p" ) == 0 )
{
flags |= CV_CALIB_FIX_PRINCIPAL_POINT;
}
else if( strcmp( s, "-v" ) == 0 )
{
flipVertical = true;
}
else if( strcmp( s, "-V" ) == 0 )
{
videofile = true;
}
else if( strcmp( s, "-o" ) == 0 )
{
outputFilename = argv[++i];
}
else if( strcmp( s, "-su" ) == 0 )
{
showUndistorted = true;
}
else if( s[0] != '-' )
{
if( isdigit( s[0] ) )
sscanf( s, "%d", &cameraId );
else
inputFilename = s;
}
else
return fprintf( stderr, "Unknown option %s", s ), -1;
}
if( inputFilename )
{
if( !videofile && readStringList( inputFilename, imageList ) )
mode = CAPTURING;
else
capture.open( inputFilename );
}
else
{
capture.open( cameraId );
}
if( !capture.isOpened( ) && imageList.empty( ) )
return fprintf( stderr, "Could not initialize video (%d) capture\n", cameraId ), -2;
if( !imageList.empty( ) )
nframes = ( int ) imageList.size( );
if( !inputFilename )
{
capture.set( CV_CAP_PROP_FRAME_WIDTH, 640 );
capture.set( CV_CAP_PROP_FRAME_HEIGHT, 480 );
}
if( capture.isOpened( ) )
printf( "%s", liveCaptureHelp );
namedWindow( "Image View", 1 );
for( i = 0;; i++ )
{
int key = 0;
Mat view, viewGray;
bool blink = false;
if( capture.isOpened( ) )
{
Mat view0;
capture >> view0;
view0.copyTo( view );
}
else if( i < ( int ) imageList.size( ) )
view = imread( imageList[i], 1 );
if( !view.data )
{
if(!imagePoints.empty())
runAndSave( outputFilename, imagePoints, imageSize,
boardSize, pattern, squareSize, aspectRatio,
flags, cameraMatrix, distCoeffs,
writeExtrinsics, writePoints );
break;
}
imageSize = view.size( );
if( flipVertical )
flip( view, view, 0 );
vector<Point2f> pointbuf;
cvtColor( view, viewGray, CV_BGR2GRAY );
bool found;
switch( pattern )
{
case CHESSBOARD:
found = findChessboardCorners( view, boardSize, pointbuf,
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE );
break;
case CIRCLES_GRID:
found = findCirclesGrid( view, boardSize, pointbuf );
break;
case ASYMMETRIC_CIRCLES_GRID:
found = findCirclesGrid( view, boardSize, pointbuf, CALIB_CB_ASYMMETRIC_GRID );
break;
default:
return fprintf( stderr, "Unknown pattern type\n" ), -1;
}
// improve the found corners' coordinate accuracy
if( pattern == CHESSBOARD && found ) cornerSubPix( viewGray, pointbuf, Size( 11, 11 ),
Size( -1, -1 ), TermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1 ) );
if( mode == CAPTURING && found &&
( !capture.isOpened( ) || ( ( ( delay <= 0 ) && ( key == 't' ) ) || ( ( delay > 0 ) && ( clock( ) - prevTimestamp > delay * 1e-3 * CLOCKS_PER_SEC ) ) ) ) )
{
imagePoints.push_back( pointbuf );
prevTimestamp = clock( );
blink = capture.isOpened( );
}
if( found )
drawChessboardCorners( view, boardSize, Mat( pointbuf ), found );
string msg = mode == CAPTURING ? "100/100" :
mode == CALIBRATED ? "Calibrated" : "Press 'g' to start";
int baseLine = 0;
Size textSize = getTextSize( msg, 1, 1, 1, &baseLine );
Point textOrigin( view.cols - 2 * textSize.width - 10, view.rows - 2 * baseLine - 10 );
if( mode == CAPTURING )
{
if( undistortImage )
msg = format( "Press 't' to grab image %d/%d Undist", ( int ) imagePoints.size( ), nframes );
else
msg = format( "Press 't' to grab image %d/%d", ( int ) imagePoints.size( ), nframes );
}
putText( view, msg, textOrigin, 1, 1,
mode != CALIBRATED ? Scalar( 0, 0, 255 ) : Scalar( 0, 255, 0 ) );
if( blink )
bitwise_not( view, view );
if( mode == CALIBRATED && undistortImage )
{
Mat temp = view.clone( );
undistort( temp, view, cameraMatrix, distCoeffs );
}
imshow( "Image View", view );
key = 0xff & waitKey( capture.isOpened( ) ? 50 : 500 );
if( ( key & 255 ) == 27 )
break;
if( key == 'u' && mode == CALIBRATED )
undistortImage = !undistortImage;
if( capture.isOpened( ) && key == 'g' )
{
mode = CAPTURING;
imagePoints.clear( );
}
if( mode == CAPTURING && imagePoints.size( ) >= ( unsigned ) nframes )
{
if( runAndSave( outputFilename, imagePoints, imageSize,
boardSize, pattern, squareSize, aspectRatio,
flags, cameraMatrix, distCoeffs,
writeExtrinsics, writePoints ) )
mode = CALIBRATED;
else
mode = DETECTION;
if( !capture.isOpened( ) )
break;
}
}
if( !capture.isOpened( ) && showUndistorted )
{
Mat view, rview, map1, map2;
initUndistortRectifyMap( cameraMatrix, distCoeffs, Mat( ),
getOptimalNewCameraMatrix( cameraMatrix, distCoeffs, imageSize, 1, imageSize, nullptr),
imageSize, CV_16SC2, map1, map2 );
for( i = 0; i < ( int ) imageList.size( ); i++ )
{
view = imread( imageList[i], 1 );
if( !view.data )
continue;
//undistort( view, rview, cameraMatrix, distCoeffs, cameraMatrix );
remap( view, rview, map1, map2, INTER_LINEAR );
imshow( "Image View", rview );
int c = 0xff & waitKey( );
if( ( c & 255 ) == 27 || c == 'q' || c == 'Q' )
break;
}
}
return 0;
}

190
src/tp/checkerboard.cpp Normal file
View file

@ -0,0 +1,190 @@
#include "tracker/utility.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>
using namespace cv;
using namespace std;
// Display the help for the programm
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, Pattern &pattern );
int main( int argc, char** argv )
{
/******************************************************************/
/* CONSTANTS to use */
/******************************************************************/
// the name of the window
const string WINDOW_NAME = "Image View";
/******************************************************************/
/* VARIABLES TO use */
/******************************************************************/
Mat view; // it will contain the original image loaded from file
vector<Point2f> pointbuf; // it will contain the detected corners on the chessboard
bool found; // it will be true if a chessboard is found, false otherwise
// it will contain the size in terms of corners (width X height) of the chessboard
Size boardSize;
// it will contains the filename of the image file
string inputFilename;
// Default pattern is chessboard
Pattern pattern = CHESSBOARD;
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, inputFilename, pattern ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
/******************************************************************/
/* PART TO DEVELOP */
/******************************************************************/
/******************************************************************/
// create a window to display the image --> see namedWindow
/******************************************************************/
/******************************************************************/
// read the input image from file into "view" --> see imread
/******************************************************************/
//Measure the execution time, get time before function call
auto t = ( double ) getTickCount( );
/******************************************************************/
// call the function that detects the chessboard on the image
// found = detectChessboard...
/******************************************************************/
// get time after function call and display info
t = ( ( double ) getTickCount( ) - t ) / getTickFrequency( );
cout << ( ( !found ) ? ( "No " ) : ( "" ) ) << "chessboard detected!" << endl;
cout << "Chessboard detection took " << t * 1000 << "ms" << endl;
/******************************************************************/
// if the chessboard is found draw the cornerns on top of it
// --> see drawChessboardCorners
/******************************************************************/
/******************************************************************/
// show the image inside the window --> see imshow
/******************************************************************/
// wait for user input before ending --> see waitKey
waitKey( -1 );
return EXIT_SUCCESS;
}
// Display the help for the programm
void help( const char* programName )
{
cout << "Detect a chessboard in a given image" << endl
<< "Usage: " << programName << endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << endl
<< " -h <board_height> # the number of inner corners per another board dimension" << endl
<< " [-pt <pattern=[circles|acircles|chess]>] # the type of pattern: chessboard or circles' grid" << endl
<< " <image file> " << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, Pattern &pattern )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
cerr << "Invalid board width" << endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
cerr << "Invalid board height" << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else if( strcmp( s, "-pt" ) == 0 )
{
i++;
if( !strcmp( argv[i], "circles" ) )
pattern = CIRCLES_GRID;
else if( !strcmp( argv[i], "acircles" ) )
pattern = ASYMMETRIC_CIRCLES_GRID;
else if( !strcmp( argv[i], "chess" ) )
pattern = CHESSBOARD;
else
{
cerr << "Invalid pattern type: must be chessboard or circles" << endl;
return false;
}
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

View file

@ -0,0 +1,224 @@
#include <tracker/utility.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>
using namespace cv;
using namespace std;
// Display the help for the program
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, Pattern &pattern );
int main( int argc, char** argv )
{
/******************************************************************/
/* CONSTANTS to use */
/******************************************************************/
// the name of the window
const string WINDOW_NAME = "Image View";
/******************************************************************/
/* VARIABLES to use */
/******************************************************************/
vector<Point2f> pointbuf; // it will contain the detected corners on the chessboard
bool found; // it will be true if a chessboard is found, false otherwise
// it will contain the size in terms of corners (width X height) of the chessboard
Size boardSize;
// it will contains the filename of the image file
string inputFilename;
// Default pattern is chessboard
Pattern pattern = CHESSBOARD;
// Used to load the video and get the frames
VideoCapture capture;
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, inputFilename, pattern ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
/******************************************************************/
/* PART TO DEVELOP */
/******************************************************************/
/******************************************************************/
// create a window to display the image --> see namedWindow
/******************************************************************/
/******************************************************************/
// read the input video with capture
/******************************************************************/
/******************************************************************/
// check it is really opened
/******************************************************************/
// processing loop
while(true)
{
Mat view;
/******************************************************************/
// get the new frame from capture and copy it to view
/******************************************************************/
/******************************************************************/
// if no more images to process exit the loop
/******************************************************************/
//Measure the execution time, get time before function call
auto t = ( double ) getTickCount( );
/******************************************************************/
// call the function that detects the chessboard on the image
// found = detectChessboard...
/******************************************************************/
// get time after function call and display info
t = ( ( double ) getTickCount( ) - t ) / getTickFrequency( );
cout << ( ( !found ) ? ( "No " ) : ( "" ) ) << "chessboard detected!" << endl;
cout << "Chessboard detection took " << t * 1000 << "ms" << endl;
/******************************************************************/
// if the chessboard is found draw the corners on top of it
// --> see drawChessboardCorners
/******************************************************************/
/******************************************************************/
// show the image inside the window --> see imshow
/******************************************************************/
// wait 20ms for user input before processing the next frame
// Any user input will stop the execution
if( waitKey( 10 ) >= 0 )
break;
}
/******************************************************************/
// release the video resource
/******************************************************************/
return EXIT_SUCCESS;
}
// Display the help for the program
void help( const char* programName )
{
cout << "Detect a chessboard in a given video" << endl
<< "Usage: " << programName << endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << endl
<< " -h <board_height> # the number of inner corners per another board dimension" << endl
<< " [-pt <pattern=[circles|acircles|chess]>] # the type of pattern: chessboard or circles' grid" << endl
<< " <video file> " << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, Pattern &pattern )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
cerr << "Invalid board width" << endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
cerr << "Invalid board height" << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else if( strcmp( s, "-pt" ) == 0 )
{
i++;
if( !strcmp( argv[i], "circles" ) )
pattern = CIRCLES_GRID;
else if( !strcmp( argv[i], "acircles" ) )
pattern = ASYMMETRIC_CIRCLES_GRID;
else if( !strcmp( argv[i], "chess" ) )
pattern = CHESSBOARD;
else
{
cerr << "Invalid pattern type: must be chessboard or circles" << endl;
return false;
}
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

View file

@ -0,0 +1,262 @@
#include <tracker/utility.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>
using namespace cv;
using namespace std;
// Display the help for the programm
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, Pattern &pattern );
int main( int argc, char** argv )
{
/******************************************************************/
/* CONSTANTS to use */
/******************************************************************/
// the name of the window
const string WINDOW_NAME = "Image View";
// the name of the window
const string WINDOW_RECTIFIED = "Rectified Image";
/******************************************************************/
/* VARIABLES to use */
/******************************************************************/
vector<Point2f> pointbuf; // it will contain the detected corners on the chessboard
vector<Point2f> objectPoints; // it will contain the 2D "arbitrary" chosen points on the chessboard
bool found; // it will be true if a chessboard is found, false otherwise
// it will contain the size in terms of corners (width X height) of the chessboard
Size boardSize;
// it will contains the filename of the image file
string inputFilename;
// Default pattern is chessboard
Pattern pattern = CHESSBOARD;
// Used to load the video and get the frames
VideoCapture capture;
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, inputFilename, pattern ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
/******************************************************************/
/* PART TO DEVELOP */
/******************************************************************/
/******************************************************************/
// create a window using WINDOW_NAME as name to display the image --> see namedWindow
/******************************************************************/
/******************************************************************/
// create a second window using WINDOW_RECTIFIED as name to display the rectified image
/******************************************************************/
/******************************************************************/
// read the input video with capture (same as before)
/******************************************************************/
/******************************************************************/
// check it is really opened
/******************************************************************/
/******************************************************************/
// create the set of 2D (arbitrary) points of the checkerboard, let's say the
// size of the squares is 25
// call to calcChessboardCorners
/******************************************************************/
// processing loop
while( true )
{
Mat view, rectified;
/******************************************************************/
// get the new frame from capture and copy it to view
/******************************************************************/
/******************************************************************/
// if no more images to process exit the loop
/******************************************************************/
/******************************************************************/
// call the function that detects the chessboard on the image
/******************************************************************/
// found = detectChessboard...
cout << ( ( !found ) ? ( "No " ) : ( "" ) ) << "chessboard detected!" << endl;
// if a chessboard is found estimate the homography and rectify the image
if( found )
{
/******************************************************************/
// estimate the homography
// --> see findHomography
// http://docs.opencv.org/2.4.13.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html?highlight=homography#findhomography
/******************************************************************/
/******************************************************************/
// use the estimated homography to rectify the image
// --> see warpPerspective
// http://docs.opencv.org/2.4.13.4/modules/imgproc/doc/geometric_transformations.html#void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags, int borderMode, const Scalar& borderValue)
/******************************************************************/
}
else
{
/******************************************************************/
// otherwise copy the original image in rectified
// Mat.copyTo()
/******************************************************************/
}
/******************************************************************/
// if the chessboard is found draw the cornerns on top of it
// --> see drawChessboardCorners
/******************************************************************/
/******************************************************************/
// show the image inside the window --> see imshow
/******************************************************************/
/******************************************************************/
// show the rectified image inside the window --> see imshow
/******************************************************************/
// wait 20ms for user input before processing the next frame
// Any user input will stop the execution
if( waitKey( 10 ) >= 0 )
break;
}
/******************************************************************/
// release the video resource
/******************************************************************/
return EXIT_SUCCESS;
}
// Display the help for the programm
void help( const char* programName )
{
cout << "Detect a chessboard in a given video and show the rectified image according to the estimated homography" << endl
<< "Usage: " << programName << endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << endl
<< " -h <board_height> # the number of inner corners per another board dimension" << endl
<< " [-pt <pattern=[circles|acircles|chess]>] # the type of pattern: chessboard or circles' grid" << endl
<< " <video file> " << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, Pattern &pattern )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
cerr << "Invalid board width" << endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
cerr << "Invalid board height" << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else if( strcmp( s, "-pt" ) == 0 )
{
i++;
if( !strcmp( argv[i], "circles" ) )
pattern = CIRCLES_GRID;
else if( !strcmp( argv[i], "acircles" ) )
pattern = ASYMMETRIC_CIRCLES_GRID;
else if( !strcmp( argv[i], "chess" ) )
pattern = CHESSBOARD;
else
{
cerr << "Invalid pattern type: must be chessboard or circles" << endl;
return false;
}
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

View file

@ -0,0 +1,298 @@
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>
using namespace cv;
using namespace std;
// Display the help for the program
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, string &inputFilename, string &calibFile );
/******************************************************************/
/* FUNCTION TO DEVELOP */
/******************************************************************/
/**
* Load the calibration parameters from a file
*
* @param[in] calibFilename The name of the file
* @param[out] matK the 3x3 calibration matrix
* @param[out] dist the vector containing the distortion coefficients
* @return true if the parameters have been successfully loaded
*/
bool loadCameraParameters( const string &calibFilename, Mat &matK, Mat &dist )
{
// object that will parse the file
FileStorage fs;
/******************************************************************/
// open the file to read the parameters
// --> see method open() of FileStorage
/******************************************************************/
/******************************************************************/
// check if the file has been found/opened
// --> see isOpened()
/******************************************************************/
/******************************************************************/
// load the camera matrix from the tag "camera_matrix" of the file
/******************************************************************/
/******************************************************************/
// load the distortion coefficients from the tag "distortion_coefficients" of the file
/******************************************************************/
cout << matK << endl;
cout << dist << endl;
return true;
}
int main( int argc, char** argv )
{
/******************************************************************/
/* CONSTANTS to use */
/******************************************************************/
// the name of the window
const string WINDOW_NAME = "Image View";
/******************************************************************/
/* VARIABLES to use */
/******************************************************************/
// it will contains the filename of the image file
string inputFilename;
// it will contains the filename of the calibration file
string calibFilename;
// Used to load the video and get the frames
VideoCapture capture;
// Matrix that will contain the camera matrix with the intrinsic parameters
Mat matK;
// Matrix that will contain the distortion coefficients of the camera
Mat dist;
// variable used to read the user input
int mode = 'o';
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, inputFilename, calibFilename ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
/******************************************************************/
/* PART TO DEVELOP */
/******************************************************************/
/******************************************************************/
// create a window using WINDOW_NAME as name to display the image --> see namedWindow
/******************************************************************/
/******************************************************************/
// read the input video with capture (same as before)
/******************************************************************/
/******************************************************************/
// check it is really opened
/******************************************************************/
/******************************************************************/
// call to loadCameraParameters. we want to read the calibration
// matrix in matK and the distortion coefficients in dist
/******************************************************************/
// processing loop
while( true )
{
Mat view;
/******************************************************************/
// get the new frame from capture and copy it to view
/******************************************************************/
if( view.empty( ) )
break;
// this string contains the message to print on the image
string msg;
// if we want to see the difference image
if( mode == 'd' )
{
msg = "(o)riginal, (u)ndistorted";
// temporary image
Mat temp;
/******************************************************************/
// copy the original image into temp --> see Mat.clone()
/******************************************************************/
/******************************************************************/
// apply the undistortion and store the new image in view
// --> see undistort
/******************************************************************/
/******************************************************************/
// compute the difference between the two images and store the result in view
// see --> absdiff
/******************************************************************/
}
// if we want to see the undistorted image
else if( mode == 'u' )
{
msg = "(o)riginal, (d)ifference";
// temporary image
Mat temp;
/******************************************************************/
// copy the original image into temp --> see Mat.clone()
/******************************************************************/
/******************************************************************/
// apply the undistortion and store the new image in view
// --> see undistort
/******************************************************************/
}
else
{
msg = "(d)ifference, (u)ndistorted";
}
int baseLine = 0;
Size textSize = getTextSize( msg, 1, 1, 1, &baseLine );
// cout << baseLine << endl;
// cout << textSize << endl;
Point textOrigin( view.cols / 2 - textSize.width / 2, view.rows - 2 * baseLine - 10 );
putText( view, msg, textOrigin, 1, 1, Scalar( 0, 255, 0 ) );
/******************************************************************/
// show view inside the window --> see imshow
/******************************************************************/
// wait 20ms for user input before processing the next frame
// Any user input will stop the execution
int key = 0xff & waitKey( 70 );
if( key == 'q' )
{
break;
}
else if( key != 255 )
{
mode = key;
}
}
// release the video resource
capture.release( );
return EXIT_SUCCESS;
}
// Display the help for the program
void help( const char* programName )
{
cout << "Undistort the images from a video" << endl
<< "Usage: " << programName << endl
<< " -c <calib file> # the name of the calibration file" << endl
<< " <video file> # the name of the video file to process" << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, string &inputFilename, string &calibFile )
{
// check the minimum number of arguments
if( argc < 2 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-c" ) == 0 )
{
if( i + 1 < argc )
calibFile.assign( argv[++i] );
else
{
cerr << "Missing argument for option " << s << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

View file

@ -0,0 +1,12 @@
set(trackerHeaders_hpp tracker/Camera.hpp
tracker/ChessboardCameraTrackerKLT.hpp
tracker/ChessboardCameraTracker.hpp
tracker/utility.hpp
tracker/ICameraTracker.hpp)
add_library( tracker STATIC utility.cpp ChessboardCameraTracker.cpp ChessboardCameraTrackerKLT.cpp Camera.cpp ${trackerHeaders_hpp})
target_link_libraries( tracker ${OpenCV_LIBS} )
install(TARGETS tracker LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(FILES ${trackerHeaders_hpp} DESTINATION include/)

91
src/tp/tracker/Camera.cpp Normal file
View file

@ -0,0 +1,91 @@
#include "tracker/Camera.hpp"
#include <iostream>
using namespace std;
using namespace cv;
/**
* Initialize the camera loading the internal parameters from the given file
*
* @param[in] calibFilename the calibration file
* @return true if success
*/
bool Camera::init( const std::string& calibFilename )
{
/******************************************************************/
// open the file storage with the given filename
/******************************************************************/
/******************************************************************/
// check if the file storage has been opened correclty
/******************************************************************/
/******************************************************************/
// load the camera_matrix in matK
/******************************************************************/
/******************************************************************/
// load the distortion_coefficients in distCoeff
/******************************************************************/
/******************************************************************/
// load image_width and image_height in imageSize.[width|height]
/******************************************************************/
// cout << matK << endl;
// cout << distCoeff << endl;
return true;
}
/**
* Return the OpenGL projection matrix for the camera
* @param[out] proj the OGL projection matrix (ready to be passed, ie in col major format)
* @param znear near clipping plane
* @param zfar far clipping plane
* \note using http://strawlab.org/2011/11/05/augmented-reality-with-OpenGL/
*/
void Camera::getOGLProjectionMatrix( float *proj, float znear, float zfar ) const
{
// With window_coords==y down, we have:
//
// [2*K00/width, -2*K01/width, (width - 2*K02 + 2*x0)/width, 0]
// [ 0, 2*K11/height, (-height + 2*K12 + 2*y0)/height, 0]
// [ 0, 0, (-zfar - znear)/(zfar - znear), -2*zfar*znear/(zfar - znear)]
// [ 0, 0, -1, 0]
//corrected with artoolkitpluss src/Tracker::349
proj[0] = ( float ) ( 2 * matK.at<double>( 0, 0 ) ) / imageSize.width;
proj[1 * 4 + 0] = ( float ) ( 2 * matK.at<double>( 0, 1 ) ) / imageSize.width;
proj[2 * 4 + 0] = -( float ) ( imageSize.width - 2 * matK.at<double>( 0, 2 ) ) / imageSize.width;
proj[3 * 4 + 0] = 0;
proj[0 * 4 + 1] = 0;
// minus -(float)(2*matK.at<double>(1,1))/imageSize.height;
proj[1 * 4 + 1] = -( float ) ( 2 * matK.at<double>( 1, 1 ) ) / imageSize.height;
proj[2 * 4 + 1] = -( float ) ( -imageSize.height + 2 * matK.at<double>( 1, 2 ) ) / imageSize.height;
proj[3 * 4 + 1] = 0;
proj[0 * 4 + 2] = 0;
proj[1 * 4 + 2] = 0;
proj[2 * 4 + 2] = ( zfar + znear ) / ( zfar - znear );
proj[3 * 4 + 2] = -2 * zfar * znear / ( zfar - znear );
proj[0 * 4 + 3] = 0;
proj[1 * 4 + 3] = 0;
proj[2 * 4 + 3] = 1;
proj[3 * 4 + 3] = 0;
}

View file

@ -0,0 +1,78 @@
#include "tracker/ChessboardCameraTracker.hpp"
#include "tracker/utility.hpp"
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
/**
* It detects a chessboard inside an image and if found it returns the pose of the camera wrt the chessboard
*
* @param[in,out] view the original image
* @param[out] pose the pose of the camera
* @param[in] cam the camera
* @param[in] boardSize the size of the chessboard to detect
* @param[in] pattern the type of pattern to detect
* @return true if the chessboard has been found
*/
bool ChessboardCameraTracker::process( cv::Mat &view, cv::Mat &pose, const Camera & cam, const cv::Size &boardSize, const Pattern &pattern )
{
// true if the chessboard is found
bool found = false;
// contains the points detected on the chessboard
vector<Point2f> corners;
//******************************************************************/
// undistort the input image. view at the end must contain the undistorted version
// of the image.
//******************************************************************/
//******************************************************************/
// detect the chessboard
//******************************************************************/
// cout << ( (!found ) ? ( "No " ) : ("") ) << "chessboard detected!" << endl;
//******************************************************************/
// if a chessboard is found, estimate the homography
//******************************************************************/
if( found )
{
// contains the points on the chessboard
vector<Point2f> objectPoints;
//******************************************************************/
// create the set of 2D (arbitrary) points of the checkerboard
// call to calcChessboardCorners
//******************************************************************/
//******************************************************************/
// estimate the homography
// --> see findHomography
// http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html?highlight=homography#findhomography
//******************************************************************/
// cout << "H = " << H << endl << endl;
// cout << "corners =" << corners << endl << endl;
// cout << "ptsOb =" << objectPoints << endl << endl;
//******************************************************************/
// decompose the homography
//******************************************************************/
}
return found;
}

View file

@ -0,0 +1,162 @@
#include "tracker/ChessboardCameraTrackerKLT.hpp"
#include "tracker/utility.hpp"
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/video/tracking.hpp>
#include <iostream>
using namespace std;
using namespace cv;
/**
* It detects a chessboard inside an image and if found it returns the pose of the camera wrt the chessboard
*
* @param[in,out] view the original image
* @param[out] pose the pose of the camera
* @param[in] cam the camera
* @param[in] boardSize the size of the chessboard to detect
* @param[in] pattern the type of pattern to detect
* @return true if the chessboard has been found
*/
bool ChessboardCameraTrackerKLT::process( cv::Mat &view, cv::Mat &pose, const Camera & cam, const cv::Size &boardSize, const Pattern &pattern )
{
// true if the chessboard is found
bool found = false;
Mat temp = view.clone( ); // used for correcting the optical distortion
//******************************************************************/
// undistort the input image. view at the end must contain the undistorted version
// of the image.
//******************************************************************/
// contains the grey version of the current frame
Mat viewGrey;
//******************************************************************/
// convert the current left frame into greylevel image
//******************************************************************/
// if we have too few points or none
if( _corners.size( ) < 10 )
{
//******************************************************************/
// detect the chessboard
//******************************************************************/
if( found )
{
//******************************************************************/
// generate the points on the chessboard, this time 3D points
// see --> calcChessboardCorners3D
//******************************************************************/
//******************************************************************/
// compute the pose of the camera using mySolvePnPRansac (utility.hpp))
//******************************************************************/
}
}
else
{
// use klt to track the points
// some parameters for the optical flow algorithm
Size winSize( 11, 11 );
TermCriteria termcrit( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03 );
// vector where the estimated tracked points of the new frame will be stored
vector<Point2f> currPts;
// auxiliary stuff for the optical flow computation
// status has will have the same length as currPts and is 0 if the
// optical flow estimation for the corresponding new point is not good
vector<uchar> status;
vector<float> err;
//******************************************************************/
// estimate the new position of the tracked points using calcOpticalFlowPyrLK
//******************************************************************/
//******************************************************************/
// Filter currPts and update the lists _corners and _objectPoints: if
// the corresponding value in status is >0 then copy the new point of
// currPts in _corner, otherwise skip the point.
//******************************************************************/
// i is used to run through all the elements of currPts
// k is used to run through _corners and _objectPoints to keep only the well tracked features
size_t i, k;
for( i = k = 0; i < currPts.size( ); i++ )
{
//******************************************************************/
// if it's a good point copy it in _corners and also copy keep the
// corresponding _objectPoints
//******************************************************************/
// if..
{
#if DEBUGGING
line( view, _corners[ i ], currPts[ i ], Scalar( 255, 0, 0 ), 1 );
circle( view, currPts[ i ], 3, Scalar( 255, 0, 255 ), -1, 8 );
#endif
//******************************************************************/
// copy the current point in _corners
//******************************************************************/
//******************************************************************/
// copy the corresponding _objectPoints
//******************************************************************/
//******************************************************************/
// update k
//******************************************************************/
++k;
}
}
// resize the two vector to the size k, the number of "well" tracked features
_corners.resize( k );
_objectPoints.resize( k );
// vector containing the inliers
vector<int> idxInl;
//******************************************************************/
// compute the pose of the camera using mySolvePnPRansac (utility.hpp))
//******************************************************************/
// _vecCorners.push_back(_corners);
//// _vecObjectPoints.push_back(_objectPoints);
// _vecIdx.push_back(_indices);
//******************************************************************/
// filter the points to remove the outliers. Use filterVector from utility.hpp
// Filter both the image points and the 3D reference points
//******************************************************************/
found = true;
}
//******************************************************************/
// update _prevGrey with the current grey frame
//******************************************************************/
return found;
}

View file

@ -0,0 +1,39 @@
#pragma once
#include <opencv2/core/core.hpp>
class Camera
{
public:
Camera( ) = default;
/**
* Initialize the camera loading the internal parameters from the given file
*
* @param[in] calibFilename the calibration file
* @return true if success
*/
bool init( const std::string& calibFilename );
virtual ~Camera( ) = default;
/**
* Return the OpenGL projection matrix for the camera
* @param[out] proj the OGL projection matrix (ready to be passed, ie in col major format)
* @param znear near clipping plane
* @param zfar far clipping plane
* \note using http://strawlab.org/2011/11/05/augmented-reality-with-OpenGL/
*/
void getOGLProjectionMatrix( float *proj, float znear, float zfar ) const;
public:
cv::Mat matK;
cv::Mat distCoeff;
cv::Size imageSize;
};

View file

@ -0,0 +1,26 @@
#pragma once
#include "ICameraTracker.hpp"
class ChessboardCameraTracker : public ICameraTracker
{
public:
ChessboardCameraTracker( ) = default;
/**
* It detects a chessboard inside an image and if found it returns the pose of the camera wrt the chessboard
*
* @param[in,out] view the original image
* @param[out] pose the pose of the camera
* @param[in] cam the camera
* @param[in] boardSize the size of the chessboard to detect
* @param[in] pattern the type of pattern to detect
* @return true if the chessboard has been found
*/
bool process( cv::Mat &view, cv::Mat &pose, const Camera & cam, const cv::Size &boardSize, const Pattern &pattern );
virtual ~ChessboardCameraTracker( ) = default;
};

View file

@ -0,0 +1,35 @@
#pragma once
#include "ICameraTracker.hpp"
class ChessboardCameraTrackerKLT : public ICameraTracker
{
public:
ChessboardCameraTrackerKLT( ) = default;
/**
* It detects and tracks a chessboard inside an image
*
* @param[in,out] input the original image
* @param[out] pose the pose of the camera
* @param[in] cam the camera
* @param[in] boardSize the size of the chessboard to detect
* @param[in] patt the type of pattern to detect
* @return true if the chessboard has been found
*/
bool process( cv::Mat &input, cv::Mat &pose, const Camera & cam, const cv::Size &boardSize, const Pattern &patt );
virtual ~ChessboardCameraTrackerKLT( ) = default;
private:
// contains the 2D corners detected in the last frame that needs to be tracked
std::vector<cv::Point2f> _corners;
// contains the 3D points of the chessboard
std::vector<cv::Point3f> _objectPoints;
// the previous frame
cv::Mat _prevGrey{};
};

View file

@ -0,0 +1,51 @@
#pragma once
#include "Camera.hpp"
#include "utility.hpp"
class ICameraTracker
{
public:
/***************************************************
* INTERFACES
*
***************************************************/
/**
*
* @param input
* @param pose
* @param cam
* @param boardSize
* @param patt
* @return
*/
virtual bool process( cv::Mat &input, cv::Mat &pose, const Camera & cam, const cv::Size &boardSize, const Pattern &patt ) = 0;
/***************************************************
* METHODS
*
***************************************************/
/**
* Return the current projection matrix of the camera
* @return current projection matrix of the camera
*/
inline const cv::Mat & getCurrPose( ) const
{
return _currPose;
}
protected:
/**
4x4 rototranslation matrix for the camera position
*/
cv::Mat _currPose;
};

View file

@ -0,0 +1,132 @@
#pragma once
#include "Camera.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#define DEBUGGING 1
#if DEBUGGING
#define PRINTVAR( a ) std::cout << #a << " = " << (a) << endl << endl;
#else
#define PRINTVAR( a )
#endif
// Enumerative type containing the possible patterns for the chessboard
enum Pattern
{
CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID
};
/**
* Detect a chessboard in a given image
*
* @param[in] rgbimage The rgb image to process
* @param[out] pointbuf the set of 2D image corner detected on the chessboard
* @param[in] boardSize the size of the board in terms of corners (width X height)
* @param[in] patternType The type of chessboard pattern to look for
* @return true if the chessboard is detected inside the image, false otherwise
*/
bool detectChessboard( const cv::Mat &rgbimage, std::vector<cv::Point2f> &pointbuf, const cv::Size &boardSize, Pattern patternType );
/**
* Decompose the homography into its components R and t
*
* @param[in] H The homography H = [h1 h2 h3]
* @param[in] matK The 3x3 calibration matrix K
* @param[out] poseMat the 3x4 pose matrix [R t]
*/
void decomposeHomography( const cv::Mat &H, const cv::Mat& matK, cv::Mat& poseMat );
/**
*
* @param[in,out] rgbimage The image on which to draw the reference system
* @param[in] cam The camera
* @param[in] poseMat The pose of the camera
* @param[in] thickness The thickness of the line
* @param[in] scale A scale factor for the unit vectors to draw
* @param[in] alreadyUndistorted A boolean value that tells if the input image rgbimage is already undistorted or we are working on a distorted image
*/
void drawReferenceSystem( cv::Mat &rgbimage, const Camera& cam, const cv::Mat &poseMat, const int &thickness, const double &scale, bool alreadyUndistorted = true );
/**
* Wrapper around the original opencv's projectPoints
*
* @param[in] objectPoints the 3D points
* @param[in] poseMat the pose matrix of the camera
* @param[in] cameraMatrix the calibration matrix
* @param[in] distCoeffs the distortion coefficients
* @param[out] imagePoints the projected points
*/
void myProjectPoints( cv::InputArray objectPoints, const cv::Mat &poseMat, cv::InputArray cameraMatrix, cv::InputArray distCoeffs, cv::OutputArray imagePoints );
/**
* Wrapper around the original opencv's solvePnPRansac
*
* @param[in] objectPoints the 3D points
* @param[in] imagePoints the image points
* @param[in] cameraMatrix the calibration matrix
* @param[in] distCoeffs the distortion coefficients
* @param[out] poseMat the pose matrix
* @param[out] inliers the list of indices of the inliers points
*/
void mySolvePnPRansac( cv::InputArray objectPoints, cv::InputArray imagePoints, cv::InputArray cameraMatrix, cv::InputArray distCoeffs, cv::Mat &poseMat, cv::OutputArray inliers = cv::noArray( ) );
/**
* Generate the set of 3D points of a chessboard
*
* @param[in] boardSize the size of the board in terms of corners (width X height)
* @param[in] squareSize the size in mm of the each square of the chessboard
* @param[out] corners the set of 2D points on the chessboard
* @param[in] patternType The type of chessboard pattern to look for
*/
void calcChessboardCorners( const cv::Size &boardSize, const float &squareSize, std::vector<cv::Point2f>& corners, Pattern patternType = CHESSBOARD );
/**
* Generate the set of 3D points of a chessboard
*
* @param[in] boardSize the size of the board in terms of corners (width X height)
* @param[in] squareSize the size in mm of the each square of the chessboard
* @param[out] corners the set of 3D points on the chessboard
* @param[in] patternType The type of chessboard pattern to look for
*/
void calcChessboardCorners3D( const cv::Size &boardSize, const float &squareSize, std::vector<cv::Point3f>& corners, Pattern patternType = CHESSBOARD );
/**
* Filter a generic vector against a list of index of the elements to be deleted,
*
* @param[in,out] inout the vector to filter
* @param[in] idx list of indices of the element to keep
*/
template<typename T>
void filterVector( std::vector<T> &inout, const std::vector<int> &idx )
{
std::vector<T> temp;
temp.reserve( idx.size( ) );
for( size_t i = 0; i < idx.size( ); ++i )
{
assert( idx[i] < inout.size( ) );
temp.push_back( inout[ idx[i] ] );
}
inout.clear( ); //necessary??
inout = temp;
}
/**
* @brief Utility function used to detect the size and the type of a video stream.
* The video must be already open.
*
* @param[in] videoFilename The name of the video file
* @paramp[in,out] capture The video stream, it must be already open
* @param[out] singleSize The size of the frames (width x height) of the video
* @param[out] imgInType The type of the frame (uchar, int etc)
* @return true if everything went ok
*/
bool getVideoSizeAndType(const std::string &videoFilename, cv::VideoCapture capture, cv::Size &singleSize, int &imgInType);

411
src/tp/tracker/utility.cpp Normal file
View file

@ -0,0 +1,411 @@
#include "tracker/utility.hpp"
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/******************************************************************/
/* FUNCTIONS TO DEVELOP */
/******************************************************************/
/**
* Detect a chessboard in a given image
*
* @param[in] rgbimage The rgb image to process
* @param[out] pointbuf the set of 2D image corner detected on the chessboard
* @param[in] boardSize the size of the board in terms of corners (width X height)
* @param[in] patternType The type of chessboard pattern to look for
* @return true if the chessboard is detected inside the image, false otherwise
*/
bool detectChessboard( const Mat &rgbimage, vector<Point2f> &pointbuf, const Size &boardSize, Pattern patternType )
{
// it contains the value to return
bool found = false;
switch( patternType )
{
// detect a classic chessboard
case CHESSBOARD:
/******************************************************************/
// detect the chessboard --> see findChessboardCorners
// found = ...
/******************************************************************/
// if a chessboard is found refine the position of the points in a window 11x11 pixel
// use the default value for the termination criteria --> TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 )
if( found )
{
Mat viewGrey; // it will contain the graylevel version of the image
/******************************************************************/
// convert the image in "rgbimage" to gray level and save it in "viewGrey"
// --> cvtColor with CV_BGR2GRAY option
/******************************************************************/
/******************************************************************/
// refine the corner location in "pointbuf" using "viewGrey"
// --> see cornerSubPix
/******************************************************************/
}
break;
// detect a regular grid made of circles
case CIRCLES_GRID:
/******************************************************************/
// detect the circles --> see findCirclesGrid
// found = ...
/******************************************************************/
break;
// detect an asymmetric grid made of circles
case ASYMMETRIC_CIRCLES_GRID:
/******************************************************************/
// detect the circles --> see findCirclesGrid using the options CALIB_CB_ASYMMETRIC_GRID | CALIB_CB_CLUSTERING
// found = ...
/******************************************************************/
break;
default:
cerr << "Unknown pattern type" << endl;
return found;
}
return found;
}
/**
*
* @param[in,out] rgbimage The image on which to draw the reference system
* @param[in] cam The camera
* @param[in] poseMat the pose matrix of the camera
* @param[in] thickness The thickness of the line
* @param[in] scale A scale factor for the unit vectors to draw
* @param[in] alreadyUndistorted A boolean value that tells if the input image rgbimage is already undistorted or we are working on a distorted image
*/
void drawReferenceSystem( cv::Mat &rgbimage, const Camera& cam, const cv::Mat &poseMat, const int &thickness, const double &scale, bool alreadyUndistorted )
{
// contains the points to project to draw the 3 axis
vector<Point3f> vertex3D;
//******************************************************************/
// Add the four 3D points (Point3f) that we can use to draw
// the reference system to vertex3D. Use <scale> as unit
//******************************************************************/
// contains the projected 3D points on the image
vector<Point2f> imgRefPts;
//******************************************************************/
// Project the 3D points using myProjectPoints. Attention, check the
// flag alreadyUndistorted to see if we have to apply the distortion:
// if it is true we pass a 1x5 zero vector, otherwise the distortion
// parameter of cam
//******************************************************************/
// cout << "vertex3D" << vertex3D << endl;
// cout << "imgRefPts" << imgRefPts << endl;
//******************************************************************/
// draw the line of the x-axis and put "X" at the end
//******************************************************************/
//******************************************************************/
// draw the line of the y-axis and put "Y" at the end
//******************************************************************/
//******************************************************************/
// draw the line of the z-axis and put "Z" at the end
//******************************************************************/
}
/**
* Wrapper around the original opencv's projectPoints
*
* @param objectPoints the 3D points
* @param poseMat the pose matrix
* @param cameraMatrix the calibration matrix
* @param distCoeffs the distortion coeffi
* @param imagePoints
*/
void myProjectPoints( InputArray objectPoints, const Mat &poseMat, InputArray cameraMatrix, InputArray distCoeffs, OutputArray imagePoints )
{
Mat rvec;
Rodrigues( poseMat.colRange( 0, 3 ), rvec );
// projectPoints( Mat( vertex3D.t( ) ).reshape( 3, 1 ), rvec, Tvec, K, dist, imgRefPts );
projectPoints( objectPoints, rvec, poseMat.col( 3 ), cameraMatrix, distCoeffs, imagePoints );
}
/**
* Generate the set of 3D points of a chessboard
*
* @param[in] boardSize the size of the board in terms of corners (width X height)
* @param[in] squareSize the size in mm of the each square of the chessboard
* @param[out] corners the set of 2D points on the chessboard
* @param[in] patternType The type of chessboard pattern to look for
*/
void calcChessboardCorners( const Size &boardSize, const float &squareSize, vector<Point2f>& corners, Pattern patternType )
{
corners.resize( 0 );
corners.reserve( boardSize.height * boardSize.width );
switch( patternType )
{
case CHESSBOARD:
case CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
{
/******************************************************************/
// create a Point2f(x,y) according to the position j,i and a square
// size of squareSize. Add it to corners (using push_back...)
/******************************************************************/
}
break;
case ASYMMETRIC_CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
{
/******************************************************************/
// create a Point2f(x,y) according to the position j,i considering
// that x is generate using the formula (2*j + i % 2)*squareSize
// Add it to corners (using push_back...)
/******************************************************************/
}
break;
default:
CV_Error( CV_StsBadArg, "Unknown pattern type\n" );
}
}
/**
* Decompose the homography into its components R and t
*
* @param[in] H The homography H = [h1 h2 h3]
* @param[in] matK The 3x3 calibration matrix K
* @param[out] poseMat the 3x4 pose matrix [R t]
*/
void decomposeHomography( const Mat &H, const Mat& matK, Mat& poseMat )
{
Mat temp;
//******************************************************************/
//temp contains inv(K)*H
//******************************************************************/
// PRINTVAR( temp );
Mat r1, r2, r3, t;
//******************************************************************/
// get r1 and r2 from temp
//******************************************************************/
//******************************************************************/
// compute lambda
//******************************************************************/
//******************************************************************/
// normalize r1 and r2
//******************************************************************/
//******************************************************************/
// compute r3
//******************************************************************/
// PRINTVAR( r3 );
//******************************************************************/
// compute t
//******************************************************************/
//******************************************************************/
// create a 3x4 matrix (float) for poseMat
//******************************************************************/
//******************************************************************/
// fill the columns of poseMat with r1 r2 r3 and t
//******************************************************************/
// PRINTVAR( poseMat );
}
/******************************************************************************/
//KLT ONLY
/**
* Generate the set of 3D points of a chessboard
*
* @param[in] boardSize the size of the board in terms of corners (width X height)
* @param[in] squareSize the size in mm of the each square of the chessboard
* @param[out] corners the set of 3D points on the chessboard
* @param[in] patternType The type of chessboard pattern to look for
*/
void calcChessboardCorners3D( const Size &boardSize, const float &squareSize, vector<Point3f>& corners, Pattern patternType )
{
corners.resize( 0 );
corners.reserve( boardSize.height * boardSize.width );
switch( patternType )
{
case CHESSBOARD:
case CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
{
/******************************************************************/
// create a Point3f(x,y,0) according to the position j,i and a square
// size of squareSize. Add it to corners (using push_back...)
/******************************************************************/
}
break;
case ASYMMETRIC_CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
{
/******************************************************************/
// create a Point3f(x,y,0) according to the position j,i considering
// that x is generate using the formula (2*j + i % 2)*squareSize
// Add it to corners (using push_back...)
/******************************************************************/
}
break;
default:
CV_Error( CV_StsBadArg, "Unknown pattern type\n" );
}
}
/**
* Wrapper around the original opencv's solvePnPRansac
*
* @param[in] objectPoints the 3D points
* @param[in] imagePoints the image points
* @param[in] cameraMatrix the calibration matrix
* @param[in] distCoeffs the distortion coefficients
* @param[out] poseMat the pose matrix
* @param[out] inliers the list of indices of the inliers points
*/
void mySolvePnPRansac( cv::InputArray objectPoints, cv::InputArray imagePoints, cv::InputArray cameraMatrix, cv::InputArray distCoeffs, cv::Mat &poseMat, OutputArray inliers )
{
Mat currR, currT;
solvePnPRansac( objectPoints, imagePoints, cameraMatrix, distCoeffs, currR, currT, false, 100, 4, 100, inliers );
poseMat = Mat( 3, 4, CV_32F );
Mat Rot;
Rodrigues( currR, Rot );
#if CV_MINOR_VERSION < 4
// apparently older versions does not support direct copy
Mat temp;
Rot.convertTo( temp, CV_32F );
Mat a1 = poseMat.colRange( 0, 3 );
temp.copyTo( a1 );
a1 = poseMat.col( 3 );
currT.convertTo( temp, CV_32F );
temp.copyTo( a1 );
#else
Rot.copyTo( poseMat.colRange( 0, 3 ) );
currT.copyTo( poseMat.col( 3 ) );
#endif
}
bool getVideoSizeAndType(const std::string &videoFilename, cv::VideoCapture capture, cv::Size &singleSize, int &imgInType)
{
if( !capture.isOpened( ) )
{
cerr << "Could not open video file " << videoFilename << endl;
return false;
}
// open video file and get the first image just to get the image size
Mat view0;
capture >> view0;
if( view0.empty( ) )
{
cerr << "Could not get the first frame of the video file " << videoFilename << endl;
return false;
}
imgInType = view0.type( );
singleSize = view0.size( );
// close capture...
capture.release( );
// and re-open it so that we will start from the first frame again
return capture.open(videoFilename);
}

223
src/tp/tracking.cpp Normal file
View file

@ -0,0 +1,223 @@
#include "tracker/Camera.hpp"
#include "tracker/ChessboardCameraTracker.hpp"
#include "tracker/utility.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>
using namespace cv;
using namespace std;
// Display the help for the program
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile );
int main( int argc, char** argv )
{
/******************************************************************/
/* CONSTANTS to use */
/******************************************************************/
// the name of the window
const string WINDOW_NAME = "Image View";
/******************************************************************/
/* VARIABLES to use */
/******************************************************************/
// it will contain the size in terms of corners (width X height) of the chessboard
Size boardSize;
// it will contains the filename of the image file
string inputFilename;
// it will contains the filename of the image file
string calibFilename;
// Default pattern is chessboard
Pattern pattern = CHESSBOARD;
// Used to load the video and get the frames
VideoCapture capture;
// Camera object containing the calibration parameters
Camera cam;
// Camera Tracker object
ChessboardCameraTracker tracker;
// 3x4 camera pose matrix [R t]
Mat cameraPose;
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, inputFilename, calibFilename ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
/******************************************************************/
/* PART TO DEVELOP */
/******************************************************************/
/******************************************************************/
// create a window using WINDOW_NAME as name to display the image --> see namedWindow
/******************************************************************/
namedWindow( WINDOW_NAME, CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO );
/******************************************************************/
// read the input video with capture (same as before)
/******************************************************************/
capture.open( string( inputFilename ) );
/******************************************************************/
// check it is really opened
/******************************************************************/
if( !capture.isOpened( ) )
{
cerr << "Could not open video file " << inputFilename << endl;
return EXIT_FAILURE;
}
//******************************************************************/
// init the Camera loading the calibration parameters
//******************************************************************/
// processing loop
while(true)
{
Mat view;
/******************************************************************/
// get the new frame from capture and copy it to view
/******************************************************************/
/******************************************************************/
// if no more images to process exit the loop
/******************************************************************/
//******************************************************************/
// process the image with the process method
//******************************************************************/
//if...
{
//******************************************************************/
// draw the reference on top of the image
//******************************************************************/
}
/******************************************************************/
// show the image inside the window --> see imshow
/******************************************************************/
// wait 20ms for user input before processing the next frame
// Any user input will stop the execution
#if DEBUGGING
if( ( waitKey( -1 ) & 0xff ) == 'q' )
break;
#else
if( waitKey( 10 ) >= 0 )
break;
#endif
}
/******************************************************************/
// release the video resource
/******************************************************************/
return EXIT_SUCCESS;
}
// Display the help for the program
void help( const char* programName )
{
cout << "Detect a chessboard and display an augmented reference system on top of it" << endl
<< "Usage: " << programName << endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << endl
<< " -h <board_height> # the number of inner corners per another board dimension" << endl
<< " -c <calib file> # the name of the calibration file" << endl
<< " <video file> # the name of the video file" << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
cerr << "Invalid board width" << endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
cerr << "Invalid board height" << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else if( strcmp( s, "-c" ) == 0 )
{
if( i + 1 < argc )
calibFile.assign( argv[++i] );
else
{
cerr << "Missing argument for option " << s << endl;
return false;
}
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

220
src/tp/trackingKLT.cpp Normal file
View file

@ -0,0 +1,220 @@
#include "tracker/Camera.hpp"
#include "tracker/ChessboardCameraTrackerKLT.hpp"
#include "tracker/utility.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>
using namespace cv;
using namespace std;
// Display the help for the program
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile );
int main( int argc, char** argv )
{
/******************************************************************/
/* CONSTANTS to use */
/******************************************************************/
// the name of the window
const string WINDOW_NAME = "Image View";
/******************************************************************/
/* VARIABLES to use */
/******************************************************************/
// it will contain the size in terms of corners (width X height) of the chessboard
Size boardSize;
// it will contains the filename of the image file
string inputFilename;
// it will contains the filename of the image file
string calibFilename;
// Default pattern is chessboard
Pattern pattern = CHESSBOARD;
// Used to load the video and get the frames
VideoCapture capture;
// Camera object containing the calibration parameters
Camera cam;
// Camera Tracker object
ChessboardCameraTrackerKLT tracker;
// 3x4 camera pose matrix [R t]
Mat cameraPose;
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, inputFilename, calibFilename ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
/******************************************************************/
/* PART TO DEVELOP */
/******************************************************************/
//******************************************************************/
// create a window using WINDOW_NAME as name to display the image --> see namedWindow
//******************************************************************/
namedWindow( WINDOW_NAME, CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO );
//******************************************************************/
// read the input video with capture (same as before)
//******************************************************************/
capture.open( string( inputFilename ) );
//******************************************************************/
// check it is really opened
//******************************************************************/
if( !capture.isOpened( ) )
{
cerr << "Could not open video file " << inputFilename << endl;
return EXIT_FAILURE;
}
//******************************************************************/
// init the Camera loading the calibration parameters
//******************************************************************/
// processing loop
while( true )
{
Mat view;
/******************************************************************/
// get the new frame from capture and copy it to view
/******************************************************************/
/******************************************************************/
// if no more images to process exit the loop
/******************************************************************/
//******************************************************************/
// process the image
//******************************************************************/
//if...
{
//******************************************************************/
// draw the reference on top of the image
//******************************************************************/
}
/******************************************************************/
// show the image inside the window --> see imshow
/******************************************************************/
// wait 20ms for user input before processing the next frame
// Any user input will stop the execution
#if DEBUGGING
if( ( waitKey( -1 ) & 0xff ) == 'q' )
break;
#else
if( waitKey( 10 ) >= 0 )
break;
#endif
}
/******************************************************************/
// release the video resource
/******************************************************************/
capture.release( );
return EXIT_SUCCESS;
}
// Display the help for the program
void help( const char* programName )
{
cout << "Detect and track a chessboard with the KLT algorithm and display an augmented reference system on top of it" << endl
<< "Usage: " << programName << endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << endl
<< " -h <board_height> # the number of inner corners per another board dimension" << endl
<< " -c <calib file> # the name of the calibration file" << endl
<< " <video file> # the name of the video file" << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
cerr << "Invalid board width" << endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
cerr << "Invalid board height" << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else if( strcmp( s, "-c" ) == 0 )
{
if( i + 1 < argc )
calibFile.assign( argv[++i] );
else
{
cerr << "Missing argument for option " << s << endl;
return false;
}
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

256
src/tp/videoOGL.cpp Normal file
View file

@ -0,0 +1,256 @@
#include "tracker/utility.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#ifdef __APPLE__
#include <OpenGL/gl.h>
// #include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
// #include <GL/glu.h>
#include <GL/freeglut.h>
#endif
#include <cstdlib>
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
using namespace cv;
/*
* Common globals
*/
int gFinished;
// the OpenGL reference for the texture to display
GLuint gCameraTextureId;
// this will physically contain the current frame that is used as texture
Mat gResultImage;
// the size of the video frame
Size singleSize;
// OpenGL initialization
void glInit( )
{
glEnable( GL_TEXTURE_2D );
glGenTextures( 1, &gCameraTextureId );
}
// Updates texture handle gCameraTextureId with OpenCV image in cv::Mat from gResultImage
void updateTexture( )
{
glBindTexture( GL_TEXTURE_2D, gCameraTextureId );
// set texture filter to linear - we do not build mipmaps for speed
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
// create the texture from OpenCV image data
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, singleSize.width, singleSize.height, 0,
#if _WIN32
GL_BGR_EXT,
#else
GL_BGR,
#endif
GL_UNSIGNED_BYTE, gResultImage.data );
}
/**
* Draw the background from the camera image
*/
void drawBackground( )
{
// set up the modelview matrix so that the view is between [-1,-1] and [1,1]
glMatrixMode( GL_PROJECTION );
glPushMatrix( );
glLoadIdentity( );
glOrtho( -1, 1, -1, 1, 0, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
// draw the quad textured with the camera image
glBindTexture( GL_TEXTURE_2D, gCameraTextureId );
glBegin( GL_QUADS );
glTexCoord2f( 0, 1 );
glVertex2f( -1, -1 );
glTexCoord2f( 0, 0 );
glVertex2f( -1, 1 );
glTexCoord2f( 1, 0 );
glVertex2f( 1, 1 );
glTexCoord2f( 1, 1 );
glVertex2f( 1, -1 );
glEnd( );
// reset the projection matrix
glMatrixMode( GL_PROJECTION );
glPopMatrix( );
glMatrixMode( GL_MODELVIEW );
}
/** OpenGL display callback */
void displayFunc( )
{
glClear( GL_COLOR_BUFFER_BIT );
// render the background image from camera texture
glEnable( GL_TEXTURE_2D );
drawBackground( );
// clear th depth buffer bit so that the background is overdrawn
glClear( GL_DEPTH_BUFFER_BIT );
// everything will be white
glColor3f( 1, 1, 1 );
// start with fresh modelview matrix and apply the transform of the plane
glLoadIdentity( );
// enable the texture for a nice effect ;)
glDisable( GL_TEXTURE_2D );
glutSwapBuffers( );
glutPostRedisplay( );
}
// Windows resize callback
void reshape( GLint width, GLint height )
{
glViewport( 0, 0, width, height );
}
// Keyboard callback
void keyFunc( unsigned char key, int x, int y )
{
cout << key << " pressed" << endl;
switch( key )
{
case 27:
gFinished = true;
break;
default:
break;
}
}
void printHelp( const string &name )
{
cout << "Usage: " << endl << "\t" << name << " <videofile.avi> " << endl << endl << "Options: " << endl;
cout << endl;
}
int main( int argc, char** argv )
{
string videoFilename;
int imgInType;
long frameNumber = 0;
if( argc < 2 )
{
cerr << "Wrong number of parameters" << endl;
printHelp( string( argv[0] ) );
return EXIT_FAILURE;
}
VideoCapture capture;
videoFilename.assign( argv[1] );
capture.open( videoFilename );
// check if capture has opened the video
if( !capture.isOpened( ) )
{
cerr << "Could not open video file " << videoFilename << endl;
return EXIT_FAILURE;
}
if( !getVideoSizeAndType(videoFilename, capture, singleSize, imgInType ) )
{
cerr << "Something wrong while checking the size and type of the video " << videoFilename << endl;
return EXIT_FAILURE;
}
gResultImage = Mat( singleSize, imgInType );
// Setup GLUT rendering and callbacks
glutInit( &argc, argv );
glutCreateWindow( "Main" );
glutKeyboardFunc( keyFunc );
glutReshapeFunc( reshape );
// reshape the window with the size of the image
glutReshapeWindow( singleSize.width, singleSize.height );
glutDisplayFunc( displayFunc );
glInit( );
gFinished = false;
while( !gFinished )
{
Mat view0;
capture >> view0;
// get a copy of the frame
if( view0.empty( ) )
{
cerr << "no more images available" << endl;
gFinished = true;
break;
}
view0.copyTo( gResultImage );
cout << endl << endl << "****************** frame " << frameNumber << " ******************" << endl;
++frameNumber;
// update the texture to be displayed in OPENGL
updateTexture( );
// force Opengl to call the displayFunc
#if __APPLE__
glutCheckLoop( );
#else
glutMainLoopEvent( );
#endif
// sleep for 35ms
std::this_thread::sleep_for(std::chrono::milliseconds(35));
}
capture.release( );
return EXIT_SUCCESS;
}

561
src/tp/videoOGLOBJ.cpp Normal file
View file

@ -0,0 +1,561 @@
#include "tracker/Camera.hpp"
#include "tracker/ChessboardCameraTracker.hpp"
#include "tracker/ChessboardCameraTrackerKLT.hpp"
#include "tracker/utility.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#ifdef __APPLE__
#include <OpenGL/gl.h>
// #include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
// #include <GL/glu.h>
#include <GL/freeglut.h>
#endif
#include <glm.h>
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <chrono>
#include <thread>
using namespace std;
using namespace cv;
// Display the help for the programm
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile, string &objFile );
/*
* Common globals
*/
int gFinished;
// the OpenGL reference for the texture to display
GLuint gCameraTextureId;
// the global array containng the explicit modelview matrix
const float *gModelViewMatrix;
// the global array containng the explicit projection matrix
float gProjectionMatrix[16] = {0.f};
// this will physically contain the current frame that is used as texture
Mat gResultImage;
bool stop = false;
bool drawTeapot = true;
GLMmodel *model{nullptr};
// the size of the video frame
Size singleSize;
void DrawAxis( float scale )
{
glPushMatrix( );
glDisable( GL_LIGHTING );
// glDisable(GL_TEXTURE_2D);
glScalef( scale, scale, scale );
glBegin( GL_LINES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( .8f, 0.05f, 0.0 );
glVertex3f( 1.0, 0.25f, 0.0 ); /* Letter X */
glVertex3f( 0.8f, .25f, 0.0 );
glVertex3f( 1.0, 0.05f, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 1.0, 0.0, 0.0 ); /* X axis */
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 0.0, 1.0, 0.0 ); /* Y axis */
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 0.0, 0.0, 0.0 );
glVertex3f( 0.0, 0.0, 1.0 ); /* Z axis */
glEnd( );
// if (lighting)
glEnable( GL_LIGHTING );
// if (lighting)
// glEnable(GL_TEXTURE_2D);
glColor3f( 1.0, 1.0, 1.0 );
glPopMatrix( );
}
void DrawPoints( float scale )
{
glPushMatrix( );
glDisable( GL_LIGHTING );
// glDisable(GL_TEXTURE_2D);
glScalef( scale, scale, scale );
glPointSize( 3 );
glBegin( GL_POINTS );
for( int i = 0; i < 6; i++ )
{
glColor3f( 1.0, ( float ) 40.0f * i / 255.0f, ( float ) 40.0f * i / 255.0f );
for( int j = 0; j < 9; j++ )
glVertex3f( j, i, 0.0 );
}
glEnd( );
// if (lighting)
glEnable( GL_LIGHTING );
// if (lighting)
// glEnable(GL_TEXTURE_2D);
glColor3f( 1.0, 1.0, 1.0 );
glPopMatrix( );
}
/**
* OpenGL initialization
*/
void glInit( )
{
//******************************************************************
// enable the depth test
//******************************************************************
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LESS );
glEnable( GL_TEXTURE_2D );
glGenTextures( 1, &gCameraTextureId );
//******************************************************************
// set the Gouraud shading
//******************************************************************
glShadeModel( GL_SMOOTH );
//******************************************************************
// set the LIGHT0 as a simple white, directional light with direction [1,2,-2]
//******************************************************************
GLfloat gLightPos[] = {100.0, 200.0, -200.0, 0.0};
glLightfv( GL_LIGHT0, GL_POSITION, gLightPos );
//******************************************************************
// set the material properties for the teapot
// choose the values for ambient, diffuse, specular and shininess
// as you prefer. The teapot in the figure has is mainly gray with
// ambient 0.7, diffuse 0.8, specular 1.0 and shininess 100
//******************************************************************
GLfloat mat_ambient[] = {0.7, 0.7, 0.7, 1.0};
GLfloat mat_diffuse[] = {0.8, 0.8, 0.8, 1.0};
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat high_shininess[] = {100.0};
glMaterialfv( GL_FRONT, GL_AMBIENT, mat_ambient );
glMaterialfv( GL_FRONT, GL_DIFFUSE, mat_diffuse );
glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );
glMaterialfv( GL_FRONT, GL_SHININESS, high_shininess );
//******************************************************************
// enable the lights
//******************************************************************
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
//******************************************************************
// set the opengl projection matrix to gProjectionMatrix:
// load the identity and multiply it by gProjectionMatrix using glMultMatrixf
//******************************************************************
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
glMultMatrixf( gProjectionMatrix );
//******************************************************************
// set back the modelview mode
//******************************************************************
glMatrixMode( GL_MODELVIEW );
}
// Updates texture handle gCameraTextureId with OpenCV image in cv::Mat from gResultImage
void updateTexture( )
{
glBindTexture( GL_TEXTURE_2D, gCameraTextureId );
// set texture filter to linear - we do not build mipmaps for speed
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
// create the texture from OpenCV image data
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, singleSize.width, singleSize.height, 0,
#if _WIN32
GL_BGR_EXT,
#else
GL_BGR,
#endif
GL_UNSIGNED_BYTE, gResultImage.data );
}
/**
* Draw the background from the camera image
*/
void drawBackground( )
{
// set up the modelview matrix so that the view is between [-1,-1] and [1,1]
glMatrixMode( GL_PROJECTION );
glPushMatrix( );
glLoadIdentity( );
glOrtho( -1, 1, -1, 1, 0, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
// draw the quad textured with the camera image
glBindTexture( GL_TEXTURE_2D, gCameraTextureId );
glBegin( GL_QUADS );
glTexCoord2f( 0, 1 );
glVertex2f( -1, -1 );
glTexCoord2f( 0, 0 );
glVertex2f( -1, 1 );
glTexCoord2f( 1, 0 );
glVertex2f( 1, 1 );
glTexCoord2f( 1, 1 );
glVertex2f( 1, -1 );
glEnd( );
// reset the projection matrix
glMatrixMode( GL_PROJECTION );
glPopMatrix( );
glMatrixMode( GL_MODELVIEW );
}
/** OpenGL display callback */
void displayFunc( )
{
glClear( GL_COLOR_BUFFER_BIT );
// render the background image from camera texture
glEnable( GL_TEXTURE_2D );
//******************************************************************
// disable the lighting before drawing the background
//******************************************************************
glDisable( GL_LIGHTING );
drawBackground( );
// clear th depth buffer bit so that the background is overdrawn
glClear( GL_DEPTH_BUFFER_BIT );
// everything will be white
glColor3f( 1, 1, 1 );
// start with fresh modelview matrix and apply the transform of the plane
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
//******************************************************************
// apply the modelview matrix gModelViewMatrix using glMultMatrixf
//******************************************************************
glMultMatrixf( gModelViewMatrix );
// DrawPoints(25);
glRotatef( -90, 1, 0, 0 );
// enable the texture for a nice effect ;)
glDisable( GL_TEXTURE_2D );
//******************************************************************
// enable the lighting before drawing the teapot/the object
//******************************************************************
glEnable( GL_LIGHTING );
// DrawAxis(100);
glTranslatef( 0, 50, 0 );
//******************************************************************
// draw the teapot (the solid version)
//******************************************************************
if(drawTeapot)
glutSolidTeapot(45.0);
else
glmDraw(model, GLM_SMOOTH|GLM_TEXTURE);
glutSwapBuffers( );
glutPostRedisplay( );
}
// Windows resize callback
void reshape( GLint width, GLint height )
{
glViewport( 0, 0, width, height );
}
// Keyboard callback
void keyFunc( unsigned char key, int x, int y )
{
cout << key << " pressed" << endl;
switch( key )
{
case 27:
gFinished = true;
break;
case 's':
stop = !stop;
break;
}
}
int main( int argc, char** argv )
{
string videoFilename, calibFilename, objFile;
int imgInType;
long frameNumber = 0;
/******************************************************************/
/* VARIABLES TO USE */
/******************************************************************/
// it will contain the size in terms of corners (width X height) of the chessboard
Size boardSize;
// Default pattern is chessboard
Pattern pattern = CHESSBOARD;
// Used to load the video and get the frames
VideoCapture capture;
// Camera object containing the calibration parameters
Camera cam;
// Camera Tracker object
ChessboardCameraTrackerKLT tracker;
// 3x4 camera pose matrix [R t]
Mat cameraPose;
// Mat dummyMatrix = Mat::eye( 4, 4, CV_32F );
// dummyMatrix.at<float>(0, 3) = 102;
// dummyMatrix.at<float>(1, 3) = 46;
// dummyMatrix.at<float>(2, 3) = 217;
// Mat dummyMatrix = (Mat_<float>(4,4) << -0.90750873, -0.0011025554, 0, 125.93854, 0.39205164, -0.0022058936, 0.00093782519, 43.355019, -0.15074302, 0.00085026468, 0.0024341263, 384.71075, 0,0,0,1);
Mat dummyMatrix = ( Mat_<float>( 4, 4 ) << 0.4830, -0.8756, 0.0077, 125.93854, 0.8365, 0.4588, -0.2996, 43.355019, 0.2588, 0.1511, 0.9540, 384.71075, 0, 0, 0, 1 );
cout << dummyMatrix << endl;
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, videoFilename, calibFilename, objFile ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
// Read the object
if(!objFile.empty())
{
model = glmReadOBJ(objFile.c_str());
if(model != nullptr)
{
drawTeapot = false;
glmUnitize(model);
glmScale(model, 140);
}
}
//******************************************************************
// init the Camera loading the calibration parameters
//******************************************************************
cam.init( calibFilename );
//******************************************************************
// get the corresponding projection matrix in OGL format
//******************************************************************
cam.getOGLProjectionMatrix( gProjectionMatrix, 10.f, 10000.f );
capture.open( videoFilename );
// check if capture has opened the video
if( !capture.isOpened( ) )
{
cerr << "Could not open video file " << videoFilename << endl;
return EXIT_FAILURE;
}
if( !getVideoSizeAndType(videoFilename, capture, singleSize, imgInType ) )
{
cerr << "Something wrong while checking the size and type of the video " << videoFilename << endl;
return EXIT_FAILURE;
}
gResultImage = Mat( singleSize, imgInType );
// Setup GLUT rendering and callbacks
glutInit( &argc, argv );
glutCreateWindow( "Main" );
glutKeyboardFunc( keyFunc );
glutReshapeFunc( reshape );
// reshape the window with the size of the image
glutReshapeWindow( singleSize.width, singleSize.height );
glutDisplayFunc( displayFunc );
glInit( );
gFinished = false;
while( !gFinished )
{
if( !stop )
{
Mat view0;
capture >> view0;
// get a copy of the frame
if( view0.empty( ) )
{
cerr << "no more images available" << endl;
gFinished = true;
break;
}
// undistort( view0, gResultImage, cam.matK, cam.distCoeff );
// process the image
if( tracker.process( view0, cameraPose, cam, boardSize, pattern ) )
{
Mat temp;
cameraPose.convertTo( temp, CV_32F );
PRINTVAR( temp );
temp.copyTo( dummyMatrix.rowRange( 0, 3 ) );
PRINTVAR( dummyMatrix );
// gModelViewMatrix = (float*) Mat(temp.t()).data;
gModelViewMatrix = ( float* ) Mat( dummyMatrix.t( ) ).data;
}
view0.copyTo( gResultImage );
// gModelViewMatrix = (float*) Mat(dummyMatrix.t()).data;
// cout << endl << endl << "****************** frame " << frameNumber << " ******************" << endl;
++frameNumber;
}
// update the texture to be displayed in OPENGL
updateTexture( );
// force Opengl to call the displayFunc
#if __APPLE__
glutCheckLoop( );
#else
glutMainLoopEvent( );
#endif
// sleep for 35ms
std::this_thread::sleep_for(std::chrono::milliseconds(35));
}
capture.release( );
return EXIT_SUCCESS;
}
// Display the help for the programm
void help( const char* programName )
{
cout << "Detect a chessboard in a given video and visualize a teapot on top of it" << endl
<< "Usage: " << programName << endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << endl
<< " -h <board_height> # the number of inner corners per another board dimension" << endl
<< " -c <calib file> # the name of the calibration file" << endl
<< " -o <obj file> # the obj file containing the 3D model to display" << endl
<< " <video file> # the name of the video file" << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile, string &objFile )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
cerr << "Invalid board width" << endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
cerr << "Invalid board height" << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else if( strcmp( s, "-c" ) == 0 )
{
if( i + 1 < argc )
calibFile.assign( argv[++i] );
else
{
cerr << "Missing argument for option " << s << endl;
return false;
}
}
else if( strcmp( s, "-o" ) == 0 )
{
if( i + 1 < argc )
objFile.assign( argv[++i] );
else
{
cerr << "Missing argument for the obj file " << s << endl;
return false;
}
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

471
src/tp/videoOGLTeapot.cpp Normal file
View file

@ -0,0 +1,471 @@
#include "tracker/Camera.hpp"
#include "tracker/ChessboardCameraTracker.hpp"
#include "tracker/ChessboardCameraTrackerKLT.hpp"
#include "tracker/utility.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#ifdef __APPLE__
#include <OpenGL/gl.h>
// #include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
// #include <GL/glu.h>
#include <GL/freeglut.h>
#endif
#include <glm.h>
#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <chrono>
#include <thread>
using namespace std;
using namespace cv;
// Display the help for the programm
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile, string &objFile );
/*
* Common globals
*/
int gFinished;
// the OpenGL reference for the texture to display
GLuint gCameraTextureId;
// the global array containng the explicit modelview matrix
const float *gModelViewMatrix;
// the global array containng the explicit projection matrix
float gProjectionMatrix[16] = {0.f};
// this will physically contain the current frame that is used as texture
Mat gResultImage;
bool stop = false;
// the size of the video frame
Size singleSize;
// OpenGL initialization
void glInit( )
{
//******************************************************************
// enable the depth test
//******************************************************************
glEnable( GL_TEXTURE_2D );
glGenTextures( 1, &gCameraTextureId );
//******************************************************************
// set the Gouraud shading
//******************************************************************
//******************************************************************
// set the LIGHT0 as a simple white, directional light with direction [1,2,-2]
//******************************************************************
//******************************************************************
// set the material properties for the teapot
// choose the values for ambient, diffuse, specular and shininess
// as you prefer. The teapot in the figure has is mainly gray with
// ambient 0.7, diffuse 0.8, specular 1.0 and shininess 100
//******************************************************************
//******************************************************************
// enable the lights
//******************************************************************
//******************************************************************
// set the opengl projection matrix to gProjectionMatrix:
// load the identity and multiply it by gProjectionMatrix using glMultMatrixf
//******************************************************************
//******************************************************************
// set back the modelview mode
//******************************************************************
}
// Updates texture handle gCameraTextureId with OpenCV image in cv::Mat from gResultImage
void updateTexture( )
{
glBindTexture( GL_TEXTURE_2D, gCameraTextureId );
// set texture filter to linear - we do not build mipmaps for speed
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
// create the texture from OpenCV image data
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, singleSize.width, singleSize.height, 0,
#if _WIN32
GL_BGR_EXT,
#else
GL_BGR,
#endif
GL_UNSIGNED_BYTE, gResultImage.data );
}
/**
* Draw the background from the camera image
*/
void drawBackground( )
{
// set up the modelview matrix so that the view is between [-1,-1] and [1,1]
glMatrixMode( GL_PROJECTION );
glPushMatrix( );
glLoadIdentity( );
glOrtho( -1, 1, -1, 1, 0, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
// draw the quad textured with the camera image
glBindTexture( GL_TEXTURE_2D, gCameraTextureId );
glBegin( GL_QUADS );
glTexCoord2f( 0, 1 );
glVertex2f( -1, -1 );
glTexCoord2f( 0, 0 );
glVertex2f( -1, 1 );
glTexCoord2f( 1, 0 );
glVertex2f( 1, 1 );
glTexCoord2f( 1, 1 );
glVertex2f( 1, -1 );
glEnd( );
// reset the projection matrix
glMatrixMode( GL_PROJECTION );
glPopMatrix( );
glMatrixMode( GL_MODELVIEW );
}
/** OpenGL display callback */
void displayFunc( )
{
glClear( GL_COLOR_BUFFER_BIT );
// render the background image from camera texture
glEnable( GL_TEXTURE_2D );
//******************************************************************
// disable the lighting before drawing the background
//******************************************************************
drawBackground( );
// clear th depth buffer bit so that the background is overdrawn
glClear( GL_DEPTH_BUFFER_BIT );
// everything will be white
glColor3f( 1, 1, 1 );
// start with fresh modelview matrix and apply the transform of the plane
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
//******************************************************************
// apply the modelview matrix gModelViewMatrix using glMultMatrixf
//******************************************************************
// enable the texture for a nice effect ;)
glDisable( GL_TEXTURE_2D );
//******************************************************************
// enable the lighting before drawing the teapot/the object
//******************************************************************
//******************************************************************
// draw the teapot (the solid version)
//******************************************************************
glutSwapBuffers( );
glutPostRedisplay( );
}
// Windows resize callback
void reshape( GLint width, GLint height )
{
glViewport( 0, 0, width, height );
}
// Keyboard callback
void keyFunc( unsigned char key, int x, int y )
{
cout << key << " pressed" << endl;
switch( key )
{
case 27:
gFinished = true;
break;
case 's':
stop = !stop;
break;
default:
break;
}
}
int main( int argc, char** argv )
{
/******************************************************************/
/* VARIABLES TO USE */
/******************************************************************/
// it will contain the size in terms of corners (width X height) of the chessboard
Size boardSize;
// Default pattern is chessboard
Pattern pattern = CHESSBOARD;
// the camera
Camera cam;
// the filenames for the video and the calibration
string videoFilename, calibFilename, objFile;
int imgInType;
long frameNumber = 0;
// the video capture
VideoCapture capture;
// the video capture a dummy matrix used to show the teapot in a fix position of the image
Mat dummyMatrix = Mat::eye( 4, 4, CV_32F );
dummyMatrix.at<float>( 1, 1 ) = -1;
dummyMatrix.at<float>( 2, 3 ) = 50;
cout << dummyMatrix << endl;
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, videoFilename, calibFilename, objFile ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
//******************************************************************
// init the Camera loading the calibration parameters
//******************************************************************
//******************************************************************
// get the corresponding projection matrix in OGL format
//******************************************************************
capture.open( videoFilename );
// check if capture has opened the video
if( !capture.isOpened( ) )
{
cerr << "Could not open video file " << videoFilename << endl;
return EXIT_FAILURE;
}
if( !getVideoSizeAndType(videoFilename, capture, singleSize, imgInType ) )
{
cerr << "Something wrong while checking the size and type of the video " << videoFilename << endl;
return EXIT_FAILURE;
}
gResultImage = Mat( singleSize, imgInType );
// Setup GLUT rendering and callbacks
glutInit( &argc, argv );
glutCreateWindow( "Main" );
glutKeyboardFunc( keyFunc );
glutReshapeFunc( reshape );
// reshape the window with the size of the image
glutReshapeWindow( singleSize.width, singleSize.height );
glutDisplayFunc( displayFunc );
glInit( );
gFinished = false;
while( !gFinished )
{
if( !stop )
{
Mat view0;
capture >> view0;
// get a copy of the frame
if( view0.empty( ) )
{
cerr << "no more images available" << endl;
gFinished = true;
break;
}
view0.copyTo( gResultImage );
// set the gModelViewMatrix with the content of the dummy matrix
// OpenGL uses a column-major order for storing the matrix element, while OpenCV uses
// a row major order for storing the elements. Hence we need first to convert the dummy matrix
// to its transpose and only then pass the data pointer to gModelViewMatrix
gModelViewMatrix = ( float* ) Mat( dummyMatrix.t( ) ).data;
cout << endl << endl << "****************** frame " << frameNumber << " ******************" << endl;
++frameNumber;
}
// update the texture to be displayed in OPENGL
updateTexture( );
// force Opengl to call the displayFunc
#if __APPLE__
glutCheckLoop( );
#else
glutMainLoopEvent( );
#endif
// sleep for 35ms
std::this_thread::sleep_for(std::chrono::milliseconds(35));
}
capture.release( );
return EXIT_SUCCESS;
}
// Display the help for the programm
void help( const char* programName )
{
cout << "Detect a chessboard in a given video and visualize a teapot on top of it" << endl
<< "Usage: " << programName << endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << endl
<< " -h <board_height> # the number of inner corners per another board dimension" << endl
<< " -c <calib file> # the name of the calibration file" << endl
<< " [-o <obj file>] # the optional obj file containing the 3D model to display" << endl
<< " <video file> # the name of the video file" << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile, string &objFile )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
cerr << "Invalid board width" << endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
cerr << "Invalid board height" << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else if( strcmp( s, "-c" ) == 0 )
{
if( i + 1 < argc )
calibFile.assign( argv[++i] );
else
{
cerr << "Missing argument for option " << s << endl;
return false;
}
}
else if( strcmp( s, "-o" ) == 0 )
{
if( i + 1 < argc )
objFile.assign( argv[++i] );
else
{
cerr << "Missing argument for the obj file " << s << endl;
return false;
}
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

553
src/tp/videoOGLTracking.cpp Normal file
View file

@ -0,0 +1,553 @@
#include "tracker/Camera.hpp"
#include "tracker/ChessboardCameraTracker.hpp"
#include "tracker/ChessboardCameraTrackerKLT.hpp"
#include "tracker/utility.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#ifdef __APPLE__
#include <OpenGL/gl.h>
// #include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
// #include <GL/glu.h>
#include <GL/freeglut.h>
#endif
#include <glm.h>
#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <chrono>
#include <thread>
using namespace std;
using namespace cv;
// Display the help for the program
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile, string &objFile );
/*
* Common globals
*/
int gFinished;
// the OpenGL reference for the texture to display
GLuint gCameraTextureId;
// the global array containg the explicit modelview matrix
const float *gModelViewMatrix;
// the global array containg the explicit projection matrix
float gProjectionMatrix[16] = {0.f};
// this will physically contain the current frame that is used as texture
Mat gResultImage;
bool stop = false;
// the size of the video frame
Size singleSize;
void DrawAxis( float scale )
{
glPushMatrix( );
glDisable( GL_LIGHTING );
// glDisable(GL_TEXTURE_2D);
glScalef( scale, scale, scale );
glLineWidth( 4.0 );
glBegin( GL_LINES );
glColor3f( 1.f, 0.f, 0.f);
glVertex3f( .8f, .05f, 0.f);
glVertex3f( 1.f, .25f, 0.f); /* Letter X */
glVertex3f( .8f, .25f, 0.f);
glVertex3f( 1.f, .05f, 0.f);
glVertex3f( 0.f, 0.f, 0.f);
glVertex3f( 1.f, 0.f, 0.f); /* X axis */
glColor3f( 0.f, 1.f, 0.f);
glVertex3f( 0.f, 0.f, 0.f);
glVertex3f( 0.f, 1.f, 0.f); /* Y axis */
glColor3f( 0.f, 0.f, 1.f );
glVertex3f( 0.f, 0.f, 0.f);
glVertex3f( 0.f, 0.f, 1.f ); /* Z axis */
glEnd( );
// if (lighting)
glEnable( GL_LIGHTING );
// if (lighting)
// glEnable(GL_TEXTURE_2D);
glColor3f( 1.f, 1.f, 1.f );
glPopMatrix( );
}
void DrawPoints( float scale )
{
glPushMatrix( );
glDisable( GL_LIGHTING );
// glDisable(GL_TEXTURE_2D);
glScalef( scale, scale, scale );
glPointSize( 5 );
glBegin( GL_POINTS );
for( int i = 0; i < 6; i++ )
{
glColor3f( 1.f, ( float ) 40.0f * i / 255.0f, ( float ) 40.0f * i / 255.0f );
for( int j = 0; j < 9; j++ )
glVertex3f( float(j), float(i), 0.f );
}
glEnd( );
// if (lighting)
glEnable( GL_LIGHTING );
// if (lighting)
// glEnable(GL_TEXTURE_2D);
glColor3f( 1.f, 1.f, 1.f );
glPopMatrix( );
}
/**
* OpenGL initialization
*/
void glInit( )
{
//******************************************************************
// enable the depth test
//******************************************************************
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LESS );
glEnable( GL_TEXTURE_2D );
glGenTextures( 1, &gCameraTextureId );
//******************************************************************
// set the Gouraud shading
//******************************************************************
glShadeModel( GL_SMOOTH );
//******************************************************************
// set the LIGHT0 as a simple white, directional light with direction [1,2,-2]
//******************************************************************
GLfloat gLightPos[] = {100.f, 200.f, -200.f, 0.0};
glLightfv( GL_LIGHT0, GL_POSITION, gLightPos );
//******************************************************************
// set the material properties for the teapot
// choose the values for ambient, diffuse, specular and shininess
// as you prefer. The teapot in the figure has is mainly gray with
// ambient 0.7, diffuse 0.8, specular 1.f and shininess 100
//******************************************************************
GLfloat mat_ambient[] = {0.7, 0.7, 0.7, 1.f};
GLfloat mat_diffuse[] = {0.8, 0.8, 0.8, 1.f};
GLfloat mat_specular[] = {1.f, 1.f, 1.f, 1.f};
GLfloat high_shininess[] = {100.0};
glMaterialfv( GL_FRONT, GL_AMBIENT, mat_ambient );
glMaterialfv( GL_FRONT, GL_DIFFUSE, mat_diffuse );
glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );
glMaterialfv( GL_FRONT, GL_SHININESS, high_shininess );
//******************************************************************
// enable the lights
//******************************************************************
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
//******************************************************************
// set the opengl projection matrix to gProjectionMatrix:
// load the identity and multiply it by gProjectionMatrix using glMultMatrixf
//******************************************************************
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
glMultMatrixf( gProjectionMatrix );
//******************************************************************
// set back the modelview mode
//******************************************************************
glMatrixMode( GL_MODELVIEW );
}
// Updates texture handle gCameraTextureId with OpenCV image in cv::Mat from gResultImage
void updateTexture( )
{
glBindTexture( GL_TEXTURE_2D, gCameraTextureId );
// set texture filter to linear - we do not build mipmaps for speed
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
// create the texture from OpenCV image data
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, singleSize.width, singleSize.height, 0,
#if _WIN32
GL_BGR_EXT,
#else
GL_BGR,
#endif
GL_UNSIGNED_BYTE, gResultImage.data );
}
/**
* Draw the background from the camera image
*/
void drawBackground( )
{
// set up the modelview matrix so that the view is between [-1,-1] and [1,1]
glMatrixMode( GL_PROJECTION );
glPushMatrix( );
glLoadIdentity( );
glOrtho( -1, 1, -1, 1, 0, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
// draw the quad textured with the camera image
glBindTexture( GL_TEXTURE_2D, gCameraTextureId );
glBegin( GL_QUADS );
glTexCoord2f( 0, 1 );
glVertex2f( -1, -1 );
glTexCoord2f( 0, 0 );
glVertex2f( -1, 1 );
glTexCoord2f( 1, 0 );
glVertex2f( 1, 1 );
glTexCoord2f( 1, 1 );
glVertex2f( 1, -1 );
glEnd( );
// reset the projection matrix
glMatrixMode( GL_PROJECTION );
glPopMatrix( );
glMatrixMode( GL_MODELVIEW );
}
/** OpenGL display callback */
void displayFunc( )
{
glClear( GL_COLOR_BUFFER_BIT );
// render the background image from camera texture
glEnable( GL_TEXTURE_2D );
//******************************************************************
// disable the lighting before drawing the background
//******************************************************************
glDisable( GL_LIGHTING );
drawBackground( );
// clear th depth buffer bit so that the background is overdrawn
glClear( GL_DEPTH_BUFFER_BIT );
// everything will be white
glColor3f( 1, 1, 1 );
// start with fresh modelview matrix and apply the transform of the plane
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
//******************************************************************
// apply the modelview matrix gModelViewMatrix using glMultMatrixf
//******************************************************************
glMultMatrixf( gModelViewMatrix );
// DrawPoints( 25 );
glRotatef( -90, 1, 0, 0 );
// enable the texture for a nice effect ;)
glDisable( GL_TEXTURE_2D );
//******************************************************************
// enable the lighting before drawing the teapot/the object
//******************************************************************
glEnable( GL_LIGHTING );
// DrawAxis( 100 );
glTranslatef( 0, 50, 0 );
//******************************************************************
// draw the teapot (the solid version)
//******************************************************************
glutSolidTeapot( 45 );
glutSwapBuffers( );
glutPostRedisplay( );
}
// Windows resize callback
void reshape( GLint width, GLint height )
{
glViewport( 0, 0, width, height );
}
// Keyboard callback
void keyFunc( unsigned char key, int x, int y )
{
cout << key << " pressed" << endl;
switch( key )
{
case 27:
gFinished = true;
break;
case 's':
stop = !stop;
break;
default:
break;
}
}
int main( int argc, char** argv )
{
string videoFilename, calibFilename, objFile;
int imgInType;
long frameNumber = 0;
/******************************************************************/
/* VARIABLES TO USE */
/******************************************************************/
// it will contain the size in terms of corners (width X height) of the chessboard
Size boardSize;
// Default pattern is chessboard
Pattern pattern = CHESSBOARD;
// Used to load the video and get the frames
VideoCapture capture;
// Camera object containing the calibration parameters
Camera cam;
// Camera Tracker object
ChessboardCameraTrackerKLT tracker;
// 3x4 camera pose matrix [R t]
Mat cameraPose;
// Mat dummyMatrix = Mat::eye( 4, 4, CV_32F );
// dummyMatrix.at<float>(0, 3) = 102;
// dummyMatrix.at<float>(1, 3) = 46;
// dummyMatrix.at<float>(2, 3) = 217;
// Mat dummyMatrix = (Mat_<float>(4,4) << -0.90750873, -0.0011025554, 0, 125.93854, 0.39205164, -0.0022058936, 0.00093782519, 43.355019, -0.15074302, 0.00085026468, 0.0024341263, 384.71075, 0,0,0,1);
Mat dummyMatrix = ( Mat_<float>( 4, 4 ) << 0.4830, -0.8756, 0.0077, 125.93854, 0.8365, 0.4588, -0.2996, 43.355019, 0.2588, 0.1511, 0.9540, 384.71075, 0, 0, 0, 1 );
cout << dummyMatrix << endl;
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, videoFilename, calibFilename, objFile ) )
{
cerr << "Aborting..." << endl;
return EXIT_FAILURE;
}
//******************************************************************
// init the Camera loading the calibration parameters
//******************************************************************
cam.init( calibFilename );
//******************************************************************
// get the corresponding projection matrix in OGL format
//******************************************************************
cam.getOGLProjectionMatrix( gProjectionMatrix, 10.f, 10000.f );
capture.open( videoFilename );
// check if capture has opened the video
if( !capture.isOpened( ) )
{
cerr << "Could not open video file " << videoFilename << endl;
return EXIT_FAILURE;
}
if( !getVideoSizeAndType(videoFilename, capture, singleSize, imgInType ) )
{
cerr << "Something wrong while checking the size and type of the video " << videoFilename << endl;
return EXIT_FAILURE;
}
gResultImage = Mat( singleSize, imgInType );
// Setup GLUT rendering and callbacks
glutInit( &argc, argv );
glutCreateWindow( "Main" );
glutKeyboardFunc( keyFunc );
glutReshapeFunc( reshape );
// reshape the window with the size of the image
glutReshapeWindow( singleSize.width, singleSize.height );
glutDisplayFunc( displayFunc );
glInit( );
gFinished = false;
while( !gFinished )
{
if( !stop )
{
Mat view0;
capture >> view0;
// get a copy of the frame
if( view0.empty( ) )
{
cerr << "no more images available" << endl;
gFinished = true;
break;
}
// undistort( view0, gResultImage, cam.matK, cam.distCoeff );
// process the image
if( tracker.process( view0, cameraPose, cam, boardSize, pattern ) )
{
Mat temp;
cameraPose.convertTo( temp, CV_32F );
PRINTVAR( temp );
#if CV_MINOR_VERSION < 4
Mat fooMat = dummyMatrix.rowRange( 0, 3 );
temp.copyTo( fooMat );
#else
temp.copyTo( dummyMatrix.rowRange( 0, 3 ) );
#endif
PRINTVAR( dummyMatrix );
// gModelViewMatrix = (float*) Mat(temp.t()).data;
gModelViewMatrix = ( float* ) Mat( dummyMatrix.t( ) ).data;
}
view0.copyTo( gResultImage );
// gModelViewMatrix = (float*) Mat(dummyMatrix.t()).data;
// cout << endl << endl << "****************** frame " << frameNumber << " ******************" << endl;
++frameNumber;
}
// update the texture to be displayed in OPENGL
updateTexture( );
// force Opengl to call the displayFunc
#if __APPLE__
glutCheckLoop( );
#else
glutMainLoopEvent( );
#endif
// sleep for 35ms
std::this_thread::sleep_for(std::chrono::milliseconds(35));
}
capture.release( );
return EXIT_SUCCESS;
}
// Display the help for the programm
void help( const char* programName )
{
cout << "Detect a chessboard in a given video and visualize a teapot on top of it" << endl
<< "Usage: " << programName << endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << endl
<< " -h <board_height> # the number of inner corners per another board dimension" << endl
<< " -c <calib file> # the name of the calibration file" << endl
<< " -o <obj file> # the obj file containing the 3D model to display" << endl
<< " <video file> # the name of the video file" << endl
<< endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, Size &boardSize, string &inputFilename, string &calibFile, string &objFile )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
cerr << "Invalid board width" << endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
cerr << "Invalid board height" << endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign( s );
}
else if( strcmp( s, "-c" ) == 0 )
{
if( i + 1 < argc )
calibFile.assign( argv[++i] );
else
{
cerr << "Missing argument for option " << s << endl;
return false;
}
}
else if( strcmp( s, "-o" ) == 0 )
{
if( i + 1 < argc )
objFile.assign( argv[++i] );
else
{
cerr << "Missing argument for the obj file " << s << endl;
return false;
}
}
else
{
cerr << "Unknown option " << s << endl;
return false;
}
}
return true;
}

View file

@ -0,0 +1,27 @@
#########################################################
#
# OPENCV TUTORIALS
#
#########################################################
add_executable( file_input_output file_input_output.cpp )
target_link_libraries( file_input_output ${OpenCV_LIBS} )
add_executable( load_and_display_video load_and_display_video.cpp )
target_link_libraries( load_and_display_video ${OpenCV_LIBS} )
add_executable( load_and_display_webcam load_and_display_webcam.cpp )
target_link_libraries( load_and_display_webcam ${OpenCV_LIBS} )
add_executable( display_image display_image.cpp )
target_link_libraries( display_image ${OpenCV_LIBS} )
add_executable( load_modify_image load_modify_image.cpp )
target_link_libraries( load_modify_image ${OpenCV_LIBS} )
add_executable( mat_the_basic_image_container mat_the_basic_image_container.cpp )
target_link_libraries( mat_the_basic_image_container ${OpenCV_LIBS} )
add_custom_target( tutorials DEPENDS file_input_output load_and_display_video load_modify_image display_image mat_the_basic_image_container )

View file

@ -0,0 +1,31 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2 )
{
cout << " Usage: display_image ImageToLoadAndDisplay" << endl;
return EXIT_FAILURE;
}
Mat image;
image = imread( argv[1], CV_LOAD_IMAGE_COLOR ); // Read the file
if( image.empty( ) ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return EXIT_FAILURE;
}
namedWindow( "Display window", CV_WINDOW_AUTOSIZE ); // Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
waitKey( 0 ); // Wait for a keystroke in the window
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,72 @@
#include <opencv2/core/core.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
static void help( char** av )
{
cout << endl
<< av[0] << " shows the usage of the OpenCV serialization functionality." << endl
<< "usage: " << endl
<< av[0] << " outputfile.yml.gz" << endl
<< "The output file may be either XML (xml) or YAML (yml/yaml). You can even compress it by "
<< "specifying this in its extension like xml.gz yaml.gz etc... " << endl;
}
int main( int ac, char** av )
{
if( ac != 2 )
{
help( av );
return EXIT_FAILURE;
}
string filename = av[1];
{ //write
Mat R = Mat( 3, 3, CV_8UC3 );
// fill the matrix with uniformly-distributed random values
randu( R, Scalar::all( 0 ), Scalar::all( 255 ) );
Mat T = Mat( 3, 1, CV_32FC3 );
// fill the matrix with normally distributed random values
randn( T, Scalar::all( 0 ), Scalar::all( 1 ) );
FileStorage fs( filename, FileStorage::WRITE );
fs << "R" << R; // cv::Mat
fs << "T" << T;
fs.release( ); // explicit close
cout << "Write Done." << endl;
}
{//read
cout << endl << "Reading: " << endl;
FileStorage fs;
fs.open( filename, FileStorage::READ );
if( !fs.isOpened( ) )
{
cerr << "Failed to open " << filename << endl;
help( av );
return EXIT_FAILURE;
}
Mat R, T;
fs["R"] >> R; // Read cv::Mat
fs["T"] >> T;
cout << endl
<< "R = " << R << endl;
cout << "T = " << T << endl << endl;
}
cout << endl
<< "Tip: Open up " << filename << " with a text editor to see the serialized data." << endl;
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,48 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2 )
{
cout << " Usage: display_video VideoToLoadAndDisplay" << endl;
return EXIT_FAILURE;
}
Mat image;
// Read the file
VideoCapture capture;
capture.open( argv[1] );
// Check if the video is loaded
if( !capture.isOpened( ) )
{
cout << "Could not open or find the video" << std::endl;
return EXIT_FAILURE;
}
cout << "FRAME_WIDTH: " << capture.get( CV_CAP_PROP_FRAME_WIDTH ) << endl;
cout << "FRAME_HEIGHT: " << capture.get( CV_CAP_PROP_FRAME_HEIGHT ) << endl;
cout << "FOURCC: " << capture.get( CV_CAP_PROP_FOURCC ) << endl;
cout << "FPS: " << capture.get( CV_CAP_PROP_FPS ) << endl;
// Create a window for display.
namedWindow( "Display window", CV_WINDOW_AUTOSIZE );
// infinite loop
while( 1 )
{
capture >> image;
//check if there are still frames
if( image.empty( ) )
break;
// Show our image inside it.
imshow( "Display window", image );
if( waitKey( 10 ) == 'q' )
break;
}
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,59 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <stdlib.h>
#include <cctype>
#include <stdio.h>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2 || !isdigit( *argv[1] ) )
{
cout << " Usage: " << argv[0] << " deviceNumber" << endl;
return EXIT_FAILURE;
}
int cameraId = 0;
sscanf( argv[1], "%d", &cameraId );
cout << cameraId << endl;
Mat image;
// Read the file
VideoCapture capture;
capture.open( cameraId );
// Check if the video is loaded
if( !capture.isOpened( ) )
{
cout << "Could not open or find the video" << std::endl;
return EXIT_FAILURE;
}
cout << "FRAME_WIDTH: " << capture.get( CV_CAP_PROP_FRAME_WIDTH ) << endl;
cout << "FRAME_HEIGHT: " << capture.get( CV_CAP_PROP_FRAME_HEIGHT ) << endl;
cout << "FOURCC: " << capture.get( CV_CAP_PROP_FOURCC ) << endl;
cout << "FPS: " << capture.get( CV_CAP_PROP_FPS ) << endl;
// Create a window for display.
capture.set( CV_CAP_PROP_FRAME_WIDTH, 640 );
capture.set( CV_CAP_PROP_FRAME_HEIGHT, 480 );
cout << capture.get( CV_CAP_PROP_FRAME_WIDTH ) << endl;
namedWindow( "Display window", CV_WINDOW_AUTOSIZE );
// infinite loop
while( 1 )
{
capture >> image;
//check if there are still frames
if( image.empty( ) )
break;
// Show our image inside it.
imshow( "Display window", image );
if( waitKey( 10 ) == 'q' )
break;
}
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,37 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
char* imageName = argv[1]; // Read the file
Mat image;
image = imread( imageName, 1 );
if( argc != 2 || image.empty( ) )
{
cerr << " No image data " << endl;
return EXIT_FAILURE;
}
Mat gray_image;
cvtColor( image, gray_image, CV_BGR2GRAY );
imwrite( "../../data/images/Gray_Image.jpg", gray_image );
namedWindow( imageName, CV_WINDOW_AUTOSIZE );
namedWindow( "Gray image", CV_WINDOW_AUTOSIZE );
imshow( imageName, image );
imshow( "Gray image", gray_image );
waitKey( 0 ); // Wait for a keystroke in the window
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,89 @@
/* For description look into the help() function. */
#include "opencv2/core/core.hpp"
#include <iostream>
using namespace std;
using namespace cv;
static void help( )
{
cout
<< "\n--------------------------------------------------------------------------" << endl
<< "This program shows how to create matrices(cv::Mat) in OpenCV and its serial"
<< " out capabilities" << endl
<< "That is, cv::Mat M(...); M.create and cout << M. " << endl
<< "Shows how output can be formated to OpenCV, python, numpy, csv and C styles." << endl
<< "Usage:" << endl
<< "./cvout_sample" << endl
<< "--------------------------------------------------------------------------" << endl
<< endl;
}
int main( int, char** )
{
help( );
// create by using the constructor
Mat M( 2, 2, CV_8UC3, Scalar( 0, 0, 255 ) );
cout << "M = " << endl << " " << M << endl << endl;
// create by using the create function()
M.create( 4, 4, CV_8UC( 2 ) );
cout << "M = " << endl << " " << M << endl << endl;
// create multidimensional matrices
int sz[3] = {2, 2, 2};
Mat L( 3, sz, CV_8UC( 1 ), Scalar::all( 0 ) );
// Cannot print via operator <<
// Create using MATLAB style eye, ones or zero matrix
Mat E = Mat::eye( 4, 4, CV_64F );
cout << "E = " << endl << " " << E << endl << endl;
Mat O = Mat::ones( 2, 2, CV_32F );
cout << "O = " << endl << " " << O << endl << endl;
Mat Z = Mat::zeros( 3, 3, CV_8UC1 );
cout << "Z = " << endl << " " << Z << endl << endl;
// create a 3x3 double-precision identity matrix
Mat C = ( Mat_<double>( 3, 3 ) << 0, -1, 0, -1, 5, -1, 0, -1, 0 );
cout << "C = " << endl << " " << C << endl << endl;
Mat RowClone = C.row( 1 ).clone( );
cout << "RowClone = " << endl << " " << RowClone << endl << endl;
// Fill a matrix with random values
Mat R = Mat( 3, 2, CV_8UC3 );
randu( R, Scalar::all( 0 ), Scalar::all( 255 ) );
// Demonstrate the output formating options
#if CV_MAJOR_VERSION < 3
cout << "R (default) = " << endl << R << endl << endl;
cout << "R (python) = " << endl << format( R, "python" ) << endl << endl;
cout << "R (numpy) = " << endl << format( R, "numpy" ) << endl << endl;
cout << "R (csv) = " << endl << format( R, "csv" ) << endl << endl;
cout << "R (c) = " << endl << format( R, "C" ) << endl << endl;
#endif
Point2f P( 5, 1 );
cout << "Point (2D) = " << P << endl << endl;
Point3f P3f( 2, 6, 7 );
cout << "Point (3D) = " << P3f << endl << endl;
vector<float> v;
v.push_back( ( float ) CV_PI );
v.push_back( 2 );
v.push_back( 3.01f );
cout << "Vector of floats via Mat = " << Mat( v ) << endl << endl;
vector<Point2f> vPoints( 20 );
for( size_t i = 0; i < vPoints.size( ); ++i )
vPoints[i] = Point2f( ( float ) ( i * 5 ), ( float ) ( i % 7 ) );
cout << "A vector of 2D Points = " << vPoints << endl << endl;
return 0;
}

BIN
sujetAR-v2022.1.0.pdf Normal file

Binary file not shown.