├── .gitignore ├── CHANGELOG.rst ├── CMakeLists.txt ├── README.rst ├── TODO ├── apps ├── dbscripts │ ├── copy_db.py │ ├── mesh_add.py │ ├── object_add.py │ ├── object_delete.py │ └── object_search.py ├── detection ├── samples │ ├── generate_pcds.py │ ├── openni_viewer.py │ ├── sample_training.py │ └── source_viewer.py ├── servo_scripts │ ├── move_to.py │ ├── play.py │ └── stop.py ├── testing │ └── nist │ │ └── upload_nist.py └── training ├── cmake ├── install.cmake └── test.cmake.in ├── doc ├── CMakeLists.txt ├── doc_config.py.in └── source │ ├── api │ ├── cells.rst │ ├── db.rst │ ├── detection.rst │ ├── generic.rst │ ├── index.rst │ ├── source_sink.rst │ └── training.rst │ ├── art │ └── or.svg │ ├── conf.py │ ├── detection │ └── detection.rst │ ├── index.rst │ ├── index_developer.rst │ ├── infrastructure │ ├── configuration.rst │ ├── couch.rst │ └── infrastructure.rst │ ├── install.rst │ ├── ork.rosinstall.indigo.jade │ ├── ork.rosinstall.kinetic.plus │ ├── quickguide.rst │ └── training │ └── training.rst ├── include └── object_recognition_core │ ├── common │ ├── dict_json_conversion.h │ ├── json.hpp │ ├── json_spirit │ │ ├── CMakeLists.txt │ │ ├── README │ │ ├── json_spirit.h │ │ ├── json_spirit_error_position.h │ │ ├── json_spirit_reader.cpp │ │ ├── json_spirit_reader.h │ │ ├── json_spirit_reader_template.h │ │ ├── json_spirit_stream_reader.h │ │ ├── json_spirit_utils.h │ │ ├── json_spirit_value.cpp │ │ ├── json_spirit_value.h │ │ ├── json_spirit_writer.cpp │ │ ├── json_spirit_writer.h │ │ └── json_spirit_writer_template.h │ ├── pose_result.h │ ├── types.h │ └── types_eigen.h │ └── db │ ├── ModelReader.h │ ├── db.h │ ├── document.h │ ├── model_utils.h │ ├── opencv.h │ ├── parameters.h │ ├── prototypes │ ├── object_info.h │ └── observations.hpp │ ├── view.h │ └── wrap_object_db.h ├── package.xml ├── python ├── CMakeLists.txt ├── __init__.py.plain.in ├── couchdb ├── couchdb-python │ ├── COPYING │ ├── ChangeLog.txt │ ├── MANIFEST.in │ ├── Makefile │ ├── README.txt │ ├── couchdb │ │ ├── __init__.py │ │ ├── client.py │ │ ├── design.py │ │ ├── http.py │ │ ├── json.py │ │ ├── mapping.py │ │ ├── multipart.py │ │ ├── tests │ │ │ ├── __init__.py │ │ │ ├── client.py │ │ │ ├── couch_tests.py │ │ │ ├── design.py │ │ │ ├── http.py │ │ │ ├── mapping.py │ │ │ ├── multipart.py │ │ │ ├── package.py │ │ │ ├── testutil.py │ │ │ └── view.py │ │ ├── tools │ │ │ ├── __init__.py │ │ │ ├── dump.py │ │ │ ├── load.py │ │ │ └── replicate.py │ │ └── view.py │ ├── doc │ │ ├── Makefile │ │ ├── changes.rst │ │ ├── client.rst │ │ ├── conf.py │ │ ├── getting-started.rst │ │ ├── index.rst │ │ ├── mapping.rst │ │ └── views.rst │ ├── setup.cfg │ └── setup.py └── object_recognition_core │ ├── __init__.py │ ├── db │ ├── __init__.py │ ├── cells.py │ ├── models.py │ ├── object_db.py │ └── tools.py │ ├── filters │ ├── __init__.py │ └── masker.py │ ├── io │ ├── __init__.py │ ├── sink.py │ ├── source.py │ └── voter.py │ ├── pipelines │ ├── __init__.py │ ├── detection.py │ ├── plasm.py │ └── training.py │ └── utils │ ├── __init__.py │ ├── doc.py │ ├── find_classes.py │ ├── json_helper.py │ ├── parser.py │ └── training_detection_args.py ├── setup.py ├── share ├── CMakeLists.txt ├── desktop_test.sh ├── run_test.sh ├── test_config.py ├── test_help.py ├── test_import.py ├── test_sink.py └── test_source.py ├── src ├── CMakeLists.txt ├── common │ ├── CMakeLists.txt │ ├── dict_json_conversion.cpp │ ├── module_python.cpp │ ├── object_info.cpp │ └── wrap_db_pose_result.cpp ├── db │ ├── CMakeLists.txt │ ├── ModelWriter.cpp │ ├── ObservationReader.cpp │ ├── ObservationWriter.cpp │ ├── curl_interface.h │ ├── db.cpp │ ├── db_couch.cpp │ ├── db_couch.h │ ├── db_default.h │ ├── db_empty.h │ ├── db_filesystem.cpp │ ├── db_filesystem.h │ ├── model_utils.cpp │ ├── module.cpp │ ├── module_python.cpp │ ├── observations.cpp │ ├── opencv.cpp │ ├── view.cpp │ ├── wrap_db_documents.cpp │ ├── wrap_db_parameters.cpp │ └── wrap_object_db.cpp ├── filters │ ├── CMakeLists.txt │ ├── depth_filter.cpp │ └── module.cpp ├── io │ ├── Aggregator.cpp │ ├── CMakeLists.txt │ ├── GuessCsvWriter.cpp │ ├── GuessTerminalWriter.cpp │ ├── PipelineInfo.cpp │ ├── csv.cpp │ ├── csv.h │ ├── module.cpp │ └── module_voter.cpp └── pipelines │ ├── CMakeLists.txt │ ├── ConstantPipeline.cpp │ └── module.cpp ├── test ├── CMakeLists.txt ├── db │ ├── CMakeLists.txt │ ├── couch_surfing.py │ ├── db_test.cpp │ ├── db_test.py │ └── main.cpp ├── detection.test.ork ├── test_config.py ├── test_import.py └── view_observations.py └── web_ui ├── CMakeLists.txt ├── _attachments ├── index.html ├── js │ ├── Three.js │ └── jsc3d.js ├── meshes.html └── objects.html ├── _id └── push.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.orig 2 | apps/data/ 3 | *.obj 4 | *.3ds 5 | *.png 6 | *.ply 7 | *.mtl 8 | *.bag 9 | build/ 10 | .* 11 | lib 12 | bin 13 | *.pyc 14 | *.yaml 15 | *.yml 16 | *~ 17 | doc_config.py 18 | -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | 0.6.7 (2017-02-02) 2 | ------------------ 3 | * Merge pull request `#46 `_ from hris2003/master 4 | (fix `#45 `_)(ModelDocument)Get _id field directly from ViewIterator 5 | * (fix)(ModelDocument)Get _id field directly from ViewIterator 6 | * fix the rosinstall files 7 | * Contributors: Ha Dang, Vincent Rabaud 8 | 9 | 0.6.6 (2016-04-24) 10 | ------------------ 11 | * add missing dependencies 12 | * fix doc according to https://github.com/wg-perception/reconstruction/issues/6 13 | * simplify OpenCV3 compatibility 14 | * add citation info in the docs 15 | fixes `#34 `_ 16 | * Contributors: Vincent Rabaud 17 | 18 | 0.6.5 (2015-02-12) 19 | ------------------ 20 | * Properly install test macros 21 | This fixes `#33 `_ 22 | * Don't throw when database is empty 23 | There is no need to throw here. 24 | The function load_fields_and_attachments works quite nicely 25 | for an empty database. The only thing it has to do is return... 26 | This makes it possible to use the rviz plugin OrkObject without 27 | a valid database (This obviously doesn't show meshes or the name then, 28 | but it's still useful as it prints confidence values and the object's key. 29 | * Contributors: Michael Görner, Vincent Rabaud 30 | 31 | 0.6.4 (2015-01-20) 32 | ------------------ 33 | * fix training pipeline creation 34 | * allow unicode strings 35 | this should fix https://github.com/wg-perception/reconstruction/issues/1 36 | * Update installation instruction to add ork_visualization 37 | * add the tutorials on the front page 38 | * get code to work with OpenCV3 39 | * OpenCV 3.0 adaptation 40 | * Contributors: Ha Dang, Vincent Rabaud, edgarriba, nlyubova 41 | 42 | 0.6.3 (2014-09-06) 43 | ------------------ 44 | * Merge pull request `#27 `_ from cottsay/master 45 | Always include ecto.hpp first 46 | * Always include ecto.hpp first 47 | ecto.hpp includes Python.hpp, which must always come before system includes 48 | * adapt docs for ROS distribution 49 | * improve install instructions 50 | This fixes `#25 `_ by only taking non-redundant information 51 | * Contributors: Scott K Logan, Vincent Rabaud 52 | 53 | 0.6.2 (2014-05-13) 54 | ------------------ 55 | * add catkin-sphinx to the docs 56 | * Fixes https://github.com/wg-perception/object_recognition_ros/issues/15 57 | * Fix detection: error: unrecognized arguments: 58 | * Merge pull request `#19 `_ from bit-pirate/master 59 | adds ork_ros to ork.rosinstall 60 | * Contributors: Sammy Pfeiffer, Vincent Rabaud, hdang 61 | 62 | 0.6.1 (2014-04-13) 63 | ------------------ 64 | * get code to compile on Indigo 65 | * allow flexibility in the inputs for the cloud 66 | * improve the viewer for the first load 67 | * fix docs 68 | * replace the mesh viewer by jsc3d 69 | jsc3d is more flexible, handles obj/stl and has a better zoom. 70 | The different possible meshes are also handled better 71 | * fix typo 72 | * install the web UI no matter what 73 | * install the db_scripts 74 | * Contributors: Vincent Rabaud 75 | 76 | 0.6.0 (2013-12-18 21:12:06 +0100) 77 | ---------------------------------- 78 | - fix docs 79 | - better mesh handling 80 | - drop Fuerte support 81 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(object_recognition_core) 3 | 4 | find_package(catkin REQUIRED cmake_modules ecto sensor_msgs) 5 | catkin_package(DEPENDS ecto 6 | CATKIN_DEPENDS sensor_msgs 7 | INCLUDE_DIRS include 8 | LIBRARIES object_recognition_core_db object_recognition_core_common 9 | CFG_EXTRAS test.cmake 10 | ) 11 | 12 | #install targets for all things python 13 | catkin_python_setup() 14 | 15 | add_subdirectory(python) 16 | 17 | add_definitions("-Wno-pragmas -fno-strict-aliasing -Wall -Wl,--no-undefined -Werror") 18 | 19 | find_package(Boost REQUIRED system filesystem serialization) 20 | find_package(OpenCV REQUIRED) 21 | 22 | include_directories(SYSTEM ${Boost_INCLUDE_DIRS} 23 | ${OpenCV_INCLUDE_DIRS} 24 | ) 25 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${catkin_INCLUDE_DIRS}) 26 | 27 | add_subdirectory(src) 28 | add_subdirectory(web_ui) 29 | 30 | #these setup the lib to be used by others 31 | include(cmake/install.cmake) 32 | 33 | # add tests 34 | add_subdirectory(share) 35 | if(CATKIN_ENABLE_TESTING) 36 | add_subdirectory(test) 37 | endif() 38 | 39 | # build docs 40 | add_subdirectory(doc) 41 | catkin_doxygen(object_recognition_core-doxygen ${CMAKE_CURRENT_SOURCE_DIR}/include) 42 | 43 | # Use the ecto scripts to build top-level documentation 44 | set(ecto_SPHINX_DIR ${CMAKE_CURRENT_SOURCE_DIR}/doc/source) 45 | ecto_sphinx(${CMAKE_CURRENT_SOURCE_DIR}/doc/source doc) 46 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Object Recognition 2 | ================== 3 | 4 | Please see http://ecto.willowgarage.com/recognition. 5 | 6 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | ecto: 2 | update the docs to say devel is done but still maintained 3 | 4 | Build: 5 | - no default build of tutorials 6 | - split the tests (db tests should at least be separated) 7 | 8 | Interface: 9 | - create a simple graph plasm viewer for ORK 10 | - get the ecto_gooey to work with ORK 11 | 12 | Performance: 13 | - Mike's stuff 14 | 15 | DB: 16 | - move to a system dependency with python-couchdb after Fuerte (dropping Oneiric support) 17 | - delete things from the DB, find orphans, find missing components (models ...), find duplicates 18 | - better object representation (model, inline images, 3d models ...) 19 | - HTML - see the model_viewer under apps. Its a couch app, we can make it do whatever. 20 | Currently have something for viewing the meshes, and something for viewing the objects. 21 | - be able to only replicate models in a DB (to put on the PR2) 22 | - add meta data that is missing (meet with everybody). We want: timestamp of the session, the sensor id 23 | - use a single view for all model types 24 | - is models.py obsolete? Soonish with the view to find observations 25 | - make more db manipulation scripts apps/dbscripts ... FIXME don't break these. 26 | 27 | Capture: 28 | - upload through the capture GUI. Also have the triggering of all the other models (RabbitMQ ...) 29 | - should be a parameter file for the type of fiducials 30 | 31 | Doc: 32 | - write docs for ecto_gooey 33 | 34 | New cells: 35 | - masks, filters 36 | - Mike's stuff 37 | 38 | Test: 39 | - ground truth format? Look at NIST CSV. Possibly come up with bag format too, where each frame has a listing of object id and pose relative to the sensor 40 | - ground truth capture... Use the NIST Ponoko rig to capture scenes with GT poses. Needs a simple app or something. 41 | - fix tests in /test that are unused 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | (ROS) logging everything happening between the Python launch and when the plasm starts 59 | the automatic docs should use the parameters from the cell only, and have a function to overload 60 | doc_config belongs to python_or_core 61 | -------------------------------------------------------------------------------- /apps/dbscripts/copy_db.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import object_recognition 3 | from object_recognition import tools as dbtools 4 | import couchdb 5 | import argparse 6 | 7 | def parse_args(): 8 | parser = argparse.ArgumentParser(description='Copies docs from one db to another.') 9 | parser.add_argument('--remote', dest='remote', type=str, 10 | help='Remote db to copy from.') 11 | parser.add_argument('--remote_collection', 12 | dest='remote_collection', type=str, 13 | help='Remote collection.') 14 | object_recognition.dbtools.add_db_arguments(parser) 15 | args = parser.parse_args() 16 | return args 17 | 18 | if __name__ == "__main__": 19 | args = parse_args() 20 | couch = couchdb.Server(args.db_root) 21 | remote_couch = couchdb.Server(args.remote) 22 | local_db = dbtools.init_object_databases(couch) 23 | remote_db = remote_couch[args.remote_collection] 24 | results = remote_db.view('_all_docs') 25 | total_docs = len(results) 26 | i = 1 27 | for x in results: 28 | doc = remote_db.get(x.id) 29 | doc = doc.copy() 30 | 31 | attachments = doc.get('_attachments',False) 32 | if attachments: 33 | del doc['_attachments'] 34 | if x.id not in local_db: 35 | (doc_id,rev) = local_db.save(doc) 36 | if attachments: 37 | for key,val in attachments.iteritems(): 38 | flo = remote_db.get_attachment(x.id,key) 39 | doc = local_db.get(x.id) 40 | local_db.put_attachment(doc,flo,key,val['content_type']) 41 | print '%d out of %d'%(i,total_docs) 42 | i += 1 43 | 44 | -------------------------------------------------------------------------------- /apps/dbscripts/mesh_add.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Script that adds a mesh to an object in the database 3 | 4 | from __future__ import print_function 5 | import argparse 6 | from object_recognition_core.db import models 7 | from object_recognition_core.db.tools import args_to_db_params 8 | import object_recognition_core.db.tools as dbtools 9 | import couchdb 10 | 11 | def parse_args(): 12 | parser = argparse.ArgumentParser(description='Add a mesh to an object.', fromfile_prefix_chars='@') 13 | parser.add_argument('object_id', metavar='OBJECT_ID', type=str, help='ID of the object to add a mesh to.') 14 | parser.add_argument('mesh_original', metavar='MESH_ORIGINAL', type=str, help='Original mesh of the object.') 15 | dbtools.add_db_arguments(parser) 16 | 17 | args = parser.parse_args() 18 | 19 | return args 20 | 21 | if __name__ == '__main__': 22 | args = parse_args() 23 | 24 | couch = couchdb.Server(args.db_root) 25 | db = dbtools.init_object_databases(couch) 26 | if args.commit: 27 | dbtools.upload_mesh(db, args.object_id, args.mesh_original, cloud_path=None, mesh_path=None) 28 | print('Stored mesh for object id :', args.object_id) 29 | else: 30 | print('Use the --commit option to commit the proposed change.') 31 | -------------------------------------------------------------------------------- /apps/dbscripts/object_add.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Script that adds an object to the database 3 | 4 | from __future__ import print_function 5 | import os, sys, argparse 6 | from object_recognition_core.db import models 7 | from object_recognition_core.db.tools import args_to_db_params 8 | import object_recognition_core.db.tools as dbtools 9 | import couchdb 10 | 11 | def parse_args(): 12 | parser = argparse.ArgumentParser(description='Add an object to the db.', 13 | fromfile_prefix_chars='@') 14 | parser.add_argument('-n', '--object_name', metavar='OBJECT_NAME', dest='object_name', type=str, default='') 15 | parser.add_argument('-d', '--description', metavar='DESCRIPTION', dest='description', type=str, default='') 16 | parser.add_argument('-a', '--author', metavar='AUTHOR_NAME', dest='author_name', type=str, default='') 17 | parser.add_argument('-e', '--email', metavar='EMAIL_ADDRESS', dest='author_email', type=str, default='') 18 | parser.add_argument('tags', metavar='TAGS', type=str, nargs='*', help='Tags to add to object description.') 19 | dbtools.add_db_arguments(parser) 20 | 21 | args = parser.parse_args() 22 | 23 | return args 24 | 25 | if __name__ == '__main__': 26 | args = parse_args() 27 | obj = models.Object(object_name=args.object_name, 28 | description=args.description, 29 | tags=args.tags, 30 | author_name=args.author_name, 31 | author_email=args.author_email, 32 | ) 33 | 34 | couch = couchdb.Server(args.db_root) 35 | db = dbtools.init_object_databases(couch) 36 | objects = db 37 | existing = models.Object.by_object_name(objects, key=obj.object_name) 38 | store_new = True 39 | if len(existing) > 0: 40 | print('It appears that there are %d object(s) with the same name.' % len(existing)) 41 | for x in existing: 42 | print(x) 43 | print('Use the object id above? [y,n]') 44 | use_it = raw_input('') 45 | if 'y' in use_it.lower(): 46 | store_new = False 47 | obj = x 48 | break 49 | else: 50 | store_new = True 51 | if store_new: 52 | if args.commit: 53 | obj.store(objects) 54 | print('Stored new object with id:', obj.id) 55 | else: 56 | print('Use the --commit option to commit the proposed change.') 57 | -------------------------------------------------------------------------------- /apps/dbscripts/object_delete.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Script that adds an object to the database 3 | 4 | from __future__ import print_function 5 | import object_recognition_core.db.tools as dbtools 6 | import couchdb 7 | import argparse 8 | 9 | def parse_args(): 10 | parser = argparse.ArgumentParser(description='Delete objects from the database.') 11 | parser.add_argument('objects', metavar='OBJECTS', type=str, nargs='+', 12 | help='Object ids to delete.') 13 | dbtools.add_db_arguments(parser) 14 | args = parser.parse_args() 15 | return args 16 | 17 | def deletion_view(db): 18 | view = couchdb.design.ViewDefinition('object_recognition', 'refer_object_id', '''function(doc) { 19 | if (doc.object_id) 20 | emit(doc.object_id, doc); 21 | }''') 22 | view.sync(db) 23 | 24 | def delete_object(db, object_ids, commit): 25 | for object_id in object_ids: 26 | for row in db.view('object_recognition/refer_object_id', key=object_id): 27 | print('Deleting doc: %s of type "%s" referring to object: %s' % (row.id, row.value['Type'], row.key)) 28 | if commit: 29 | del db[row.id] 30 | if not db.get(object_id): 31 | print("No object by id", object_id, "found!") 32 | elif commit: 33 | print("Deleting object:", object_id) 34 | del db[object_id] 35 | 36 | if __name__ == "__main__": 37 | args = parse_args() 38 | couch = couchdb.Server(args.db_root) 39 | db = dbtools.init_object_databases(couch) 40 | deletion_view(db) 41 | delete_object(db, args.objects, args.commit) 42 | if not args.commit: 43 | print('just kidding. --commit to actually do it.') 44 | -------------------------------------------------------------------------------- /apps/dbscripts/object_search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import object_recognition_core 3 | from object_recognition_core.db import tools as dbtools, models 4 | import couchdb 5 | import argparse 6 | 7 | def parse_args(): 8 | parser = argparse.ArgumentParser(description='Search for an objects in the DB based on tags..') 9 | parser.add_argument('-t', '--tag', metavar='TAG', dest='tag', type=str, default='', 10 | help='Tag to search for.') 11 | dbtools.add_db_arguments(parser) 12 | args = parser.parse_args() 13 | return args 14 | 15 | if __name__ == "__main__": 16 | args = parse_args() 17 | couch = couchdb.Server(args.db_root) 18 | db = dbtools.init_object_databases(couch) 19 | if len(args.tag) > 0: 20 | results = models.Object.by_tag(db, key=args.tag) 21 | else: 22 | results = models.Object.by_object_name(db) 23 | for obj in results: 24 | print "******************************" 25 | print "Object Name:", obj.object_name 26 | print "Description:", obj.description 27 | print "Tags:", ','.join(obj.tags) 28 | print "Author:", obj.author_name 29 | print "email:", obj.author_email 30 | print "db id:", obj.id 31 | print "session ids:", [session.id for session in models.Session.by_object_id(db, key=obj.id)] 32 | -------------------------------------------------------------------------------- /apps/detection: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | This script launches several detection pipelines defined in a configuration file to detect several objects in a 4 | common snapshot of data 5 | """ 6 | from object_recognition_core.pipelines.plasm import create_plasm 7 | from object_recognition_core.utils.training_detection_args import create_parser, read_arguments 8 | from ecto.opts import scheduler_options, run_plasm 9 | import argparse 10 | 11 | if __name__ == '__main__': 12 | # create an ORK parser (it is special as it can read from option files) 13 | parser = create_parser() 14 | 15 | # add ecto options 16 | scheduler_options(parser) 17 | 18 | # create the plasm that will run the detection 19 | args = parser.parse_args() 20 | ork_params, _args = read_arguments(args) 21 | plasm = create_plasm(ork_params) 22 | 23 | # run the detection plasm 24 | run_plasm(args, plasm) 25 | -------------------------------------------------------------------------------- /apps/samples/openni_viewer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import ecto 3 | from ecto_opencv.highgui import imshow 4 | from ecto_opencv.calib import DepthTo3d 5 | from image_pipeline import Rectifier, StereoModelLoader, DepthRegister, CameraModelToCv, CV_INTER_NN 6 | from ecto_openni import OpenNICapture, DEPTH_RGB, DEPTH_IR, RGB, IR, IRGamma, enumerate_devices 7 | from image_pipeline_conversion import MatToPointCloudXYZRGB 8 | from ecto_pcl import PointCloudT2PointCloud, CloudViewer, XYZRGB 9 | 10 | openni_reg = True 11 | print enumerate_devices() 12 | 13 | capture = OpenNICapture('Camera',stream_mode=DEPTH_RGB, registration=openni_reg, latched=False) 14 | depthTo3d = DepthTo3d('Depth ~> 3d') 15 | to_xyzrgb = MatToPointCloudXYZRGB('OpenCV ~> PCL') 16 | pcl_cloud = PointCloudT2PointCloud('conversion',format=XYZRGB) 17 | cloud_viewer = CloudViewer('Cloud Display') 18 | 19 | 20 | plasm = ecto.Plasm() 21 | plasm.connect(capture['K'] >> depthTo3d['K'], 22 | capture['image'] >> imshow('Image Display')[:], 23 | capture['depth'] >> depthTo3d['depth'], 24 | depthTo3d['points3d'] >> to_xyzrgb['points'], 25 | capture['image'] >> to_xyzrgb['image'], 26 | to_xyzrgb[:] >> pcl_cloud[:], 27 | pcl_cloud[:] >> cloud_viewer[:] 28 | ) 29 | 30 | if __name__ == '__main__': 31 | from ecto.opts import doit 32 | doit(plasm, description='Capture Kinect depth and RGB and register them.', locals=vars()) 33 | -------------------------------------------------------------------------------- /apps/samples/sample_training.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import ecto 3 | import sys 4 | import couchdb 5 | from ecto_opencv.highgui import imshow, ImageSaver 6 | from ecto_object_recognition import capture 7 | from object_recognition import models, tools as dbtools 8 | import ecto_opencv 9 | import os 10 | 11 | def parse_args(): 12 | import argparse 13 | parser = argparse.ArgumentParser(description='Train MyAlgorithm on views from the database.') 14 | parser.add_argument('objects', metavar='OBJECT', type=str, nargs='+', 15 | help='Object ids to train.') 16 | dbtools.add_db_arguments(parser) 17 | args = parser.parse_args() 18 | return args 19 | 20 | args = parse_args() 21 | db = dbtools.init_object_databases(couchdb.Server(args.db_root)) 22 | 23 | for object_id in args.objects: 24 | #get a list of observation ids for a particular object id. 25 | obs_ids = models.find_all_observations_for_object(db, object_id) 26 | 27 | if not obs_ids: 28 | print 'No observations found for object %s.' % object_id 29 | continue 30 | 31 | plasm = ecto.Plasm() 32 | #the db_reader transforms observation id into a set of image,depth,mask,K,R,T 33 | db_reader = capture.ObservationReader("db_reader", db_params=dbtools.args_to_db_params(args)) 34 | #this iterates over all of the observation ids. 35 | observation_dealer = ecto.Dealer(tendril=db_reader.inputs.at('observation'), iterable=obs_ids) 36 | 37 | plasm.connect(observation_dealer[:] >> db_reader['observation']) 38 | 39 | path_names = [ 'image', 'depth', 'mask'] 40 | for path_name in path_names: 41 | path = os.path.join(object_id, path_name) 42 | if not os.path.exists(path): 43 | os.makedirs(path) 44 | writer_image = ImageSaver(filename_format=os.path.join(path, '%05d.png'))[:] 45 | plasm.connect(db_reader[path_name] >> (writer_image, imshow(name=path_name)['image'])) 46 | 47 | sched = ecto.schedulers.Singlethreaded(plasm) 48 | sched.execute() 49 | 50 | # write files listing the produced files 51 | for path_name in path_names: 52 | file_object = open(os.path.join(os.getcwd(), object_id, path_name + '.txt'), 'w') 53 | for file_name in [ os.path.join(os.getcwd(), object_id, path_name, file_name) 54 | for file_name in os.listdir(os.path.join(object_id, path_name)) 55 | if file_name.endswith('png') ]: 56 | file_object.write(file_name + '\n') 57 | file_object.close 58 | 59 | #After done execution upload the resulting model to the db.... 60 | -------------------------------------------------------------------------------- /apps/samples/source_viewer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import ecto 3 | from ecto_opencv.highgui import imshow 4 | from ecto_openni import OpenNICapture, DEPTH_RGB, enumerate_devices 5 | from image_pipeline_conversion import MatToPointCloudXYZRGB 6 | from ecto_pcl import PointCloudT2PointCloud, CloudViewer, XYZRGB 7 | from object_recognition.common.io.standalone import OpenNISource 8 | 9 | capture = OpenNISource() 10 | to_xyzrgb = MatToPointCloudXYZRGB('OpenCV ~> PCL') 11 | pcl_cloud = PointCloudT2PointCloud('conversion', format=XYZRGB) 12 | cloud_viewer = CloudViewer('Cloud Display') 13 | 14 | plasm = ecto.Plasm() 15 | plasm.connect(capture['image'] >> imshow('Image Display')[:], 16 | capture['points3d'] >> to_xyzrgb['points'], 17 | capture['image'] >> to_xyzrgb['image'], 18 | to_xyzrgb[:] >> pcl_cloud[:], 19 | pcl_cloud[:] >> cloud_viewer[:] 20 | ) 21 | 22 | if __name__ == '__main__': 23 | from ecto.opts import doit 24 | doit(plasm, description='Capture Kinect depth and RGB and register them.', locals=vars()) 25 | -------------------------------------------------------------------------------- /apps/servo_scripts/move_to.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python 2 | 3 | from object_recognition.capture.arbotix import * 4 | import time 5 | 6 | MY_SERVO = 0xE9 7 | a = ArbotiX("/dev/ttyUSB0") 8 | a.disableWheelMode(MY_SERVO,resolution=12) 9 | a.setSpeed(MY_SERVO,100) 10 | a.setPosition(MY_SERVO,0) 11 | time.sleep(1) 12 | a.setPosition(MY_SERVO,4095) 13 | a.disableTorque(MY_SERVO) 14 | 15 | -------------------------------------------------------------------------------- /apps/servo_scripts/play.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from object_recognition.capture.arbotix import * 3 | import sys 4 | MY_SERVO = 0xE9 5 | a = ArbotiX("/dev/ttyUSB0",baud=1e6) #1 meg for e 6 | a.enableWheelMode(MY_SERVO) 7 | speed = 32 8 | if len(sys.argv) > 1: 9 | speed = int(sys.argv[1]) 10 | a.setSpeed(MY_SERVO,speed) 11 | 12 | -------------------------------------------------------------------------------- /apps/servo_scripts/stop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from object_recognition.capture.arbotix import * 3 | 4 | MY_SERVO = 0xE9 5 | 6 | a = ArbotiX("/dev/ttyUSB0",baud=1e6) 7 | a.disableTorque(MY_SERVO) 8 | 9 | -------------------------------------------------------------------------------- /apps/training: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | This script launches several training pipelines defined in a configuration file to train several models for several 4 | objects 5 | """ 6 | from __future__ import print_function 7 | from object_recognition_core.db import ObjectDb, ObjectDbParameters, ObjectDbTypes, models 8 | from object_recognition_core.db.tools import interpret_object_ids, init_object_databases 9 | from object_recognition_core.pipelines.plasm import create_plasm 10 | from object_recognition_core.utils.find_classes import find_class 11 | from object_recognition_core.utils.training_detection_args import create_parser, read_arguments 12 | import ecto 13 | import sys 14 | 15 | if __name__ == '__main__': 16 | parser = create_parser(do_training=True) 17 | 18 | args = parser.parse_args() 19 | ork_params, _args = read_arguments(args) 20 | 21 | for _pipeline_id, pipeline_param in ork_params.iteritems(): 22 | pipeline_class = find_class([ pipeline_param['module'] ], pipeline_param['type'] ) 23 | if not pipeline_class: 24 | raise RuntimeError('Invalid pipeline name: %s\nMake sure that the pipeline type is defined by a ' 25 | 'TrainingPipeline class, in the name class function.' % pipeline_param['type']) 26 | 27 | db_params_raw = pipeline_param['parameters'].get('json_db', {}) 28 | db_params = db_params_raw 29 | object_ids = interpret_object_ids(db_params, pipeline_param.get('parameters', {}).get('json_object_ids', [])) 30 | print('Training %d objects.' % len(object_ids)) 31 | for object_id in object_ids: 32 | print('computing object_id: %s' % object_id) 33 | object_id = object_id.encode('ascii') 34 | 35 | ork_params_sub = {} 36 | ork_params_sub[_pipeline_id] = pipeline_param 37 | ork_params_sub[_pipeline_id]['parameters']['object_id'] = object_id 38 | plasm = create_plasm(ork_params_sub) 39 | plasm.execute() 40 | 41 | # Make sure the views exist 42 | object_db = ObjectDb(db_params) 43 | db_params = ObjectDbParameters(db_params) 44 | if db_params.type == ObjectDbTypes.COUCHDB: 45 | import couchdb 46 | import json 47 | dic = json.loads(db_params_raw) 48 | couch = couchdb.Server(dic['root']) 49 | init_object_databases(couch) 50 | -------------------------------------------------------------------------------- /cmake/install.cmake: -------------------------------------------------------------------------------- 1 | # install the include folder 2 | install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/object_recognition_core/ 3 | DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} 4 | COMPONENT main 5 | ) 6 | 7 | # install the applications 8 | install(PROGRAMS ${PROJECT_SOURCE_DIR}/apps/detection 9 | ${PROJECT_SOURCE_DIR}/apps/training 10 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 11 | ) 12 | 13 | # install the DB scripts 14 | install(DIRECTORY ${PROJECT_SOURCE_DIR}/apps/dbscripts 15 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 16 | COMPONENT main 17 | USE_SOURCE_PERMISSIONS 18 | ) 19 | -------------------------------------------------------------------------------- /cmake/test.cmake.in: -------------------------------------------------------------------------------- 1 | set(SETUP_DOT_SH ${CATKIN_DEVEL_PREFIX}/setup.sh) 2 | 3 | if (object_recognition_core_SOURCE_DIR) 4 | get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 5 | set(object_recognition_core_TEST_DIR ${SELF_DIR}/../test) 6 | else() 7 | get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 8 | set(object_recognition_core_TEST_DIR ${SELF_DIR}/../test) 9 | endif() 10 | 11 | #testing macros 12 | macro(object_recognition_core_pytest pyfile) 13 | string(REPLACE ";" " " args "${ARGN}") 14 | add_test(${PROJECT_NAME}_${pyfile}.py 15 | ${object_recognition_core_TEST_DIR}/run_test.sh ${SETUP_DOT_SH} ${CMAKE_CURRENT_SOURCE_DIR}/${pyfile}.py ${args} 16 | ) 17 | endmacro() 18 | 19 | macro(object_recognition_core_desktop_test pyfile) 20 | if(DESKTOP_TEST) 21 | string(REPLACE ";" " " args "${ARGN}") 22 | add_test(desktop_${PROJECT_NAME}_${pyfile}.py 23 | ${object_recognition_core_TEST_DIR}/run_test.sh ${SETUP_DOT_SH} ${CMAKE_CURRENT_SOURCE_DIR}/${pyfile}.py ${args} 24 | ) 25 | endif(DESKTOP_TEST) 26 | endmacro() 27 | 28 | macro(object_recognition_core_data_download PATH_VAR DATA_FILE) 29 | set(data_base_url http://vault.willowgarage.com/wgdata1/vol1/ecto_data) 30 | set(${PATH_VAR} ${PROJECT_BINARY_DIR}/data/${DATA_FILE}) 31 | if(NOT EXISTS ${${PATH_VAR}}) 32 | message(STATUS "Data fetch.\n** Downloading:\n** ${data_base_url}/${DATA_FILE}\n** to:\n** ${${PATH_VAR}}") 33 | file(DOWNLOAD ${data_base_url}/${DATA_FILE} ${${PATH_VAR}}) 34 | endif() 35 | endmacro() 36 | 37 | # macro testing an ORK configuration file 38 | macro(object_recognition_core_config_test config_file) 39 | add_test(${PROJECT_NAME}_${config_file} 40 | ${object_recognition_core_TEST_DIR}/run_test.sh ${SETUP_DOT_SH} "${object_recognition_core_TEST_DIR}/test_config.py -c ${config_file}" 41 | ) 42 | endmacro() 43 | 44 | # macro testing a script with --help: "script" must contain the whole path 45 | macro(object_recognition_core_help_test script) 46 | add_test(${PROJECT_NAME}_help_${script} 47 | ${object_recognition_core_TEST_DIR}/run_test.sh ${SETUP_DOT_SH} "${object_recognition_core_TEST_DIR}/test_help.py ${script}" 48 | ) 49 | endmacro() 50 | 51 | # macro testing a Source 52 | # the first argument is the value returned by type_name 53 | # the second argument is the Python module in which to find that source 54 | # the third argument is a string of the dict used for parameters: has to be set to "{}" if none 55 | macro(object_recognition_core_source_test source_name package_name parameters) 56 | add_test(${PROJECT_NAME}_source_${source_name} 57 | ${object_recognition_core_TEST_DIR}/run_test.sh ${SETUP_DOT_SH} "${object_recognition_core_TEST_DIR}/test_source.py ${source_name} ${package_name} ${parameters}" 58 | ) 59 | endmacro() 60 | 61 | # macro testing a Sink 62 | # the first argument is the value returned by type_name 63 | # the second argument is the Python module in which to find that sink 64 | # the third argument is a string of the dict used for parameters: has to be set to "{}" if none 65 | macro(object_recognition_core_sink_test sink_name package_name parameters) 66 | add_test(${PROJECT_NAME}_sink_${sink_name} 67 | ${object_recognition_core_TEST_DIR}/run_test.sh ${SETUP_DOT_SH} "${object_recognition_core_TEST_DIR}/test_sink.py ${sink_name} ${package_name} ${parameters}" 68 | ) 69 | endmacro() 70 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2011, Willow Garage, Inc. 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions are met: 7 | # * Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # * Redistributions in binary form must reproduce the above copyright 10 | # notice, this list of conditions and the following disclaimer in the 11 | # documentation and/or other materials provided with the distribution. 12 | # * Neither the name of the Willow Garage, Inc. nor the names of its 13 | # contributors may be used to endorse or promote products derived from 14 | # this software without specific prior written permission. 15 | # 16 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | # POSSIBILITY OF SUCH DAMAGE. 27 | # 28 | #these are used by the docs. 29 | configure_file(doc_config.py.in ${CMAKE_CURRENT_SOURCE_DIR}/source/doc_config.py) 30 | -------------------------------------------------------------------------------- /doc/doc_config.py.in: -------------------------------------------------------------------------------- 1 | version='${${PROJECT_NAME}_GITTAG_SHORT}' 2 | commithash='${${PROJECT_NAME}_COMMITHASH}' 3 | gittag_short='${${PROJECT_NAME}_GITTAG_SHORT}' 4 | gittag_long='${${PROJECT_NAME}_GITTAG_LONG}' 5 | git_lastmod='${${PROJECT_NAME}_LAST_MODIFIED}' 6 | github_url='${${PROJECT_NAME}_GITHUB_URL}' 7 | 8 | breathe_default_project = '${PROJECT_NAME}' 9 | breathe_projects = dict(object_recognition_core='${CMAKE_CURRENT_BINARY_DIR}/../api/xml') 10 | 11 | # for release 12 | ork_module_url_root = 'http://wg-perception.github.com/' 13 | 14 | intersphinx_mapping = {'orkcapture': (ork_module_url_root + 'capture', None), 15 | 'orklinemod': (ork_module_url_root + 'linemod', None), 16 | 'orkreconstruction': (ork_module_url_root + 'reconstruction', None), 17 | 'orkros': (ork_module_url_root + 'object_recognition_ros', None), 18 | 'orktabletop': (ork_module_url_root + 'tabletop', None), 19 | 'orktod': (ork_module_url_root + 'tod', None), 20 | 'orktransparentobjects': (ork_module_url_root + 'transparent_objects', None), 21 | 'orktutorials': (ork_module_url_root + 'ork_tutorials', None), 22 | } 23 | 24 | programoutput_path = '${DOC_SOURCE_DIRS}'.split(';') 25 | -------------------------------------------------------------------------------- /doc/source/api/cells.rst: -------------------------------------------------------------------------------- 1 | Cells API 2 | ========= 3 | 4 | .. ectomodule:: object_recognition_core.ecto_cells.db 5 | 6 | .. ectomodule:: object_recognition_core.ecto_cells.io 7 | 8 | .. ectomodule:: object_recognition_ros.ecto_cells.io_ros 9 | 10 | .. ectomodule:: object_recognition_core.ecto_cells.filters 11 | 12 | .. ectomodule:: object_recognition_core.ecto_cells.voter 13 | -------------------------------------------------------------------------------- /doc/source/api/db.rst: -------------------------------------------------------------------------------- 1 | DB API 2 | ====== 3 | 4 | Core Types 5 | ---------- 6 | 7 | .. doxygenclass:: object_recognition_core::db::ObjectDb 8 | :project: object_recognition_core 9 | :members: 10 | 11 | 12 | .. doxygenclass:: object_recognition_core::db::ObjectDbParameters 13 | :project: object_recognition_core 14 | :members: 15 | 16 | 17 | .. doxygenclass:: object_recognition_core::db::Document 18 | :project: object_recognition_core 19 | :members: 20 | 21 | Implementing your own DB type 22 | ----------------------------- 23 | 24 | If you want to create your own DB type, look at the examples from the core like CouchDb or filesystem. 25 | You just have to inherit from ``ObjectDb``. 26 | -------------------------------------------------------------------------------- /doc/source/api/detection.rst: -------------------------------------------------------------------------------- 1 | Detection 2 | ========= 3 | 4 | To implement a detection pipeline runnable with the object recognition infrastructure you will need a Python script that implements a plasm for your pipeline. To ease the implementation, we describe a simple way way to retrieve models from the database, as well as the output format of the pipeline. 5 | 6 | Python Plasm 7 | ------------ 8 | 9 | Your pipeline has to provide an implementation of the :py:class:`object_recognition_core.pipelines.detection.DetectionPipeline` class to be fully integrated with object recognition infrastructure: 10 | 11 | .. autoclass:: object_recognition_core.pipelines.detection.DetectorBase 12 | :members: 13 | 14 | By providing so, after parsing the config file, the detection script will be able to find/load you cell when present on the PYTHONPATH. 15 | 16 | Database Cell 17 | ------------- 18 | 19 | If you are using the predefined ModelWriter for training, you will also want to use our ModelReader for simplicity. 20 | 21 | Step 1 22 | ^^^^^^ 23 | 24 | The cell is bit different from the ModelWriter as it reads several models at once. It has to inherit from 25 | ``db::bases::ModelReaderImpl``. An example implementation is: 26 | 27 | .. code-block:: cpp 28 | :linenos: 29 | 30 | struct MyAwesomeModelReaderImpl: public db::bases::ModelReaderImpl 31 | { 32 | public: 33 | // This function gives you db_documents for each model from which you can extract the information you want and 34 | // store it locally (maybe in a search structure) 35 | void 36 | ParameterCallback(const Documents & db_documents) 37 | { 38 | // Stacking the models, or building a search structure ... 39 | } 40 | 41 | // The next 4 functions are the standard ecto cells ones 42 | static void 43 | declare_params(ecto::tendrils& params) 44 | { 45 | } 46 | 47 | static void 48 | declare_io(const ecto::tendrils& params, ecto::tendrils& inputs, ecto::tendrils& outputs) 49 | { 50 | } 51 | 52 | void 53 | configure(const ecto::tendrils& params, const ecto::tendrils& inputs, const ecto::tendrils& outputs) 54 | { 55 | } 56 | 57 | virtual int 58 | process(const ecto::tendrils& inputs, const ecto::tendrils& outputs) 59 | { 60 | // Doing some awesome matching or just passing the models to the output 61 | return ecto::OK; 62 | } 63 | }; 64 | 65 | The ``ParameterCallback`` function gets from the model everything that makes it specific. Please refer to ModelWriter 66 | for how to get this data 67 | 68 | Step 2 69 | ^^^^^^ 70 | 71 | Very important, you need to actually define a type for your cell based on ModelReaderBase. Something like this suffices: 72 | 73 | .. code-block:: cpp 74 | 75 | typedef db::bases::ModelReaderBase MyAwesomeModelReaderCell; 76 | 77 | Sink 78 | ---- 79 | 80 | You can output results to the console or to a CSV file. 81 | 82 | .. toggle_table:: 83 | :arg1: Non-ROS 84 | :arg2: ROS 85 | 86 | .. toggle:: Non-ROS 87 | 88 | That is all you can output to if you don't use ROS. 89 | 90 | .. toggle:: ROS 91 | 92 | If you want to use the ROS publisher that outputs object recognition messages, you need to have your recognition pipeline have the following output tendrils: 93 | 94 | object_ids: a vector of Object ids 95 | Rs: a vector of cv::Mat, each representing the pose rotation of a matching object 96 | ts: a vector of cv::Mat, each representing the pose translation of a matching object 97 | -------------------------------------------------------------------------------- /doc/source/api/generic.rst: -------------------------------------------------------------------------------- 1 | Generic Comments 2 | ================ 3 | 4 | ``ORK`` is able to run different object recognition pipelines concurrently while using a common infrastructure: data will come in 5 | through a ``Source`` that will then go to a ``Pipeline`` which will output information to a ``Sink``. 6 | 7 | 8 | Source/Pipeline/Sink 9 | -------------------- 10 | 11 | Those are usually written in C++ and can come from any library out there. To be usable, they need to be wrapper in a C++ ``ecto`` cell as 12 | ``ORK`` is running everything in a big ``ecto graph``. To have this cell foundable and easier to use, it also needs to be wrapped in a Python 13 | object (there is a base class for any of the types). 14 | 15 | Unit Tests 16 | ---------- 17 | 18 | To make sure your ``Source``/``Pipeline``/``Sink`` is compatible with ``ORK``, we provide CMake macros to test your code. Use them as follows: 19 | 20 | .. code-block:: cmake 21 | 22 | find_package(object_recognition_core) 23 | # for a detection pipeline 24 | object_recognition_core_detection_test(${PATH_TO_YOUR_DETECTION_CONFIG_FILE}) 25 | # for a training pipeline 26 | object_recognition_core_training_test(${PATH_TO_YOUR_TRAINING_CONFIG_FILE}) 27 | # for a sink 28 | object_recognition_core_sink_test(${YOUR_SINK_NAME}) 29 | # for a source 30 | object_recognition_core_source_test(${YOUR_SOURCE_NAME}) 31 | # for a generic Python script you want to test --help on 32 | object_recognition_core_help_test(${PATH_TO_YOUR_PYTHON_SCRIPT}) 33 | -------------------------------------------------------------------------------- /doc/source/api/index.rst: -------------------------------------------------------------------------------- 1 | DB API 2 | ====== 3 | 4 | DB interactions are done with a specific API. You can either use the default types, or create your own. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | db.rst 10 | 11 | Object Recognition API 12 | ====================== 13 | 14 | In the Object Recognition Kitchen each algorithm is defined in terms of a pipeline. We have a few interfaces you should follow if 15 | you wish to add a new pipeline to reduce the amount of code to write. 16 | 17 | Our infrastructure is very flexible thanks to ``ecto`` and we have developed several tools to facilitate the traditional 18 | pipelines that contain a training phase and a detection phase. If your pipeline does not require training, just skip 19 | the section. 20 | 21 | Once you wrap your code into those ``base classes`` (it's slightly more complex than a base class), you have access to everything 22 | we've coded for you. Doing so usually requires two steps: writing an ``ecto`` cell in pure C++ (or Python if you know a bit of ``ecto``) 23 | which is the core of your processing, and a simple Python wrapper that enables ORK to exploit your cell fully (by being able to find it, 24 | by getting automatic docs from it ...). 25 | 26 | 27 | .. toctree:: 28 | :maxdepth: 2 29 | 30 | generic.rst 31 | training.rst 32 | detection.rst 33 | source_sink.rst 34 | cells.rst 35 | -------------------------------------------------------------------------------- /doc/source/api/source_sink.rst: -------------------------------------------------------------------------------- 1 | Source/Sink 2 | =========== 3 | 4 | ``Sources`` and ``Sinks`` are the inputs/outputs of any pipelines. ``ORK`` provides a few for you but you can extend them by providing your own. 5 | For both, you now know the drill: you need a Python wrapper that wraps your ``Sourc/Sink`` cell. you just need to implement a Python object inheriting 6 | from some base classes. 7 | 8 | For a ``Source``: :py:class:`object_recognition_core.io.source.SourceBase`: 9 | 10 | .. autoclass:: object_recognition_core.io.source.OpenNI 11 | :members: 12 | 13 | And for a ``Sink``: py:class:`object_recognition_core.io.source.SinkBase`: 14 | 15 | .. autoclass:: object_recognition_core.io.sink.SinkBase 16 | :members: 17 | -------------------------------------------------------------------------------- /doc/source/api/training.rst: -------------------------------------------------------------------------------- 1 | Training 2 | ======== 3 | 4 | 5 | Database Cell 6 | ------------- 7 | 8 | When creating your training pipeline, you will want to store your model in the database. 9 | By using our interface you will 10 | save a lot of time. Creating such a cell is easy and 11 | it will automatically add the following fields to 12 | the model when persisted: 13 | 14 | - the object id 15 | - the model parameters 16 | - the fact that the document is a model, of the type given by the member function ``model_type`` 17 | 18 | 19 | Step 1 20 | ^^^^^^ 21 | 22 | First, you will need to create a cell that implements what is added to the DB document. It has to inherit from 23 | ``db::bases::ModelWriterImpl``. An example implementation is: 24 | 25 | .. code-block:: cpp 26 | :linenos: 27 | 28 | struct MyAwesomeModelWriterImpl: public db::bases::ModelWriterImpl 29 | { 30 | public: 31 | // You can define the declare_params and configure functions if needed 32 | 33 | // This is the standard ecto cell declare_io 34 | static void 35 | declare_io(const ecto::tendrils& params, ecto::tendrils& inputs, ecto::tendrils& outputs) 36 | { 37 | inputs.declare(&MyAwesomeModelWriterImpl::model_part_, "model_part", "A part of the model."); 38 | } 39 | 40 | // Note how this function has an extra argument: the db::Document 41 | virtual int 42 | process(const ecto::tendrils& inputs, const ecto::tendrils& outputs, db::Document& doc) 43 | { 44 | doc.set_attachment("model_part", *model_part_); 45 | return ecto::OK; 46 | } 47 | 48 | // The DB needs to know the type of your model, to differentiate it from other methods 49 | virtual std::string 50 | model_type() const 51 | { 52 | return "My awesome model"; 53 | } 54 | 55 | private: 56 | ecto::spore model_part_; 57 | }; 58 | 59 | The ``process`` function fills your document with everything that makes your model specific. Use the ``set_value`` to add fields that can be searched (strings, numerals) and the ``set_attachment`` 60 | member function of the ``db::Document`` to fill the different binary blobs of the model. If your type is not supported, you 61 | will have to implement the following member functions (and please send us a patch containing them if it is a very common type): 62 | 63 | .. code-block:: cpp 64 | :linenos: 65 | 66 | template<> 67 | void 68 | Document::get_attachment(const AttachmentName &attachment_name, YourType & value) const; 69 | 70 | template<> 71 | void 72 | Document::get_attachment_and_cache(const AttachmentName &attachment_name, YourType & value); 73 | 74 | template<> 75 | void 76 | Document::set_attachment(const AttachmentName &attachment_name, const cv::Mat & value); 77 | 78 | (we provide a default ``boost`` serialization but to make sure the binary blobs are readable on machines with a different 79 | ``boost serialization`` library, you should probably implement your own serialization) 80 | 81 | Step 2 82 | ^^^^^^ 83 | 84 | Very important, you need to actually define a type for your cell based on ModelWriterBase. Something like this suffices: 85 | 86 | .. code-block:: cpp 87 | 88 | typedef db::bases::ModelWriterBase MyAwesomeModelWriterCell; 89 | 90 | Python Plasm 91 | ------------ 92 | 93 | Your pipeline also has to provide an implementation of the :py:class:`object_recognition_core.pipelines.training.TrainingPipeline` class so that 94 | ``ORK`` can find it (as it will be on the ``PYTHONPATH``), generate docs for it and do everything that is basically not the raw computation. 95 | 96 | .. autoclass:: object_recognition_core.pipelines.training.TrainerBase 97 | :members: 98 | -------------------------------------------------------------------------------- /doc/source/art/or.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 45 | 47 | 48 | 50 | image/svg+xml 51 | 53 | 54 | 55 | 56 | 57 | 62 | 65 | OR 76 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /doc/source/detection/detection.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. _detection: 4 | 5 | Detection 6 | ######### 7 | .. highlight:: ectosh 8 | 9 | .. contents:: 10 | 11 | Using the different trained objects, we can now detect them. 12 | 13 | Use 14 | *** 15 | 16 | .. toggle_table:: 17 | :arg1: Non-ROS 18 | :arg2: ROS 19 | 20 | .. toggle:: Non-ROS 21 | 22 | Just run the detection.py script in /apps. This will run continuously on the input image/point cloud. 23 | 24 | .. code-block:: sh 25 | 26 | ./apps/detection -c detection.ork 27 | 28 | The server requires a configuration file through the ``-c`` option. 29 | 30 | .. toggle:: ROS 31 | 32 | If you want continuous detection, you can just run the detection script: 33 | 34 | .. code-block:: sh 35 | 36 | rosrun object_recognition_core detection -c `rospack find object_recognition_tod`/conf/detection.ros.ork 37 | 38 | Then again, there is also an actionlib server as detailed on :ref:`actionlib server `: 39 | 40 | .. code-block:: sh 41 | 42 | rosrun object_recognition_ros server -c `rospack find object_recognition_tod`/conf/detection.ros.ork 43 | 44 | This will start a server with a given configuration file. 45 | If you want to test the server, just execute the client once: 46 | 47 | .. code-block:: sh 48 | 49 | rosrun object_recognition_ros client 50 | 51 | You can also use roslaunch if you want traditional actionlib support. There is a ``config_file`` argument 52 | that can help you choose different pipelines: 53 | 54 | .. code-block:: sh 55 | 56 | roslaunch object_recognition_ros server.robot.launch 57 | 58 | A typical command line session might look like:: 59 | 60 | % apps/detection -c `rospack find object_recognition_tod`/conf/detection.ros.ork 61 | [ INFO] [1317692023.717854617]: Initialized ros. node_name: /ecto_node_1317692023710501315 62 | Threadpool executing [unlimited] ticks in 5 threads. 63 | [ INFO] [1317692024.254588151]: Subscribed to topic:/camera/rgb/camera_info with queue size of 0 64 | [ INFO] [1317692024.255467268]: Subscribed to topic:/camera/depth_registered/camera_info with queue size of 0 65 | [ INFO] [1317692024.256186358]: Subscribed to topic:/camera/depth_registered/image with queue size of 0 66 | [ INFO] [1317692024.256863212]: Subscribed to topic:/camera/rgb/image_color with queue size of 0 67 | model_id: e2449bdc43fd6d9dd646fcbcd012daaa 68 | span: 0.433393 meters 69 | 1 70 | ***Starting object: 0 71 | * starting RANSAC 72 | added : 1 73 | added : 0 74 | * n inliers: 1824 75 | [-0.056509789, 0.99800211, 0.028263446; 76 | 0.94346958, 0.062639669, -0.32548648; 77 | -0.32660651, 0.0082725696, -0.94512439] 78 | [-0.32655218; 0.03684178; 0.85040951] 79 | ********************* found 1poses 80 | [ INFO] [1317692117.187226953]: publishing to topic:/object_ids 81 | [ INFO] [1317692117.188155476]: publishing to topic:/poses 82 | 83 | 84 | Command Line Interface 85 | ********************** 86 | .. program-output:: ../../../apps/detection --help 87 | :in_srcdir: 88 | 89 | Configuration File 90 | ****************** 91 | 92 | The configuration file is where you define your graph and with the current ORK, you can choose any of the following sources: 93 | 94 | .. program-output:: python -c "from object_recognition_core.utils.doc import config_yaml_for_ecto_cells; print '\n'.join(config_yaml_for_ecto_cells('source'))" 95 | :shell: 96 | 97 | any of the following sinks: 98 | 99 | .. program-output:: python -c "from object_recognition_core.utils.doc import config_yaml_for_ecto_cells; print '\n'.join(config_yaml_for_ecto_cells('sink'))" 100 | :shell: 101 | 102 | or the following pipelines: 103 | 104 | .. program-output:: python -c "from object_recognition_core.utils.doc import config_yaml_for_ecto_cells; print '\n'.join(config_yaml_for_ecto_cells('detection_pipeline'))" 105 | :shell: 106 | 107 | More of any of those can be added by the user obviously 108 | -------------------------------------------------------------------------------- /doc/source/index_developer.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. _ork_developer: 4 | 5 | object_recognition_core for developers 6 | ###################################### 7 | 8 | Adding a pipeline to ``ORK`` is done by wrapping code and is usually only around 200/300 lines of Python/C++ but please 9 | read the :ref:`Infrastructure ` docs first so that you know what a user will expect from you. 10 | 11 | API 12 | *** 13 | .. toctree:: 14 | :maxdepth: 2 15 | 16 | api/index.rst 17 | -------------------------------------------------------------------------------- /doc/source/infrastructure/configuration.rst: -------------------------------------------------------------------------------- 1 | .. _configuration: 2 | 3 | Configuration File 4 | ################## 5 | 6 | ``ORK`` contains several scripts but two steps (obviously) require heavy configuration: those are 7 | :ref:`Training ` and :ref:`Detection `. Those two steps are very flexible and can use several 8 | inputs/outputs or any pipeline defined on the :ref:`Main Page `. 9 | 10 | Those are configured through a config file passed as an argument. For both cases, the file defines one or several 11 | `ecto `_ cells that are connected together and executed in a pipeline. Each cell is 12 | defined as follows: 13 | 14 | .. code-block:: yaml 15 | 16 | cell_name: 17 | type: class_of_the_ecto_cell 18 | module: Python_module_where_the_class_is 19 | inputs: ['other_cell_name_1', 'other_cell_name_2'] (Optional) 20 | outputs: ['other_cell_name_3', 'other_cell_name_4'] (Optional) 21 | parameters: (Optional) 22 | any_valid_JSON 23 | 24 | An example of a pipeline could therefore be: 25 | 26 | 27 | .. code-block:: yaml 28 | 29 | cell1: 30 | type: class1 31 | module: module1 32 | outputs: [cell2] 33 | parameters: 34 | parameter1: value1 35 | 36 | cell2: 37 | type: class2 38 | module: module2 39 | inputs: [cell1] (Optional: actually does not need to be as it's defined for cell1) 40 | 41 | The second cell could also have parameters. 42 | 43 | Once those relationships are defined, the cells can be properly initialized, linked and executed altogether. That might 44 | seems like sparse information but it really is that simple. The easiest is to look at the different configuration files 45 | for the different pipelines. 46 | -------------------------------------------------------------------------------- /doc/source/infrastructure/couch.rst: -------------------------------------------------------------------------------- 1 | Database 2 | ######## 3 | .. _couchdb: http://couchdb.apache.org 4 | 5 | .. _object_recognition_core_db: 6 | 7 | Implementations 8 | *************** 9 | 10 | Several DB implementations are provided by default. They accept the following parameters: 11 | 12 | CouchDb: 13 | 14 | .. program-output:: python -c "import object_recognition_core.boost.interface as db; print db.ObjectDb(db.ObjectDbParameters({'type':'CouchDB'})).parameters().raw" 15 | 16 | Filesystem: 17 | 18 | .. program-output:: python -c "import object_recognition_core.boost.interface as db; print db.ObjectDb(db.ObjectDbParameters({'type':'filesystem'})).parameters().raw" 19 | 20 | Empty (only for testing): 21 | 22 | .. program-output:: python -c "import object_recognition_core.boost.interface as db; print db.ObjectDb(db.ObjectDbParameters({'type':'empty'})).parameters().raw" 23 | 24 | Any custom implementation will have the "noncore" type. 25 | 26 | Couch Db 27 | ******** 28 | We are using `couchdb`_ as our main database and it is the most tested implementation. To set up your local instance, all you must do is install couchdb, and ensure that the service has started. 29 | 30 | .. highlight:: ectosh 31 | 32 | The following should download and start the couch on Ubuntu like distros: 33 | 34 | .. code-block:: sh 35 | 36 | sudo apt-get install couchdb 37 | 38 | 39 | To test that it is working properly: 40 | 41 | .. code-block:: sh 42 | 43 | curl -X GET http://localhost:5984 44 | % {"couchdb":"Welcome","version":"1.0.1"} 45 | 46 | The couchdb version should be greater than ``0.10.0``. 47 | 48 | Configuration 49 | ============= 50 | If you would like to expose your couchdb instance to a different port, or bind to a different interface, besides the loopback, edit ``/etc/couchdb/local.ini``. 51 | 52 | For instance, changing the bind_address to ``0.0.0.0`` will allow your couchdb to be accessed on any interface. 53 | 54 | :: 55 | 56 | [httpd] port = 5984 bind_address = 0.0.0.0 57 | 58 | After editing this file, restart the couchdb service: 59 | 60 | .. code-block:: sh 61 | 62 | sudo service couchdb restart 63 | 64 | Web UI 65 | ====== 66 | 67 | We have a set of webpages that may be pushed to your couchdb instance that help browse the objects that you train, or models created. 68 | 69 | First make sure you have ``couchapp``: 70 | 71 | .. code-block:: sh 72 | 73 | sudo pip install -U couchapp 74 | 75 | 76 | .. toggle_table:: 77 | :arg1: From Source 78 | :arg2: From ROS packages 79 | 80 | .. toggle:: From Source 81 | 82 | There is a make target for installing the web ui for your convenience.: 83 | 84 | .. code-block:: sh 85 | 86 | make or_web_ui 87 | 88 | This will push the app to the location specified in the Cmake cache, by the variable, ``OR_WEB_UI_LOCATION``. Use 89 | ccache or cmake-gui to point it to a different location if you like. 90 | 91 | You can manually push it also, if you need more flexibility, or hate the cmake cache. cd to the 92 | ``object_recognition/web_ui`` directory and run couchapp in a manner similar to the following.: 93 | 94 | .. code-block:: sh 95 | 96 | couchapp push . http://localhost:5984/or_web_ui 97 | 98 | .. toggle:: From ROS packages 99 | 100 | We provide a utility that automatically installs the visualizer on the DB. 101 | 102 | .. code-block:: bash 103 | 104 | rosrun object_recognition_core push.sh 105 | 106 | This will upload the contents of the directory to collection in your couchdb instance, called ``or_web_ui``. After this you can browse the web ui using the url http://localhost:5984/or_web_ui/_design/viewer/index.html 107 | 108 | Library 109 | ======= 110 | 111 | Object Recognition tools manipulate the database either using libCURL or python-couchdb. You may find it helpful to browse the default db HTML interface at http://localhost:5984/_utils 112 | 113 | We also provide scripts located for maintenance located in the db_scripts folder. 114 | -------------------------------------------------------------------------------- /doc/source/infrastructure/infrastructure.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. _infrastructure: 4 | 5 | ORK for users 6 | ############# 7 | 8 | object_recognition_core provides an infrastructure for easy development and usage of object recognition pipelines. When 9 | using/developing a new method you created or found, you usually always have to recreate the following: 10 | 11 | * figure out a way to store/query/use your training data 12 | * figure out a way to store/query/use your models 13 | * an easy to train your objects 14 | * deal with where your data is coming from (cameras, ROS rosbag, ROS topics) 15 | * deal with where your data is going to 16 | * integrate it with ROS by listening to the right topics and publishing something 17 | * compare it to other pipelines by having several pipelines running at once 18 | 19 | ``ORK`` takes care of all that (and more !) by providing base classes and a flexible infrastructure because let's face 20 | it, you want to work on the juicy stuff: the pipeline itself. 21 | 22 | If you are a user, the docs are right below. 23 | 24 | User Docs 25 | ######### 26 | .. toctree:: 27 | :maxdepth: 2 28 | 29 | couch.rst 30 | configuration.rst 31 | -------------------------------------------------------------------------------- /doc/source/ork.rosinstall.indigo.jade: -------------------------------------------------------------------------------- 1 | - git: {local-name: ecto, uri: "https://github.com/plasmodic/ecto"} 2 | - git: {local-name: ecto_image_pipeline, uri: "https://github.com/plasmodic/ecto_image_pipeline"} 3 | - git: {local-name: ecto_openni, uri: "https://github.com/plasmodic/ecto_openni"} 4 | - git: {local-name: ecto_opencv, uri: "https://github.com/plasmodic/ecto_opencv", version: "indigo"} 5 | - git: {local-name: ecto_pcl, uri: "https://github.com/plasmodic/ecto_pcl"} 6 | - git: {local-name: ecto_ros, uri: "https://github.com/plasmodic/ecto_ros"} 7 | - git: {local-name: opencv_candidate, uri: "https://github.com/wg-perception/opencv_candidate"} 8 | - git: {local-name: ork_core, uri: "https://github.com/wg-perception/object_recognition_core"} 9 | - git: {local-name: ork_capture, uri: "https://github.com/wg-perception/capture"} 10 | - git: {local-name: ork_reconstruction, uri: "https://github.com/wg-perception/reconstruction"} 11 | - git: {local-name: ork_linemod, uri: "https://github.com/wg-perception/linemod"} 12 | - git: {local-name: ork_renderer, uri: "https://github.com/wg-perception/ork_renderer"} 13 | - git: {local-name: ork_tabletop, uri: "https://github.com/wg-perception/tabletop"} 14 | - git: {local-name: ork_tod, uri: "https://github.com/wg-perception/tod"} 15 | - git: {local-name: ork_transparent_objects, uri: "https://github.com/wg-perception/transparent_objects"} 16 | - git: {local-name: ork_ros, uri: "https://github.com/wg-perception/object_recognition_ros"} 17 | - git: {local-name: ork_ros_visualization, uri: "https://github.com/wg-perception/object_recognition_ros_visualization"} 18 | -------------------------------------------------------------------------------- /doc/source/ork.rosinstall.kinetic.plus: -------------------------------------------------------------------------------- 1 | - git: {local-name: ecto, uri: "https://github.com/plasmodic/ecto"} 2 | - git: {local-name: ecto_image_pipeline, uri: "https://github.com/plasmodic/ecto_image_pipeline"} 3 | - git: {local-name: ecto_openni, uri: "https://github.com/plasmodic/ecto_openni"} 4 | - git: {local-name: ecto_opencv, uri: "https://github.com/plasmodic/ecto_opencv"} 5 | - git: {local-name: ecto_pcl, uri: "https://github.com/plasmodic/ecto_pcl"} 6 | - git: {local-name: ecto_ros, uri: "https://github.com/plasmodic/ecto_ros"} 7 | - git: {local-name: opencv_candidate, uri: "https://github.com/wg-perception/opencv_candidate"} 8 | - git: {local-name: ork_core, uri: "https://github.com/wg-perception/object_recognition_core"} 9 | - git: {local-name: ork_capture, uri: "https://github.com/wg-perception/capture"} 10 | - git: {local-name: ork_reconstruction, uri: "https://github.com/wg-perception/reconstruction"} 11 | - git: {local-name: ork_linemod, uri: "https://github.com/wg-perception/linemod"} 12 | - git: {local-name: ork_renderer, uri: "https://github.com/wg-perception/ork_renderer"} 13 | - git: {local-name: ork_tabletop, uri: "https://github.com/wg-perception/tabletop"} 14 | - git: {local-name: ork_tod, uri: "https://github.com/wg-perception/tod"} 15 | - git: {local-name: ork_transparent_objects, uri: "https://github.com/wg-perception/transparent_objects"} 16 | - git: {local-name: ork_ros, uri: "https://github.com/wg-perception/object_recognition_ros"} 17 | - git: {local-name: ork_ros_visualization, uri: "https://github.com/wg-perception/object_recognition_ros_visualization"} 18 | -------------------------------------------------------------------------------- /doc/source/training/training.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | .. _training: 4 | 5 | Training 6 | ######## 7 | .. highlight:: ectosh 8 | 9 | .. contents:: 10 | 11 | Once some observations are stored in the database, models can be built from them. 12 | 13 | Config File 14 | *********** 15 | 16 | Training, just like recognition, requires a configuration file but it usually only contains one cell that defines a 17 | pipeline that reads data from the database and computes a model. Then again, nothing prevents you to train several 18 | models at the same time by executing several pipelines. 19 | 20 | Use 21 | *** 22 | 23 | .. toggle_table:: 24 | :arg1: Non-ROS 25 | :arg2: ROS 26 | 27 | .. toggle:: Non-ROS 28 | 29 | Just run the training.py script in ``/apps``. It requires a configuration file through the ``-c`` option. Some of the 30 | options in there can be overriden through the command line for convenience. Change the following parameters to your needs: 31 | 32 | * the ``object_ids`` should be the list of object ids you want to train on. If you want, you can also use object_names, 33 | that are more human readable. object_ids is of the form ["6b3de86feee4e840280b4caad90003fb"] but there are two special 34 | options: if it is "all", then all models are recomputed; if it is "missing", only the missing models are computed. 35 | 36 | 37 | .. toggle:: ROS 38 | 39 | The training script can be run as follow: 40 | 41 | .. code-block:: sh 42 | 43 | rosrun object_recognition_core training \ 44 | -c `rospack find object_recognition_tod`/conf/training.ork \ 45 | --visualize 46 | 47 | You can choose whatever configuration file; a few are provided in ``object_recognition_server/conf``. 48 | 49 | 50 | A typical command line session might look like:: 51 | 52 | % apps/training -c config_training.txt --commit 53 | Prepare G2O: processing image 65/65 54 | Performing full BA: 55 | iteration= 0 chi2= 168324165740673896546304.000000 time= 39.2803 cumTime= 39.2803 lambda= 154861.907021 edges= 64563 schur= 1 56 | Persisted 57 | 58 | Command Line Interface 59 | ********************** 60 | .. program-output:: ../../../apps/training --help 61 | :in_srcdir: 62 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/dict_json_conversion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2012, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #ifndef DICT_JSON_CONVERSION_H_ 37 | #define DICT_JSON_CONVERSION_H_ 38 | 39 | #include 40 | 41 | #include "json_spirit/json_spirit.h" 42 | #include "types.h" 43 | 44 | namespace object_recognition_core 45 | { 46 | namespace common 47 | { 48 | or_json::mObject 49 | BpDictToJson(const boost::python::dict &bp_dict); 50 | 51 | boost::python::dict 52 | JsonToBpDict(const or_json::mObject & map); 53 | } 54 | } 55 | 56 | #endif /* DICT_JSON_CONVERSION_H_ */ 57 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "json_spirit/json_spirit.h" 5 | namespace object_recognition_core 6 | { 7 | inline or_json::mValue 8 | to_json(const std::string& str) 9 | { 10 | or_json::mValue value; 11 | or_json::read(str, value); 12 | return value; 13 | } 14 | 15 | inline std::string 16 | from_json(const or_json::mValue& obj) 17 | { 18 | return or_json::write(obj); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(JSON_SPIRIT_SRCS 2 | json_spirit_reader.cpp 3 | json_spirit_value.cpp 4 | json_spirit_writer.cpp) 5 | 6 | FIND_PACKAGE(Boost 1.34 REQUIRED) 7 | INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) 8 | 9 | ADD_LIBRARY(json_spirit STATIC ${JSON_SPIRIT_SRCS}) 10 | 11 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/README: -------------------------------------------------------------------------------- 1 | Those files were obtained from http://www.gitorious.org/json-spirit. 2 | It is version 4.03 of boost spirit. 3 | The license is MIT 4 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_SPIRIT 2 | #define JSON_SPIRIT 3 | 4 | // Copyright John W. Wilkinson 2007 - 2009. 5 | // Distributed under the MIT License, see accompanying file LICENSE.txt 6 | 7 | // json spirit version 4.03 8 | 9 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 10 | # pragma once 11 | #endif 12 | 13 | #include "json_spirit_value.h" 14 | #include "json_spirit_reader.h" 15 | #include "json_spirit_writer.h" 16 | #include "json_spirit_utils.h" 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit_error_position.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_SPIRIT_ERROR_POSITION 2 | #define JSON_SPIRIT_ERROR_POSITION 3 | 4 | // Copyright John W. Wilkinson 2007 - 2009. 5 | // Distributed under the MIT License, see accompanying file LICENSE.txt 6 | 7 | // json spirit version 4.03 8 | 9 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 10 | # pragma once 11 | #endif 12 | 13 | #include 14 | 15 | namespace or_json 16 | { 17 | // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. 18 | // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" 19 | // functions that return a bool. 20 | // 21 | struct Error_position 22 | { 23 | Error_position(); 24 | Error_position( unsigned int line, unsigned int column, const std::string& reason ); 25 | bool operator==( const Error_position& lhs ) const; 26 | unsigned int line_; 27 | unsigned int column_; 28 | std::string reason_; 29 | }; 30 | 31 | inline Error_position::Error_position() 32 | : line_( 0 ) 33 | , column_( 0 ) 34 | { 35 | } 36 | 37 | inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) 38 | : line_( line ) 39 | , column_( column ) 40 | , reason_( reason ) 41 | { 42 | } 43 | 44 | inline bool Error_position::operator==( const Error_position& lhs ) const 45 | { 46 | if( this == &lhs ) return true; 47 | 48 | return ( reason_ == lhs.reason_ ) && 49 | ( line_ == lhs.line_ ) && 50 | ( column_ == lhs.column_ ); 51 | } 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit_reader.cpp: -------------------------------------------------------------------------------- 1 | // Copyright John W. Wilkinson 2007 - 2009. 2 | // Distributed under the MIT License, see accompanying file LICENSE.txt 3 | 4 | // json spirit version 4.03 5 | 6 | #include "json_spirit_reader.h" 7 | #include "json_spirit_reader_template.h" 8 | 9 | using namespace or_json; 10 | 11 | bool or_json::read( const std::string& s, Value& value ) 12 | { 13 | return read_string( s, value ); 14 | } 15 | 16 | void or_json::read_or_throw( const std::string& s, Value& value ) 17 | { 18 | read_string_or_throw( s, value ); 19 | } 20 | 21 | bool or_json::read( std::istream& is, Value& value ) 22 | { 23 | return read_stream( is, value ); 24 | } 25 | 26 | void or_json::read_or_throw( std::istream& is, Value& value ) 27 | { 28 | read_stream_or_throw( is, value ); 29 | } 30 | 31 | bool or_json::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) 32 | { 33 | return read_range( begin, end, value ); 34 | } 35 | 36 | void or_json::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) 37 | { 38 | begin = read_range_or_throw( begin, end, value ); 39 | } 40 | 41 | #ifndef BOOST_NO_STD_WSTRING 42 | 43 | bool or_json::read( const std::wstring& s, wValue& value ) 44 | { 45 | return read_string( s, value ); 46 | } 47 | 48 | void or_json::read_or_throw( const std::wstring& s, wValue& value ) 49 | { 50 | read_string_or_throw( s, value ); 51 | } 52 | 53 | bool or_json::read( std::wistream& is, wValue& value ) 54 | { 55 | return read_stream( is, value ); 56 | } 57 | 58 | void or_json::read_or_throw( std::wistream& is, wValue& value ) 59 | { 60 | read_stream_or_throw( is, value ); 61 | } 62 | 63 | bool or_json::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) 64 | { 65 | return read_range( begin, end, value ); 66 | } 67 | 68 | void or_json::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) 69 | { 70 | begin = read_range_or_throw( begin, end, value ); 71 | } 72 | 73 | #endif 74 | 75 | bool or_json::read( const std::string& s, mValue& value ) 76 | { 77 | return read_string( s, value ); 78 | } 79 | 80 | void or_json::read_or_throw( const std::string& s, mValue& value ) 81 | { 82 | read_string_or_throw( s, value ); 83 | } 84 | 85 | bool or_json::read( std::istream& is, mValue& value ) 86 | { 87 | return read_stream( is, value ); 88 | } 89 | 90 | void or_json::read_or_throw( std::istream& is, mValue& value ) 91 | { 92 | read_stream_or_throw( is, value ); 93 | } 94 | 95 | bool or_json::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) 96 | { 97 | return read_range( begin, end, value ); 98 | } 99 | 100 | void or_json::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) 101 | { 102 | begin = read_range_or_throw( begin, end, value ); 103 | } 104 | 105 | #ifndef BOOST_NO_STD_WSTRING 106 | 107 | bool or_json::read( const std::wstring& s, wmValue& value ) 108 | { 109 | return read_string( s, value ); 110 | } 111 | 112 | void or_json::read_or_throw( const std::wstring& s, wmValue& value ) 113 | { 114 | read_string_or_throw( s, value ); 115 | } 116 | 117 | bool or_json::read( std::wistream& is, wmValue& value ) 118 | { 119 | return read_stream( is, value ); 120 | } 121 | 122 | void or_json::read_or_throw( std::wistream& is, wmValue& value ) 123 | { 124 | read_stream_or_throw( is, value ); 125 | } 126 | 127 | bool or_json::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) 128 | { 129 | return read_range( begin, end, value ); 130 | } 131 | 132 | void or_json::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) 133 | { 134 | begin = read_range_or_throw( begin, end, value ); 135 | } 136 | 137 | #endif 138 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_SPIRIT_READER 2 | #define JSON_SPIRIT_READER 3 | 4 | // Copyright John W. Wilkinson 2007 - 2009. 5 | // Distributed under the MIT License, see accompanying file LICENSE.txt 6 | 7 | // json spirit version 4.03 8 | 9 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 10 | # pragma once 11 | #endif 12 | 13 | #include "json_spirit_value.h" 14 | #include "json_spirit_error_position.h" 15 | #include 16 | 17 | namespace or_json 18 | { 19 | // functions to reads a JSON values 20 | 21 | bool read( const std::string& s, Value& value ); 22 | bool read( std::istream& is, Value& value ); 23 | bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); 24 | 25 | void read_or_throw( const std::string& s, Value& value ); 26 | void read_or_throw( std::istream& is, Value& value ); 27 | void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); 28 | 29 | #ifndef BOOST_NO_STD_WSTRING 30 | 31 | bool read( const std::wstring& s, wValue& value ); 32 | bool read( std::wistream& is, wValue& value ); 33 | bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); 34 | 35 | void read_or_throw( const std::wstring& s, wValue& value ); 36 | void read_or_throw( std::wistream& is, wValue& value ); 37 | void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); 38 | 39 | #endif 40 | 41 | bool read( const std::string& s, mValue& value ); 42 | bool read( std::istream& is, mValue& value ); 43 | bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); 44 | 45 | void read_or_throw( const std::string& s, mValue& value ); 46 | void read_or_throw( std::istream& is, mValue& value ); 47 | void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); 48 | 49 | #ifndef BOOST_NO_STD_WSTRING 50 | 51 | bool read( const std::wstring& s, wmValue& value ); 52 | bool read( std::wistream& is, wmValue& value ); 53 | bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); 54 | 55 | void read_or_throw( const std::wstring& s, wmValue& value ); 56 | void read_or_throw( std::wistream& is, wmValue& value ); 57 | void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); 58 | 59 | #endif 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit_stream_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_SPIRIT_READ_STREAM 2 | #define JSON_SPIRIT_READ_STREAM 3 | 4 | // Copyright John W. Wilkinson 2007 - 2009. 5 | // Distributed under the MIT License, see accompanying file LICENSE.txt 6 | 7 | // json spirit version 4.03 8 | 9 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 10 | # pragma once 11 | #endif 12 | 13 | #include "json_spirit_reader_template.h" 14 | 15 | namespace json_spirit 16 | { 17 | // these classes allows you to read multiple top level contiguous values from a stream, 18 | // the normal stream read functions have a bug that prevent multiple top level values 19 | // from being read unless they are separated by spaces 20 | 21 | template< class Istream_type, class Value_type > 22 | class Stream_reader 23 | { 24 | public: 25 | 26 | Stream_reader( Istream_type& is ) 27 | : iters_( is ) 28 | { 29 | } 30 | 31 | bool read_next( Value_type& value ) 32 | { 33 | return read_range( iters_.begin_, iters_.end_, value ); 34 | } 35 | 36 | private: 37 | 38 | typedef Multi_pass_iters< Istream_type > Mp_iters; 39 | 40 | Mp_iters iters_; 41 | }; 42 | 43 | template< class Istream_type, class Value_type > 44 | class Stream_reader_thrower 45 | { 46 | public: 47 | 48 | Stream_reader_thrower( Istream_type& is ) 49 | : iters_( is ) 50 | , posn_begin_( iters_.begin_, iters_.end_ ) 51 | , posn_end_( iters_.end_, iters_.end_ ) 52 | { 53 | } 54 | 55 | void read_next( Value_type& value ) 56 | { 57 | posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); 58 | } 59 | 60 | private: 61 | 62 | typedef Multi_pass_iters< Istream_type > Mp_iters; 63 | typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; 64 | 65 | Mp_iters iters_; 66 | Posn_iter_t posn_begin_, posn_end_; 67 | }; 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_SPIRIT_UTILS 2 | #define JSON_SPIRIT_UTILS 3 | 4 | // Copyright John W. Wilkinson 2007 - 2009. 5 | // Distributed under the MIT License, see accompanying file LICENSE.txt 6 | 7 | // json spirit version 4.03 8 | 9 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 10 | # pragma once 11 | #endif 12 | 13 | #include "json_spirit_value.h" 14 | #include 15 | 16 | namespace or_json 17 | { 18 | template< class Obj_t, class Map_t > 19 | void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) 20 | { 21 | mp_obj.clear(); 22 | 23 | for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) 24 | { 25 | mp_obj[ i->name_ ] = i->value_; 26 | } 27 | } 28 | 29 | template< class Obj_t, class Map_t > 30 | void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) 31 | { 32 | obj.clear(); 33 | 34 | for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) 35 | { 36 | obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); 37 | } 38 | } 39 | 40 | typedef std::map< std::string, Value > Mapped_obj; 41 | 42 | #ifndef BOOST_NO_STD_WSTRING 43 | typedef std::map< std::wstring, wValue > wMapped_obj; 44 | #endif 45 | 46 | template< class Object_type, class String_type > 47 | const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) 48 | { 49 | for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) 50 | { 51 | if( i->name_ == name ) 52 | { 53 | return i->value_; 54 | } 55 | } 56 | 57 | return Object_type::value_type::Value_type::null; 58 | } 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit_value.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2007 John W Wilkinson 2 | 3 | This source code can be used for any purpose as long as 4 | this comment is retained. */ 5 | 6 | // json spirit version 2.00 7 | 8 | #include "json_spirit_value.h" 9 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit_writer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright John W. Wilkinson 2007 - 2009. 2 | // Distributed under the MIT License, see accompanying file LICENSE.txt 3 | 4 | // json spirit version 4.03 5 | 6 | #include "json_spirit_writer.h" 7 | #include "json_spirit_writer_template.h" 8 | 9 | void or_json::write( const Value& value, std::ostream& os ) 10 | { 11 | write_stream( value, os, false ); 12 | } 13 | 14 | void or_json::write_formatted( const Value& value, std::ostream& os ) 15 | { 16 | write_stream( value, os, true ); 17 | } 18 | 19 | std::string or_json::write( const Value& value ) 20 | { 21 | return write_string( value, false ); 22 | } 23 | 24 | std::string or_json::write_formatted( const Value& value ) 25 | { 26 | return write_string( value, true ); 27 | } 28 | 29 | #ifndef BOOST_NO_STD_WSTRING 30 | 31 | void or_json::write( const wValue& value, std::wostream& os ) 32 | { 33 | write_stream( value, os, false ); 34 | } 35 | 36 | void or_json::write_formatted( const wValue& value, std::wostream& os ) 37 | { 38 | write_stream( value, os, true ); 39 | } 40 | 41 | std::wstring or_json::write( const wValue& value ) 42 | { 43 | return write_string( value, false ); 44 | } 45 | 46 | std::wstring or_json::write_formatted( const wValue& value ) 47 | { 48 | return write_string( value, true ); 49 | } 50 | 51 | #endif 52 | 53 | void or_json::write( const mValue& value, std::ostream& os ) 54 | { 55 | write_stream( value, os, false ); 56 | } 57 | 58 | void or_json::write_formatted( const mValue& value, std::ostream& os ) 59 | { 60 | write_stream( value, os, true ); 61 | } 62 | 63 | std::string or_json::write( const mValue& value ) 64 | { 65 | return write_string( value, false ); 66 | } 67 | 68 | std::string or_json::write_formatted( const mValue& value ) 69 | { 70 | return write_string( value, true ); 71 | } 72 | 73 | #ifndef BOOST_NO_STD_WSTRING 74 | 75 | void or_json::write( const wmValue& value, std::wostream& os ) 76 | { 77 | write_stream( value, os, false ); 78 | } 79 | 80 | void or_json::write_formatted( const wmValue& value, std::wostream& os ) 81 | { 82 | write_stream( value, os, true ); 83 | } 84 | 85 | std::wstring or_json::write( const wmValue& value ) 86 | { 87 | return write_string( value, false ); 88 | } 89 | 90 | std::wstring or_json::write_formatted( const wmValue& value ) 91 | { 92 | return write_string( value, true ); 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/json_spirit/json_spirit_writer.h: -------------------------------------------------------------------------------- 1 | #ifndef JSON_SPIRIT_WRITER 2 | #define JSON_SPIRIT_WRITER 3 | 4 | // Copyright John W. Wilkinson 2007 - 2009. 5 | // Distributed under the MIT License, see accompanying file LICENSE.txt 6 | 7 | // json spirit version 4.03 8 | 9 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 10 | # pragma once 11 | #endif 12 | 13 | #include "json_spirit_value.h" 14 | #include 15 | 16 | namespace or_json 17 | { 18 | // functions to convert JSON Values to text, 19 | // the "formatted" versions add whitespace to format the output nicely 20 | 21 | void write ( const Value& value, std::ostream& os ); 22 | void write_formatted( const Value& value, std::ostream& os ); 23 | std::string write ( const Value& value ); 24 | std::string write_formatted( const Value& value ); 25 | 26 | #ifndef BOOST_NO_STD_WSTRING 27 | 28 | void write ( const wValue& value, std::wostream& os ); 29 | void write_formatted( const wValue& value, std::wostream& os ); 30 | std::wstring write ( const wValue& value ); 31 | std::wstring write_formatted( const wValue& value ); 32 | 33 | #endif 34 | 35 | void write ( const mValue& value, std::ostream& os ); 36 | void write_formatted( const mValue& value, std::ostream& os ); 37 | std::string write ( const mValue& value ); 38 | std::string write_formatted( const mValue& value ); 39 | 40 | #ifndef BOOST_NO_STD_WSTRING 41 | 42 | void write ( const wmValue& value, std::wostream& os ); 43 | void write_formatted( const wmValue& value, std::wostream& os ); 44 | std::wstring write ( const wmValue& value ); 45 | std::wstring write_formatted( const wmValue& value ); 46 | 47 | #endif 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2011, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef TYPES_H_ 36 | #define TYPES_H_ 37 | 38 | #include 39 | 40 | #include "json_spirit/json_spirit.h" 41 | 42 | namespace object_recognition_core 43 | { 44 | namespace db 45 | { 46 | /** The unique identifier of an object in the DB */ 47 | typedef std::string ObjectId; 48 | 49 | /** The unique identifier of a model in the DB */ 50 | typedef std::string ModelId; 51 | 52 | typedef std::string AttachmentName; 53 | typedef std::string CollectionName; 54 | typedef std::string DocumentId; 55 | typedef std::string DbType; 56 | typedef std::string Field; 57 | typedef std::string MimeType; 58 | typedef std::string RevisionId; 59 | 60 | const std::string MIME_TYPE_DEFAULT = "application/octet-stream"; 61 | 62 | /** The type of a model in the DB */ 63 | typedef std::string ModelType; 64 | } 65 | } 66 | 67 | #endif /* TYPES_H_ */ 68 | -------------------------------------------------------------------------------- /include/object_recognition_core/common/types_eigen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #ifndef TYPES_EIGEN_H_ 37 | #define TYPES_EIGEN_H_ 38 | 39 | #include 40 | 41 | #include 42 | #include 43 | 44 | typedef std::vector > VectorQuaterniond; 45 | typedef std::vector > VectorVector3d; 46 | 47 | #endif /* TYPES_EIGEN_H_ */ 48 | -------------------------------------------------------------------------------- /include/object_recognition_core/db/model_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #ifndef ORK_CORE_DB_UTILS_H_ 37 | #define ORK_CORE_DB_UTILS_H_ 38 | 39 | #include 40 | 41 | namespace object_recognition_core 42 | { 43 | namespace db 44 | { 45 | /** Function that compares the intersection of two JSON trees 46 | * @param obj1 47 | * @param obj2 48 | * @return true if the intersection between the keys have the same values 49 | */ 50 | bool 51 | CompareJsonIntersection(const or_json::mValue &obj1, const or_json::mValue &obj2); 52 | 53 | /** Function filling a DB document for a model with the common attributes 54 | * @param db the DB where the model will be saved 55 | * @param object_id the id of the object for that model 56 | * @param method the method used to compute the models (e.g. 'TOD') 57 | * @param parameters_str a JSON string detailing the non-discriminative parameters used in the method 58 | * @param doc the document to fill 59 | * @return the Document to update 60 | */ 61 | void 62 | PopulateModel(const ObjectDbPtr& db, const ObjectId& object_id, const std::string& method, 63 | const std::string& parameters_str, Document& doc); 64 | 65 | /** Given some parameters, retrieve Documents that are models with an object_id 66 | * that is in object_ids and with parameters matching model_json_params 67 | * @param db 68 | * @param object_ids 69 | * @param method 70 | * @return 71 | */ 72 | Documents 73 | ModelDocuments(ObjectDbPtr &db, const std::vector & object_ids, const std::string & method); 74 | 75 | /** Given some parameters, retrieve Documents that are models with parameters matching model_json_params 76 | * @param db 77 | * @param method 78 | * @return 79 | */ 80 | Documents 81 | ModelDocuments(ObjectDbPtr &db, const std::string & method); 82 | } 83 | } 84 | 85 | #endif /* ORK_CORE_DB_UTILS_H_ */ 86 | -------------------------------------------------------------------------------- /include/object_recognition_core/db/opencv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace object_recognition_core 14 | { 15 | namespace db 16 | { 17 | std::string 18 | temporary_yml_file_name(bool do_gzip); 19 | 20 | void 21 | mats2yaml(const std::map& mm,std::ostream& out, bool do_gzip = false); 22 | 23 | void 24 | yaml2mats(std::map& mm,std::istream& in, bool do_gzip = false); 25 | 26 | void 27 | png_attach(cv::Mat image, db::DummyDocument& doc, const std::string& name); 28 | 29 | void 30 | get_png_attachment(cv::Mat& image, const db::DummyDocument& doc, const std::string& name); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /include/object_recognition_core/db/prototypes/observations.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #pragma once 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | namespace object_recognition_core { 43 | namespace db { 44 | class DummyDocument; 45 | } 46 | 47 | namespace prototypes 48 | { 49 | 50 | struct Observation 51 | { 52 | //fields 53 | std::string object_id, session_id; 54 | int frame_number; 55 | 56 | //attachments 57 | cv::Mat K, R, T; //yaml files 58 | cv::Mat image, depth, mask; //png images 59 | 60 | static void 61 | declare(ecto::tendrils& t, bool required); 62 | }; 63 | 64 | void 65 | operator>>(Observation& o, db::DummyDocument* doc); 66 | void 67 | operator<<(Observation& o, const db::DummyDocument* doc); 68 | void 69 | operator>>(Observation& obs, const ecto::tendrils& o); 70 | void 71 | operator<<(Observation& obs, const ecto::tendrils& i); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /include/object_recognition_core/db/wrap_object_db.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | namespace bp = boost::python; 48 | 49 | namespace object_recognition_core 50 | { 51 | namespace db 52 | { 53 | /** Provide a default empty pickling infrastructure 54 | */ 55 | struct object_db_pickle_suite: boost::python::pickle_suite 56 | { 57 | static boost::python::tuple 58 | getinitargs(const ObjectDbParameters& db_params) 59 | { 60 | return boost::python::make_tuple(); 61 | } 62 | 63 | static boost::python::tuple 64 | getstate(const ObjectDbParameters& db_params) 65 | { 66 | // TODO 67 | return boost::python::make_tuple(); 68 | } 69 | 70 | static 71 | void 72 | setstate(ObjectDbParameters& db_params, boost::python::tuple state) 73 | { 74 | using namespace boost::python; 75 | // TODO 76 | } 77 | }; 78 | 79 | /** If you have your own Db to deal with, just call that function to make it visible from Python 80 | * You can override some Python definition after calling it 81 | * @param object_db_name the name of your DB 82 | * @param constructor the constructor of your DB 83 | */ 84 | template 85 | void 86 | wrap_object_db(const std::string &object_db_name, Constructor constructor) 87 | { 88 | bp::class_ ObjectDbClass(object_db_name.c_str(), bp::no_init); 89 | ObjectDbClass.def("__init__", bp::make_constructor(constructor)); 90 | ObjectDbClass.def("parameters", &ObjectDb::parameters, 91 | boost::python::return_value_policy()); 92 | ObjectDbClass.def_pickle(object_db_pickle_suite()); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | object_recognition_core 3 | 0.6.7 4 | object_recognition_core contains tools to launch several recognition pipelines, train objects, store models ... 5 | Ethan Rublee 6 | Vincent Rabaud 7 | Vincent Rabaud 8 | BSD 9 | 10 | http://wg-perception.github.io/object_recognition_core/ 11 | 12 | boost 13 | cmake_modules 14 | curl 15 | ecto 16 | ecto_image_pipeline 17 | sensor_msgs 18 | 19 | boost 20 | couchdb 21 | curl 22 | ecto 23 | ecto_image_pipeline 24 | sensor_msgs 25 | 26 | visualization_msgs 27 | 28 | catkin 29 | 30 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | configure_file(__init__.py.plain.in 2 | ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION}/boost/__init__.py 3 | @ONLY 4 | ) 5 | configure_file(__init__.py.plain.in 6 | ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION}/ecto_cells/__init__.py 7 | @ONLY 8 | ) 9 | 10 | install(FILES ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION}/boost/__init__.py 11 | DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}/boost 12 | ) 13 | install(FILES ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION}/ecto_cells/__init__.py 14 | DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}/ecto_cells 15 | ) 16 | -------------------------------------------------------------------------------- /python/__init__.py.plain.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wg-perception/object_recognition_core/ad17546b7f3b91e7fb2a8bd55e8ca4aebe8ed55b/python/__init__.py.plain.in -------------------------------------------------------------------------------- /python/couchdb: -------------------------------------------------------------------------------- 1 | couchdb-python/couchdb -------------------------------------------------------------------------------- /python/couchdb-python/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2007-2008 Christopher Lenz 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 3. The name of the author may not be used to endorse or promote 15 | products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 19 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 24 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 26 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 28 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /python/couchdb-python/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYING 2 | include Makefile 3 | include ChangeLog.txt 4 | include doc/conf.py 5 | include doc/*.rst 6 | -------------------------------------------------------------------------------- /python/couchdb-python/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test doc upload-doc 2 | 3 | test: 4 | PYTHONPATH=. python couchdb/tests/__init__.py 5 | 6 | doc: 7 | python setup.py build_sphinx 8 | 9 | upload-doc: 10 | python setup.py upload_sphinx 11 | -------------------------------------------------------------------------------- /python/couchdb-python/README.txt: -------------------------------------------------------------------------------- 1 | CouchDB Python Library 2 | ====================== 3 | 4 | This package provides a Python interface to CouchDB. 5 | 6 | 7 | 8 | Please see the files in the `doc` folder or browse the documentation online at: 9 | 10 | 11 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2007 Christopher Lenz 4 | # All rights reserved. 5 | # 6 | # This software is licensed as described in the file COPYING, which 7 | # you should have received as part of this distribution. 8 | 9 | from .client import Database, Document, Server 10 | from .http import HTTPError, PreconditionFailed, Resource, \ 11 | ResourceConflict, ResourceNotFound, ServerError, Session, Unauthorized 12 | 13 | try: 14 | __version__ = 5 #__import__('pkg_resources').get_distribution('CouchDB').version 15 | except: 16 | __version__ = '?' 17 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2007 Christopher Lenz 4 | # All rights reserved. 5 | # 6 | # This software is licensed as described in the file COPYING, which 7 | # you should have received as part of this distribution. 8 | 9 | import unittest 10 | 11 | from couchdb.tests import client, couch_tests, design, http, multipart, \ 12 | mapping, view, package 13 | 14 | 15 | def suite(): 16 | suite = unittest.TestSuite() 17 | suite.addTest(client.suite()) 18 | suite.addTest(design.suite()) 19 | suite.addTest(http.suite()) 20 | suite.addTest(multipart.suite()) 21 | suite.addTest(mapping.suite()) 22 | suite.addTest(view.suite()) 23 | suite.addTest(couch_tests.suite()) 24 | suite.addTest(package.suite()) 25 | return suite 26 | 27 | 28 | if __name__ == '__main__': 29 | unittest.main(defaultTest='suite') 30 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/tests/design.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2008 Christopher Lenz 4 | # All rights reserved. 5 | # 6 | # This software is licensed as described in the file COPYING, which 7 | # you should have received as part of this distribution. 8 | 9 | import doctest 10 | import unittest 11 | 12 | from couchdb import design 13 | from couchdb.tests import testutil 14 | 15 | 16 | class DesignTestCase(testutil.TempDatabaseMixin, unittest.TestCase): 17 | 18 | def test_options(self): 19 | options = {'collation': 'raw'} 20 | view = design.ViewDefinition( 21 | 'foo', 'foo', 22 | 'function(doc) {emit(doc._id, doc._rev)}', 23 | options=options) 24 | _, db = self.temp_db() 25 | view.sync(db) 26 | design_doc = db.get('_design/foo') 27 | self.assertTrue(design_doc['views']['foo']['options'] == options) 28 | 29 | 30 | def suite(): 31 | suite = unittest.TestSuite() 32 | suite.addTest(unittest.makeSuite(DesignTestCase)) 33 | suite.addTest(doctest.DocTestSuite(design)) 34 | return suite 35 | 36 | 37 | if __name__ == '__main__': 38 | unittest.main(defaultTest='suite') 39 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/tests/http.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2009 Christopher Lenz 4 | # All rights reserved. 5 | # 6 | # This software is licensed as described in the file COPYING, which 7 | # you should have received as part of this distribution. 8 | 9 | import doctest 10 | import socket 11 | import time 12 | import unittest 13 | from StringIO import StringIO 14 | 15 | from couchdb import http 16 | from couchdb.tests import testutil 17 | 18 | 19 | class SessionTestCase(testutil.TempDatabaseMixin, unittest.TestCase): 20 | 21 | def test_timeout(self): 22 | dbname, db = self.temp_db() 23 | timeout = 1 24 | session = http.Session(timeout=timeout) 25 | start = time.time() 26 | status, headers, body = session.request('GET', db.resource.url + '/_changes?feed=longpoll&since=1000&timeout=%s' % (timeout*2*1000,)) 27 | self.assertRaises(socket.timeout, body.read) 28 | self.failUnless(time.time() - start < timeout * 1.3) 29 | 30 | 31 | class ResponseBodyTestCase(unittest.TestCase): 32 | def test_close(self): 33 | class TestStream(StringIO): 34 | def isclosed(self): 35 | return len(self.buf) == self.tell() 36 | 37 | class Counter(object): 38 | def __init__(self): 39 | self.value = 0 40 | 41 | def __call__(self): 42 | self.value += 1 43 | 44 | counter = Counter() 45 | 46 | response = http.ResponseBody(TestStream('foobar'), counter) 47 | 48 | response.read(10) # read more than stream has. close() is called 49 | response.read() # steam ended. another close() call 50 | 51 | self.assertEqual(counter.value, 1) 52 | 53 | def test_double_iteration_over_same_response_body(self): 54 | class TestHttpResp(object): 55 | msg = {'transfer-encoding': 'chunked'} 56 | def __init__(self, fp): 57 | self.fp = fp 58 | 59 | def isclosed(self): 60 | return len(self.fp.buf) == self.fp.tell() 61 | 62 | data = 'foobarbaz' 63 | data = '\n'.join([hex(len(data))[2:], data]) 64 | response = http.ResponseBody(TestHttpResp(StringIO(data)), 65 | lambda *a, **k: None) 66 | self.assertEqual(list(response), ['foobarbaz']) 67 | self.assertEqual(list(response), []) 68 | 69 | 70 | def suite(): 71 | suite = unittest.TestSuite() 72 | suite.addTest(doctest.DocTestSuite(http)) 73 | suite.addTest(unittest.makeSuite(SessionTestCase, 'test')) 74 | suite.addTest(unittest.makeSuite(ResponseBodyTestCase, 'test')) 75 | return suite 76 | 77 | 78 | if __name__ == '__main__': 79 | unittest.main(defaultTest='suite') 80 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/tests/package.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import unittest 4 | import couchdb 5 | 6 | class PackageTestCase(unittest.TestCase): 7 | 8 | def test_exports(self): 9 | expected = set([ 10 | # couchdb.client 11 | 'Server', 'Database', 'Document', 12 | # couchdb.http 13 | 'HTTPError', 'PreconditionFailed', 'ResourceNotFound', 14 | 'ResourceConflict', 'ServerError', 'Unauthorized', 15 | 'Resource', 'Session' 16 | ]) 17 | exported = set(e for e in dir(couchdb) if not e.startswith('_')) 18 | self.assertTrue(expected <= exported) 19 | 20 | 21 | def suite(): 22 | suite = unittest.TestSuite() 23 | suite.addTest(unittest.makeSuite(PackageTestCase, 'test')) 24 | return suite 25 | 26 | 27 | if __name__ == '__main__': 28 | unittest.main(defaultTest='suite') 29 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/tests/testutil.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2007-2009 Christopher Lenz 4 | # All rights reserved. 5 | # 6 | # This software is licensed as described in the file COPYING, which 7 | # you should have received as part of this distribution. 8 | 9 | import random 10 | import sys 11 | from couchdb import client 12 | 13 | class TempDatabaseMixin(object): 14 | 15 | temp_dbs = None 16 | _db = None 17 | 18 | def setUp(self): 19 | self.server = client.Server(full_commit=False) 20 | 21 | def tearDown(self): 22 | if self.temp_dbs: 23 | for name in self.temp_dbs: 24 | self.server.delete(name) 25 | 26 | def temp_db(self): 27 | if self.temp_dbs is None: 28 | self.temp_dbs = {} 29 | # Find an unused database name 30 | while True: 31 | name = 'couchdb-python/%d' % random.randint(0, sys.maxint) 32 | if name not in self.temp_dbs: 33 | break 34 | db = self.server.create(name) 35 | self.temp_dbs[name] = db 36 | return name, db 37 | 38 | def del_db(self, name): 39 | del self.temp_dbs[name] 40 | self.server.delete(name) 41 | 42 | @property 43 | def db(self): 44 | if self._db is None: 45 | name, self._db = self.temp_db() 46 | return self._db 47 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/tools/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (C) 2008 Christopher Lenz 4 | # All rights reserved. 5 | # 6 | # This software is licensed as described in the file COPYING, which 7 | # you should have received as part of this distribution. 8 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/tools/dump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (C) 2007-2009 Christopher Lenz 5 | # All rights reserved. 6 | # 7 | # This software is licensed as described in the file COPYING, which 8 | # you should have received as part of this distribution. 9 | 10 | """Utility for dumping a snapshot of a CouchDB database to a multipart MIME 11 | file. 12 | """ 13 | 14 | from base64 import b64decode 15 | from optparse import OptionParser 16 | import sys 17 | 18 | from couchdb import __version__ as VERSION 19 | from couchdb import json 20 | from couchdb.client import Database 21 | from couchdb.multipart import write_multipart 22 | 23 | 24 | def dump_db(dburl, username=None, password=None, boundary=None, 25 | output=sys.stdout): 26 | db = Database(dburl) 27 | if username is not None and password is not None: 28 | db.resource.http.add_credentials(username, password) 29 | 30 | envelope = write_multipart(output, boundary=boundary) 31 | for docid in db: 32 | 33 | doc = db.get(docid, attachments=True) 34 | print >> sys.stderr, 'Dumping document %r' % doc.id 35 | attachments = doc.pop('_attachments', {}) 36 | jsondoc = json.encode(doc) 37 | 38 | if attachments: 39 | parts = envelope.open({ 40 | 'Content-ID': doc.id, 41 | 'ETag': '"%s"' % doc.rev 42 | }) 43 | parts.add('application/json', jsondoc) 44 | 45 | for name, info in attachments.items(): 46 | content_type = info.get('content_type') 47 | if content_type is None: # CouchDB < 0.8 48 | content_type = info.get('content-type') 49 | parts.add(content_type, b64decode(info['data']), { 50 | 'Content-ID': name 51 | }) 52 | parts.close() 53 | 54 | else: 55 | envelope.add('application/json', jsondoc, { 56 | 'Content-ID': doc.id, 57 | 'ETag': '"%s"' % doc.rev 58 | }) 59 | 60 | envelope.close() 61 | 62 | 63 | def main(): 64 | parser = OptionParser(usage='%prog [options] dburl', version=VERSION) 65 | parser.add_option('--json-module', action='store', dest='json_module', 66 | help='the JSON module to use ("simplejson", "cjson", ' 67 | 'or "json" are supported)') 68 | parser.add_option('-u', '--username', action='store', dest='username', 69 | help='the username to use for authentication') 70 | parser.add_option('-p', '--password', action='store', dest='password', 71 | help='the password to use for authentication') 72 | parser.set_defaults() 73 | options, args = parser.parse_args() 74 | 75 | if len(args) != 1: 76 | return parser.error('incorrect number of arguments') 77 | 78 | if options.json_module: 79 | json.use(options.json_module) 80 | 81 | dump_db(args[0], username=options.username, password=options.password) 82 | 83 | 84 | if __name__ == '__main__': 85 | main() 86 | -------------------------------------------------------------------------------- /python/couchdb-python/couchdb/tools/load.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (C) 2007-2009 Christopher Lenz 5 | # All rights reserved. 6 | # 7 | # This software is licensed as described in the file COPYING, which 8 | # you should have received as part of this distribution. 9 | 10 | """Utility for loading a snapshot of a CouchDB database from a multipart MIME 11 | file. 12 | """ 13 | 14 | from base64 import b64encode 15 | from optparse import OptionParser 16 | import sys 17 | 18 | from couchdb import __version__ as VERSION 19 | from couchdb import json 20 | from couchdb.client import Database 21 | from couchdb.multipart import read_multipart 22 | 23 | 24 | def load_db(fileobj, dburl, username=None, password=None, ignore_errors=False): 25 | db = Database(dburl) 26 | if username is not None and password is not None: 27 | db.resource.http.add_credentials(username, password) 28 | 29 | for headers, is_multipart, payload in read_multipart(fileobj): 30 | docid = headers['content-id'] 31 | 32 | if is_multipart: # doc has attachments 33 | for headers, _, payload in payload: 34 | if 'content-id' not in headers: 35 | doc = json.decode(payload) 36 | doc['_attachments'] = {} 37 | else: 38 | doc['_attachments'][headers['content-id']] = { 39 | 'data': b64encode(payload), 40 | 'content_type': headers['content-type'], 41 | 'length': len(payload) 42 | } 43 | 44 | else: # no attachments, just the JSON 45 | doc = json.decode(payload) 46 | 47 | del doc['_rev'] 48 | print>>sys.stderr, 'Loading document %r' % docid 49 | try: 50 | db[docid] = doc 51 | except Exception, e: 52 | if not ignore_errors: 53 | raise 54 | print>>sys.stderr, 'Error: %s' % e 55 | 56 | 57 | def main(): 58 | parser = OptionParser(usage='%prog [options] dburl', version=VERSION) 59 | parser.add_option('--input', action='store', dest='input', metavar='FILE', 60 | help='the name of the file to read from') 61 | parser.add_option('--ignore-errors', action='store_true', 62 | dest='ignore_errors', 63 | help='whether to ignore errors in document creation ' 64 | 'and continue with the remaining documents') 65 | parser.add_option('--json-module', action='store', dest='json_module', 66 | help='the JSON module to use ("simplejson", "cjson", ' 67 | 'or "json" are supported)') 68 | parser.add_option('-u', '--username', action='store', dest='username', 69 | help='the username to use for authentication') 70 | parser.add_option('-p', '--password', action='store', dest='password', 71 | help='the password to use for authentication') 72 | parser.set_defaults(input='-') 73 | options, args = parser.parse_args() 74 | 75 | if len(args) != 1: 76 | return parser.error('incorrect number of arguments') 77 | 78 | if options.input != '-': 79 | fileobj = open(options.input, 'rb') 80 | else: 81 | fileobj = sys.stdin 82 | 83 | if options.json_module: 84 | json.use(options.json_module) 85 | 86 | load_db(fileobj, args[0], username=options.username, 87 | password=options.password, ignore_errors=options.ignore_errors) 88 | 89 | 90 | if __name__ == '__main__': 91 | main() 92 | -------------------------------------------------------------------------------- /python/couchdb-python/doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | 15 | .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest 16 | 17 | all: html 18 | 19 | help: 20 | @echo "Please use \`make ' where is one of" 21 | @echo " html to make standalone HTML files" 22 | @echo " dirhtml to make HTML files named index.html in directories" 23 | @echo " pickle to make pickle files" 24 | @echo " json to make JSON files" 25 | @echo " htmlhelp to make HTML files and a HTML help project" 26 | @echo " qthelp to make HTML files and a qthelp project" 27 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 28 | @echo " changes to make an overview of all changed/added/deprecated items" 29 | @echo " linkcheck to check all external links for integrity" 30 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 31 | 32 | clean: 33 | -rm -rf $(BUILDDIR)/* 34 | 35 | html: 36 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 37 | @echo 38 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 39 | 40 | dirhtml: 41 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 42 | @echo 43 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 44 | 45 | pickle: 46 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 47 | @echo 48 | @echo "Build finished; now you can process the pickle files." 49 | 50 | json: 51 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 52 | @echo 53 | @echo "Build finished; now you can process the JSON files." 54 | 55 | htmlhelp: 56 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 57 | @echo 58 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 59 | ".hhp project file in $(BUILDDIR)/htmlhelp." 60 | 61 | qthelp: 62 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 63 | @echo 64 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 65 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 66 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/couchdb-python.qhcp" 67 | @echo "To view the help file:" 68 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/couchdb-python.qhc" 69 | 70 | latex: 71 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 72 | @echo 73 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 74 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ 75 | "run these through (pdf)latex." 76 | 77 | changes: 78 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 79 | @echo 80 | @echo "The overview file is in $(BUILDDIR)/changes." 81 | 82 | linkcheck: 83 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 84 | @echo 85 | @echo "Link check complete; look for any errors in the above output " \ 86 | "or in $(BUILDDIR)/linkcheck/output.txt." 87 | 88 | doctest: 89 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 90 | @echo "Testing of doctests in the sources finished, look at the " \ 91 | "results in $(BUILDDIR)/doctest/output.txt." 92 | -------------------------------------------------------------------------------- /python/couchdb-python/doc/changes.rst: -------------------------------------------------------------------------------- 1 | Changes 2 | ======= 3 | 4 | .. include:: ../ChangeLog.txt 5 | -------------------------------------------------------------------------------- /python/couchdb-python/doc/client.rst: -------------------------------------------------------------------------------- 1 | Basic CouchDB API: couchdb.client 2 | ================================= 3 | 4 | .. automodule:: couchdb.client 5 | 6 | 7 | Server 8 | ------ 9 | 10 | .. autoclass:: Server 11 | :members: 12 | 13 | 14 | Database 15 | -------- 16 | 17 | .. autoclass:: Database 18 | :members: 19 | 20 | 21 | Document 22 | -------- 23 | 24 | .. autoclass:: Document 25 | :members: 26 | 27 | 28 | ViewResults 29 | ----------- 30 | 31 | .. autoclass:: ViewResults 32 | :members: 33 | 34 | 35 | Row 36 | --- 37 | 38 | .. autoclass:: Row 39 | :members: 40 | -------------------------------------------------------------------------------- /python/couchdb-python/doc/getting-started.rst: -------------------------------------------------------------------------------- 1 | Getting started with couchdb-python 2 | =================================== 3 | 4 | Some snippets of code to get you started with writing code against CouchDB. 5 | 6 | Starting off:: 7 | 8 | >>> import couchdb 9 | >>> couch = couchdb.Server() 10 | 11 | This gets you a Server object, representing a CouchDB server. By default, it 12 | assumes CouchDB is running on localhost:5894. If your CouchDB server is 13 | running elsewhere, set it up like this: 14 | 15 | >>> couch = couchdb.Server('http://example.com:5984/') 16 | 17 | You can create a new database from Python, or use an existing database: 18 | 19 | >>> db = couch.create('test') # newly created 20 | >>> db = couch['mydb'] # existing 21 | 22 | After selecting a database, create a document and insert it into the db: 23 | 24 | >>> doc = {'foo': 'bar'} 25 | >>> db.save(doc) 26 | ('e0658cab843b59e63c8779a9a5000b01', '1-4c6114c65e295552ab1019e2b046b10e') 27 | >>> doc 28 | {'_rev': '1-4c6114c65e295552ab1019e2b046b10e', 'foo': 'bar', '_id': 'e0658cab843b59e63c8779a9a5000b01'} 29 | 30 | The ``save()`` method returns the ID and "rev" for the newly created document. 31 | You can also set your own ID by including an ``_id`` item in the document. 32 | 33 | Getting the document out again is easy: 34 | 35 | >>> db['e0658cab843b59e63c8779a9a5000b01'] 36 | 37 | 38 | To find all your documents, simply iterate over the database: 39 | 40 | >>> for id in db: 41 | ... print id 42 | ... 43 | 'e0658cab843b59e63c8779a9a5000b01' 44 | 45 | Now we can clean up the test document and database we created: 46 | 47 | >>> db.delete(doc) 48 | >>> couch.delete('test') 49 | -------------------------------------------------------------------------------- /python/couchdb-python/doc/index.rst: -------------------------------------------------------------------------------- 1 | .. -*- mode: rst; encoding: utf-8 -*- 2 | .. couchdb-python documentation master file, created by 3 | sphinx-quickstart on Thu Apr 29 18:32:43 2010. 4 | You can adapt this file completely to your liking, but it should at least 5 | contain the root `toctree` directive. 6 | 7 | Introduction 8 | ============ 9 | 10 | ``couchdb`` is Python package for working with CouchDB_ from Python code. 11 | It consists of the following main modules: 12 | 13 | * ``couchdb.client``: This is the client library for interfacing CouchDB 14 | servers. If you don't know where to start, this is likely to be what you're 15 | looking for. 16 | 17 | * ``couchdb.mapping``: This module provides advanced mapping between CouchDB 18 | JSON documents and Python objects. 19 | 20 | Additionally, the ``couchdb.view`` module implements a view server for 21 | views written in Python. 22 | 23 | There may also be more information on the `project website`_. 24 | 25 | .. _couchdb: http://couchdb.org/ 26 | .. _project website: http://code.google.com/p/couchdb-python 27 | .. _views written in Python: views 28 | 29 | Documentation 30 | ============= 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | :numbered: 35 | 36 | getting-started.rst 37 | views.rst 38 | client.rst 39 | mapping.rst 40 | changes.rst 41 | 42 | Indices and tables 43 | ================== 44 | 45 | * :ref:`genindex` 46 | * :ref:`modindex` 47 | * :ref:`search` 48 | -------------------------------------------------------------------------------- /python/couchdb-python/doc/mapping.rst: -------------------------------------------------------------------------------- 1 | Mapping CouchDB documents to Python objects: couchdb.mapping 2 | ============================================================ 3 | 4 | .. automodule:: couchdb.mapping 5 | 6 | Field types 7 | ----------- 8 | 9 | .. autoclass:: TextField 10 | .. autoclass:: FloatField 11 | .. autoclass:: IntegerField 12 | .. autoclass:: LongField 13 | .. autoclass:: BooleanField 14 | .. autoclass:: DecimalField 15 | .. autoclass:: DateField 16 | .. autoclass:: DateTimeField 17 | .. autoclass:: DictField 18 | .. autoclass:: ListField 19 | .. autoclass:: ViewField 20 | -------------------------------------------------------------------------------- /python/couchdb-python/doc/views.rst: -------------------------------------------------------------------------------- 1 | Writing views in Python 2 | ======================= 3 | 4 | The couchdb-python package comes with a view server to allow you to write 5 | views in Python instead of JavaScript. When couchdb-python is installed, it 6 | will install a script called couchpy that runs the view server. To enable 7 | this for your CouchDB server, add the following section to local.ini:: 8 | 9 | [query_servers] 10 | python=/usr/bin/couchpy 11 | 12 | After restarting CouchDB, the Futon view editor should show ``python`` in 13 | the language pull-down menu. Here's some sample view code to get you started:: 14 | 15 | def fun(doc): 16 | if doc['date']: 17 | yield doc['date'], doc 18 | 19 | Note that the ``map`` function uses the Python ``yield`` keyword to emit 20 | values, where JavaScript views use an ``emit()`` function. 21 | -------------------------------------------------------------------------------- /python/couchdb-python/setup.cfg: -------------------------------------------------------------------------------- 1 | [egg_info] 2 | tag_build = dev 3 | tag_svn_revision = true 4 | 5 | [build_sphinx] 6 | source-dir = doc/ 7 | build-dir = doc/build 8 | all_files = 1 9 | 10 | [upload_sphinx] 11 | upload-dir = doc/build/html 12 | -------------------------------------------------------------------------------- /python/object_recognition_core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wg-perception/object_recognition_core/ad17546b7f3b91e7fb2a8bd55e8ca4aebe8ed55b/python/object_recognition_core/__init__.py -------------------------------------------------------------------------------- /python/object_recognition_core/db/__init__.py: -------------------------------------------------------------------------------- 1 | # import from the boost wrapped C++ structures. Use a specific name in the imports intead 2 | # of an import * to make sure of what we have 3 | from object_recognition_core.boost.interface import ObjectDbParameters, ObjectDbTypes, Documents, Models, Document 4 | from .object_db import ObjectDb 5 | -------------------------------------------------------------------------------- /python/object_recognition_core/db/cells.py: -------------------------------------------------------------------------------- 1 | # Use a specific name in the imports intead of an import * to make sure of what we have 2 | from object_recognition_core.ecto_cells.db import ModelWriter, ObservationInserter, ObservationReader 3 | -------------------------------------------------------------------------------- /python/object_recognition_core/db/object_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module defining a common Python interface to an ObjectDb. 3 | It also provides a factory you can use to wrap your own DB 4 | """ 5 | 6 | from abc import ABCMeta 7 | from object_recognition_core.boost.interface import ObjectDbParameters 8 | from object_recognition_core.utils.find_classes import find_classes 9 | import json 10 | 11 | ######################################################################################################################## 12 | 13 | class ObjectDbFactory(object): 14 | """ 15 | A base class for a factory that can allow you to wrap your own ObjectDb 16 | """ 17 | 18 | __metaclass__ = ABCMeta 19 | 20 | @classmethod #see http://docs.python.org/library/abc.html#abc.ABCMeta.__subclasshook__ 21 | def __subclasshook__(cls, C): 22 | if C is ObjectDb: 23 | #all pipelines must have atleast this function. 24 | if any("type_name" in B.__dict__ for B in C.__mro__): 25 | return True 26 | return NotImplemented 27 | 28 | @classmethod 29 | def type_name(cls): 30 | """ 31 | Return the code name for your ObjectDb 32 | """ 33 | raise NotImplementedError("The ObjectDb type_name function must return a string name.") 34 | 35 | @classmethod 36 | def object_db(cls, db_params): 37 | """ 38 | Return the ObjectDbBase object 39 | :param db_params: an object of type ObjectDbParameters that you can use to initiate your DB 40 | """ 41 | raise NotImplementedError("The ObjectDb object_db function must return a C++ wrapped ObjectDb.") 42 | 43 | ######################################################################################################################## 44 | 45 | def core_db_types(): 46 | """ 47 | Return the current DB types implemented in object_recognition_core 48 | :returns: a list of string matching the ObjectDb types 49 | """ 50 | types = [] 51 | from object_recognition_core.db import ObjectDbTypes 52 | for db_type in ObjectDbTypes.values.values(): 53 | types.append(str(db_type).split('.')[-1].lower()) 54 | types.remove('noncore') 55 | return types 56 | 57 | def ObjectDb(db_params): 58 | """ 59 | Returns the ObjectDb for the given db_params given as a dictionary 60 | It crawls the object_recognition_core module or any other module 61 | in order to find the ObjectDb you are looking for 62 | 63 | :param db_params: ObjectDbParameters defining a DB, or json string or dict 64 | """ 65 | 66 | if (isinstance(db_params, ObjectDbParameters)): 67 | db_params_raw = db_params.raw 68 | object_db_params = db_params 69 | elif (isinstance(db_params, str)): 70 | db_params_raw = json.loads(db_params) 71 | object_db_params = ObjectDbParameters(db_params) 72 | else: 73 | db_params_raw = db_params 74 | object_db_params = ObjectDbParameters(db_params) 75 | 76 | # check if it is a conventional DB from object_recognition_core 77 | db_type = db_params_raw.get('type', None) 78 | if db_type.lower() in core_db_types(): 79 | from object_recognition_core.boost.interface import ObjectDb as ObjectDbCpp 80 | return ObjectDbCpp(object_db_params) 81 | 82 | # otherwise, look for the possible modules for that DB type 83 | module = db_params_raw.get('module', None) 84 | if not module: 85 | raise RuntimeError("The 'module' property is not set. It is required to find the DB object") 86 | for db_factory in find_classes([module], [ObjectDbFactory]): 87 | if db_factory.__name__ == db_type: 88 | return db_factory.object_db(db_params_raw) 89 | -------------------------------------------------------------------------------- /python/object_recognition_core/filters/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wg-perception/object_recognition_core/ad17546b7f3b91e7fb2a8bd55e8ca4aebe8ed55b/python/object_recognition_core/filters/__init__.py -------------------------------------------------------------------------------- /python/object_recognition_core/filters/masker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Module defining several inputs for the object recognition pipeline 4 | """ 5 | 6 | import ecto 7 | import ecto.opts 8 | import sys 9 | 10 | ######################################################################################################################## 11 | 12 | class Masker(ecto.BlackBox): 13 | """ 14 | Blackbox that masks out certain areas of the image 15 | If a new type of masker is created, add it in the enum list and update the add_arguments and parse_arguments 16 | """ 17 | 18 | #TODO FIXME 19 | DEPTH = 'depth' 20 | 21 | def __init__(self, plasm): 22 | """ 23 | sinks: a list of the sinks to use 24 | """ 25 | ecto.BlackBox.__init__(self, plasm) 26 | 27 | # add the different possible outputs 28 | self._cell_factory = {} 29 | self._cells = [] 30 | 31 | # common ecto implementation 32 | def declare_io(self, p, i ,o): 33 | if self._cells: 34 | return {'points3d': self._cells[0]['points3d']} 35 | else: 36 | return {} 37 | 38 | def expose_outputs(self): 39 | if self._cells: 40 | return {'mask': self._cells[-1]['mask']} 41 | else: 42 | return {} 43 | 44 | def expose_parameters(self): 45 | return {} 46 | 47 | def connections(self): 48 | return [] 49 | 50 | # Functions to help with the argument parsing 51 | def add_arguments(self, parser): 52 | from ecto_object_recognition.common.filters import DepthFilter 53 | self._cell_factory[Masker.DEPTH] = ecto.opts.cell_options(parser, DepthFilter, 'depth_filter') 54 | 55 | def parse_arguments(self, parser): 56 | args = parser.parse_args() 57 | if hasattr(args, 'd_min') or hasattr(args, 'd_max'): 58 | cell = self._cell_factory[Source.ROS_BAG](parser) 59 | self._cells.append(cell) 60 | -------------------------------------------------------------------------------- /python/object_recognition_core/io/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wg-perception/object_recognition_core/ad17546b7f3b91e7fb2a8bd55e8ca4aebe8ed55b/python/object_recognition_core/io/__init__.py -------------------------------------------------------------------------------- /python/object_recognition_core/io/sink.py: -------------------------------------------------------------------------------- 1 | '''' 2 | Module defining several outputs for the object recognition pipeline 3 | ''' 4 | 5 | from object_recognition_core.ecto_cells.io import GuessCsvWriter as GuessCsvWriterCpp 6 | 7 | ######################################################################################################################## 8 | 9 | class SinkBase(object): 10 | """ 11 | This is a base class for a sink: you don't need to have your sink cell inherit from that class but if you do, 12 | it will make sure that its inputs/outputs fit the ORK standard (which is good if you want to interact with 13 | the official ORK pipelines). 14 | You need to call the BlackBox constructor in your __init__ first and then this function. Typically, yout __init__ is 15 | 16 | >>> class Foo(ecto.BlackBox, SinkBase): 17 | >>> def __init__(self, *args, **kwargs): 18 | >>> ecto.BlackBox.__init__(self, *args, **kwargs) 19 | >>> SinkBase.__init__(self) 20 | """ 21 | 22 | def __init__(self): 23 | """ 24 | This ensures that the given cell exhibits the minimal interface to be 25 | considered a sink for object recognition 26 | """ 27 | validate_sink(self) 28 | 29 | def validate_sink(cell): 30 | """ 31 | This ensures that the given cell exhibits the minimal interface to be 32 | considered a sink for object recognition 33 | """ 34 | assert(isinstance(cell, SinkBase)) 35 | inputs = dir(cell.inputs) 36 | # all sources must produce the following 37 | for x in ['pose_results']: 38 | if x not in inputs: 39 | raise NotImplementedError('This cell does not correctly implement the sink interface. Must have an input named %s' % x) 40 | # type checks 41 | possible_types_dict = {'pose_results': [ 42 | 'std::vector >', 43 | 'ecto::tendril::none']} 44 | for input_name, possible_types in possible_types_dict.items(): 45 | type_name = cell.inputs.at(input_name).type_name 46 | # test the type: the ecto::tendril::none is here for a passthrough 47 | if type_name not in type_name: 48 | raise NotImplementedError('The cell with doc\n%s\n does not correctly implement the sink interface.\n' 49 | 'Must have an input named %s, with type one of %s\n' 50 | 'This cells input at %s has type %s' % (cell.__doc__, input_name, 51 | ','.join(possible_types.split()), input_name, type_name)) 52 | return cell 53 | 54 | ######################################################################################################################## 55 | 56 | class GuessCsvWriter(GuessCsvWriterCpp, SinkBase): 57 | 58 | def __init__(self, *args, **kwargs): 59 | GuessCsvWriterCpp.__init__(self, *args, **kwargs) 60 | SinkBase.__init__(self) 61 | -------------------------------------------------------------------------------- /python/object_recognition_core/io/voter.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module defining several voters for the object recognition pipeline 3 | """ 4 | 5 | from object_recognition_core.ecto_cells.voter import Aggregator as AggregatorCpp 6 | import ecto 7 | from ecto.blackbox import BlackBoxCellInfo as CellInfo 8 | 9 | ######################################################################################################################## 10 | 11 | class VoterBase(object): 12 | """ 13 | This is a base class for a voter: you don't need to have your voter cell inherit from that class but if you do, 14 | it will make sure that its inputs/outputs fit the ORK standard (which is good if you want to interact with 15 | the official ORK pipelines). 16 | You need to call the BlackBox constructor in your __init__ first and then this function. Typically, your __init__ is 17 | class Foo(ecto.BlackBox, VoterBase): 18 | def __init__(self, *args, **kwargs): 19 | ecto.BlackBox.__init__(self, *args, **kwargs) 20 | VoterBase.__init__(self) 21 | """ 22 | 23 | def __init__(self): 24 | """ 25 | This ensures that the given cell exhibits the minimal interface to be 26 | considered a voter for object recognition 27 | """ 28 | pass 29 | 30 | ######################################################################################################################## 31 | 32 | class Aggregator(ecto.BlackBox, VoterBase): 33 | """ 34 | Cell meant to take several outputs from pipelines and aggregate the results 35 | """ 36 | def __init__(self, *args, **kwargs): 37 | ecto.BlackBox.__init__(self, *args, **kwargs) 38 | VoterBase.__init__(self) 39 | 40 | @staticmethod 41 | def declare_cells(_p): 42 | return {'main': CellInfo(AggregatorCpp)} 43 | 44 | @staticmethod 45 | def declare_forwards(_p): 46 | return ({'main': 'all'}, {'main': 'all'}, {'main': 'all'}) 47 | 48 | def connections(self, _p): 49 | return [self.main] 50 | -------------------------------------------------------------------------------- /python/object_recognition_core/pipelines/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wg-perception/object_recognition_core/ad17546b7f3b91e7fb2a8bd55e8ca4aebe8ed55b/python/object_recognition_core/pipelines/__init__.py -------------------------------------------------------------------------------- /python/object_recognition_core/pipelines/detection.py: -------------------------------------------------------------------------------- 1 | ''' 2 | ABC for Detection pipelines 3 | ''' 4 | from ecto import BlackBoxCellInfo as CellInfo 5 | from object_recognition_core.ecto_cells.io import PipelineInfo 6 | from object_recognition_core.utils.json_helper import obj_to_cpp_json_str 7 | import ecto 8 | 9 | class DetectorBase(object): 10 | """ 11 | This is a base class for a detection pipeline: you don't need to have your pipeline cell inherit from that class 12 | but if you do, it will make sure that its inputs/outputs fit the ORK standard (which is good if you want to 13 | interact with the official ORK pipelines). 14 | You need to call the BlackBox constructor in your __init__ first and then this function. Typically, your __init__ is 15 | 16 | >>> class Foo(ecto.BlackBox, DetectorBase): 17 | >>> def __init__(self, *args, **kwargs): 18 | >>> ecto.BlackBox.__init__(self, *args, **kwargs) 19 | >>> DetectorBase.__init__(self) 20 | """ 21 | def __init__(self, do_check_object_ids=True, do_check_db=True): 22 | """ 23 | Normal constructor that checks for the validity of inputs/outputs 24 | 25 | :param do_check_object_ids: if True, it is checked that the cell has an input 'json_object_ids' that is a string 26 | :param do_check_db: if True, it is checked that the cell has an input 'json_db' that is a string 27 | """ 28 | checks = {'output': [ ('pose_results', ['std::vector >'], 'std::vector'), 29 | ], 30 | 'input': [], 31 | 'param': []} 32 | if do_check_object_ids: 33 | checks['param'].append(('json_object_ids', ['std::string', 'boost::python::api::object'], 'std::string')) 34 | if do_check_db: 35 | checks['param'].append(('json_db', ['std::string', 'boost::python::api::object'], 'std::string')) 36 | 37 | for check_type, check_list in list(checks.items()): 38 | tendrils = {'input':self.inputs, 'output':self.outputs, 'param':self.params}[check_type] 39 | for check in check_list: 40 | tendril_name, tendril_types_cpp, tendril_types_print = check 41 | if tendril_name not in tendrils: 42 | raise RuntimeError('The detector needs to have a "%s" %s tendril.' % (tendril_name, check_type)) 43 | # check for the right type for the pose_results output 44 | type_name = tendrils.at(tendril_name).type_name 45 | if type_name not in tendril_types_cpp: 46 | raise RuntimeError('The detector does not have a "%s" tendril of the right type.\n' % tendril_name + 47 | 'Must have a %s named "%s", with type "%s"\n and not "%s"' % (check_type, 48 | tendril_name, tendril_types_print, type_name)) 49 | 50 | ######################################################################################################################## 51 | 52 | class DetectorAndInfo(ecto.BlackBox): 53 | """ 54 | This blackbox contains a detection pipeline and a cell that simply forwards its parameters 55 | Each executed pipeline is actually wrapped in such an object so that outputs can be linked 56 | to where they are coming from (through the info). 57 | This is for private implementation 58 | """ 59 | def __init__(self, detection_class, *args, **kwargs): 60 | self._detector = detection_class(*args, **kwargs) 61 | self._info = PipelineInfo(parameters=obj_to_cpp_json_str(kwargs)) 62 | ecto.BlackBox.__init__(self, *args, **kwargs) 63 | 64 | def declare_cells(self, _p): 65 | return {'detector': self._detector, 66 | 'info': self._info 67 | } 68 | 69 | @staticmethod 70 | def declare_forwards(_p): 71 | return ({'detector': 'all'}, {'detector': 'all'}, {'detector': 'all', 'info': 'all'}) 72 | 73 | def connections(self, _p): 74 | return [ self.detector, self.info ] 75 | -------------------------------------------------------------------------------- /python/object_recognition_core/pipelines/training.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Defines the base class for any training pipeline 3 | ''' 4 | import ecto 5 | 6 | class TrainerBase(object): 7 | """ 8 | This is a base class for a training pipeline: you don't need to have your pipeline cell inherit from that class 9 | but if you do, it will be listed as an official training pipeline 10 | You need to call the BlackBox constructor in your __init__ first and then this function. Typically, your __init__ is 11 | 12 | >>> class Foo(ecto.BlackBox, TrainerBase): 13 | >>> def __init__(self, *args, **kwargs): 14 | >>> ecto.BlackBox.__init__(self, *args, **kwargs) 15 | >>> TrainerBase.__init__(self) 16 | """ 17 | pass 18 | -------------------------------------------------------------------------------- /python/object_recognition_core/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wg-perception/object_recognition_core/ad17546b7f3b91e7fb2a8bd55e8ca4aebe8ed55b/python/object_recognition_core/utils/__init__.py -------------------------------------------------------------------------------- /python/object_recognition_core/utils/doc.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file implements functions to help documentation: 3 | - autogeneration of config files 4 | """ 5 | from object_recognition_core.utils.find_classes import find_classes 6 | import ecto 7 | import os 8 | 9 | def config_yaml_for_ecto_cell(cls, header=None): 10 | """ 11 | Given an ecto cell, generate YAML for all the possibles parameters 12 | 13 | :param cls: the class of an ecto cell 14 | :param header: this is just the name of the cell section. If None, no header is written and no indent is given 15 | """ 16 | if header: 17 | res = '%s:\n' % header 18 | indent = ' ' 19 | else: 20 | res = '' 21 | indent = '' 22 | res += '%stype: %s\n' % (indent, cls.__name__) 23 | res += '%smodule: %s\n' % (indent, cls.__module__) 24 | # display the parameters 25 | res += '%sparameters:\n' % indent 26 | p = ecto.Tendrils() 27 | try: 28 | cls.declare_params(p) 29 | except AttributeError: 30 | p = cls.params 31 | for tendril_name, tendril in list(p.items()): 32 | # Split the doc string to 100 characters 33 | line = '%s # ' % indent 34 | for word in tendril.doc.split(): 35 | if len(line + ' ' + word) > 100: 36 | res += line + '\n' 37 | line = '%s # %s' % (indent, word) 38 | else: 39 | line += ' ' + word 40 | res += line + '\n' 41 | res += '%s %s: %s\n' % (indent, tendril_name, tendril.val) 42 | 43 | return res 44 | 45 | ######################################################################################################################## 46 | 47 | def config_yaml_for_ecto_cells(class_type): 48 | """ 49 | Function returning an array of doc strings for each cell of class `class_type` in object_recognition 50 | :param class_type: one of 'detection_pipeline', 'training_pipeline', 'source', 'sink' 51 | """ 52 | from object_recognition_core.io.sink import SinkBase 53 | from object_recognition_core.io.source import SourceBase 54 | from object_recognition_core.io.voter import VoterBase 55 | from object_recognition_core.pipelines.detection import DetectorBase 56 | from object_recognition_core.pipelines.training import TrainerBase 57 | 58 | supported_classes = {'detection_pipeline': DetectorBase, 'training_pipeline': TrainerBase, 59 | 'source': SourceBase, 'sink': SinkBase} 60 | if class_type not in supported_classes: 61 | raise RuntimeError('Class type not support: %s. Accepted are: %s' % (class_type, 62 | str(supported_classes.keys()))) 63 | 64 | modules = set() 65 | # go over the modules on the PYTHONPATH and only keep the ones that start with object_recognition 66 | if 'PYTHONPATH' not in os.environ: 67 | raise RuntimeError('You need a PYTHONPATH to use that script') 68 | for path in os.environ['PYTHONPATH'].split(':'): 69 | if not os.path.isdir(path): 70 | continue 71 | for name in os.listdir(path): 72 | if os.path.isdir(os.path.join(path,name)) and (name.startswith('object_recognition') or name.startswith('ork')): 73 | modules.add(name) 74 | # find all the objects of the right type 75 | classes = find_classes(modules, [supported_classes[class_type]]) 76 | 77 | # create a string with the config documentation 78 | res_list = [] 79 | 80 | class_number = 0 81 | for class_object in classes: 82 | res = config_yaml_for_ecto_cell(class_object, '%s_%s' % (class_type, class_number)) 83 | 84 | class_number += 1 85 | res_list.append(res) 86 | 87 | return res_list 88 | -------------------------------------------------------------------------------- /python/object_recognition_core/utils/json_helper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Module providing simple function to deal with the conversion from file to JSON 4 | """ 5 | 6 | import json 7 | 8 | def file_to_json(file_path): 9 | """ 10 | Given the path of a file containing JSON, load it and make sure there is no unicode 11 | """ 12 | json_params = json.loads(str(open(file_path).read())) 13 | json_params = eval(str(json_params).replace("'", '"').replace('u"', '"').replace('{u', '{')) 14 | return json_params 15 | 16 | def obj_to_cpp_json_str(obj): 17 | """ 18 | Given a dictionary or a list object, convert it to a JSON string for C++ to parse. All unicode 19 | references are removed 20 | 21 | :param obj: a dict or a list 22 | """ 23 | return json.dumps(obj) 24 | -------------------------------------------------------------------------------- /python/object_recognition_core/utils/parser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Module defining a parser that can read arguments from a file as long as an argument @file_path is given. 4 | It will also ignore every line preceded by //, # 5 | """ 6 | import argparse 7 | import sys as _sys 8 | 9 | class ObjectRecognitionParser(argparse.ArgumentParser): 10 | def __init__(self, *args): 11 | argparse.ArgumentParser.__init__(self, *args, fromfile_prefix_chars='@') 12 | 13 | # copied and tweaked from http://bugs.python.org/issue10523 14 | def _read_args_from_files(self, arg_strings): 15 | filtered_arg_strings = self.remove_launchfile_generated_args(arg_strings) 16 | # expand arguments referencing files 17 | new_arg_strings = [] 18 | for arg_string in filtered_arg_strings: 19 | 20 | # for regular arguments, just add them back into the list 21 | if not arg_string or arg_string[0] not in self.fromfile_prefix_chars: 22 | new_arg_strings.append(arg_string) 23 | 24 | # replace arguments referencing files with the file content 25 | else: 26 | try: 27 | args_file = open(arg_string[1:]) 28 | try: 29 | arg_strings = [] 30 | for line in args_file: 31 | if not line: 32 | continue 33 | if line[0].startswith('//') or line[0].startswith('#'): 34 | continue 35 | arg_strings.extend(line.strip().split()) 36 | arg_strings = self._read_args_from_files(arg_strings) 37 | 38 | new_arg_strings.extend(arg_strings) 39 | finally: 40 | args_file.close() 41 | except IOError: 42 | err = _sys.exc_info()[1] 43 | self.error(str(err)) 44 | 45 | # return the modified argument list 46 | return new_arg_strings 47 | 48 | def remove_launchfile_generated_args(self, arg_strings): 49 | new_arg_strings = [] 50 | for arg_string in arg_strings: 51 | if not arg_string.startswith('__name:=') and not arg_string.startswith('__log:='): 52 | new_arg_strings.append(arg_string) 53 | return new_arg_strings 54 | 55 | 56 | # The following function should be the only one needed but the implementation is now broken in Python 57 | """ 58 | def convert_arg_line_to_args(self, arg_line): 59 | if (not arg_line) or arg_line.startswith('//') or arg_line.startswith('#'): 60 | yield '' 61 | else: 62 | for arg in arg_line.split(): 63 | yield arg 64 | """ 65 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from distutils.core import setup 3 | from catkin_pkg.python_setup import generate_distutils_setup 4 | 5 | d = generate_distutils_setup( 6 | packages=['object_recognition_core', 'object_recognition_core.db', 'object_recognition_core.filters', 7 | 'object_recognition_core.io', 'object_recognition_core.pipelines', 8 | 'object_recognition_core.utils', 'couchdb'], 9 | package_dir={'': 'python'}, 10 | scripts=['apps/detection', 'apps/training', 'apps/dbscripts/copy_db.py', 11 | 'apps/dbscripts/mesh_add.py', 'apps/dbscripts/object_add.py', 12 | 'apps/dbscripts/object_delete.py', 'apps/dbscripts/object_search.py'] 13 | ) 14 | 15 | setup(**d) 16 | -------------------------------------------------------------------------------- /share/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # install some files so that they can be used by other projects when using the macros 2 | set(TEST_FILES run_test.sh 3 | desktop_test.sh 4 | test_config.py 5 | test_help.py 6 | test_sink.py 7 | test_source.py 8 | ) 9 | 10 | file(COPY ${TEST_FILES} 11 | DESTINATION ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/test) 12 | 13 | install(PROGRAMS ${TEST_FILES} 14 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/test 15 | ) 16 | -------------------------------------------------------------------------------- /share/desktop_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | . $1 3 | $2 --scheduler Singlethreaded --niter 100 4 | $2 --scheduler Threadpool --niter 100 5 | -------------------------------------------------------------------------------- /share/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | . $1 3 | $2 $3 4 | -------------------------------------------------------------------------------- /share/test_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | This script tests whether a detection pipeline can be created given a config file. 4 | It is not meant to be run as a test of object_recognition but as a test for and by each 5 | pipeline independently. 6 | """ 7 | 8 | from ecto.opts import scheduler_options 9 | from object_recognition_core.pipelines.plasm import create_plasm 10 | from object_recognition_core.utils.training_detection_args import create_parser, read_arguments 11 | 12 | if __name__ == '__main__': 13 | # create an ORK parser 14 | parser = create_parser() 15 | 16 | # add ecto options 17 | scheduler_options(parser) 18 | 19 | # read the config file 20 | args = parser.parse_args() 21 | ork_params, args = read_arguments(args) 22 | 23 | # override the database parameters 24 | for cell_name, parameters in ork_params.items(): 25 | if 'parameters' in parameters and 'object_ids' in parameters['parameters']: 26 | parameters['parameters']['object_ids'] = '[]' 27 | 28 | # create the big plasm 29 | plasm = create_plasm(ork_params) 30 | -------------------------------------------------------------------------------- /share/test_help.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import subprocess 3 | import sys 4 | import os 5 | 6 | script = sys.argv[1] 7 | 8 | print script 9 | subprocess.check_call([script,'--help']) 10 | -------------------------------------------------------------------------------- /share/test_import.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import subprocess 4 | import sys 5 | 6 | new_dir = sys.argv[1] 7 | 8 | current_path = os.getcwd() 9 | new_cwd = os.path.join(current_path, new_dir) 10 | os.chdir(new_cwd) 11 | print 'move from ' + current_path + ' to ' + os.getcwd() 12 | 13 | for file_name in os.listdir(os.getcwd()): 14 | if file_name.endswith('.py'): 15 | module_name = file_name.split('.py')[0] 16 | print 'module "%s" in %s' % (module_name, os.getcwd()) 17 | __import__('test_opposing_dot_estimator') 18 | __import__('bilateral') 19 | # __import__(module_name) 20 | -------------------------------------------------------------------------------- /share/test_sink.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | This script tests whether a sink can be created given some command line arguments. 4 | It is not meant to be run as a test of object_recognition but as a test for and by each 5 | module independently. 6 | """ 7 | 8 | from object_recognition_core.io.sink import SinkBase 9 | from object_recognition_core.utils.find_classes import find_cell 10 | import sys 11 | 12 | if __name__ == '__main__': 13 | sink_name = sys.argv[1] 14 | 15 | SinkClass = find_cell([sys.argv[2]], sink_name, [SinkBase]) 16 | 17 | if len(sys.argv)>=4: 18 | args = eval(sys.argv[3]) 19 | else: 20 | args = {} 21 | 22 | sink = SinkClass(**args) 23 | print 'Found sink ' + sink_name 24 | -------------------------------------------------------------------------------- /share/test_source.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | This script tests whether a source can be created given some command line arguments. 4 | It is not meant to be run as a test of object_recognition but as a test for and by each 5 | module independently. 6 | """ 7 | 8 | from object_recognition_core.io.source import SourceBase 9 | from object_recognition_core.utils.find_classes import find_cell 10 | import sys 11 | 12 | if __name__ == '__main__': 13 | source_name = sys.argv[1] 14 | 15 | SourceClass = find_cell([sys.argv[2]], source_name, [SourceBase]) 16 | 17 | if len(sys.argv)>=4: 18 | args = eval(sys.argv[3]) 19 | else: 20 | args = {} 21 | 22 | source = SourceClass(**args) 23 | print 'Found source ' + source_name 24 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(common) 2 | add_subdirectory(db) 3 | add_subdirectory(filters) 4 | add_subdirectory(io) 5 | add_subdirectory(pipelines) 6 | -------------------------------------------------------------------------------- /src/common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Boost REQUIRED) 2 | find_package(PythonLibs REQUIRED) 3 | 4 | include_directories(SYSTEM 5 | ${Boost_INCLUDE_DIRS} 6 | ${PYTHON_INCLUDE_PATH} 7 | ) 8 | 9 | add_library(object_recognition_core_common SHARED 10 | dict_json_conversion.cpp 11 | object_info.cpp 12 | ) 13 | 14 | target_link_libraries(object_recognition_core_common 15 | object_recognition_core_db 16 | ${Boost_LIBRARIES} 17 | ) 18 | 19 | install(TARGETS object_recognition_core_common 20 | DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 21 | ) 22 | 23 | # create a Python module to wrap the PoseResult 24 | add_library(common_interface SHARED module_python.cpp 25 | wrap_db_pose_result.cpp 26 | ) 27 | 28 | target_link_libraries(common_interface ${Boost_LIBRARIES} 29 | object_recognition_core_db 30 | ) 31 | 32 | set_target_properties(common_interface PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION}/boost 33 | OUTPUT_NAME common 34 | PREFIX "" 35 | ) 36 | 37 | install(TARGETS common_interface 38 | DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}/boost 39 | ) 40 | -------------------------------------------------------------------------------- /src/common/dict_json_conversion.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | #include 41 | 42 | namespace bp = boost::python; 43 | 44 | namespace object_recognition_core 45 | { 46 | namespace common 47 | { 48 | or_json::mObject 49 | BpDictToJson(const bp::dict &bp_dict) 50 | { 51 | or_json::mObject params; 52 | bp::list l = bp_dict.items(); 53 | for (int j = 0, end = bp::len(l); j < end; ++j) 54 | { 55 | std::string key = bp::extract(l[j][0]); 56 | // Try to extract a string 57 | { 58 | bp::extract extract(l[j][1]); 59 | if (extract.check()) 60 | { 61 | params[key] = or_json::mValue(std::string(extract)); 62 | continue; 63 | } 64 | } 65 | // Try to extract an int 66 | { 67 | bp::extract extract(l[j][1]); 68 | if (extract.check()) 69 | { 70 | params[key] = or_json::mValue(int(extract)); 71 | continue; 72 | } 73 | } 74 | throw std::runtime_error("BpDictToJson: unimplemented type"); 75 | } 76 | return params; 77 | } 78 | 79 | bp::dict 80 | JsonToBpDict(const or_json::mObject & map) 81 | { 82 | bp::dict bp_dict; 83 | for (or_json::mObject::const_iterator iter = map.begin(), end = map.end(); iter != end; ++iter) 84 | { 85 | switch (iter->second.type()) 86 | { 87 | case or_json::int_type: 88 | bp_dict[iter->first] = iter->second.get_int(); 89 | break; 90 | case or_json::str_type: 91 | bp_dict[iter->first] = iter->second.get_str(); 92 | break; 93 | default: 94 | throw std::runtime_error("MapToBpDict unimplemented type"); 95 | } 96 | } 97 | return bp_dict; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/common/module_python.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace object_recognition_core 4 | { 5 | namespace common 6 | { 7 | void 8 | wrap_db_pose_result(); 9 | } 10 | } 11 | 12 | BOOST_PYTHON_MODULE(common) 13 | { 14 | using namespace object_recognition_core::common; 15 | wrap_db_pose_result(); 16 | } 17 | -------------------------------------------------------------------------------- /src/db/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Boost COMPONENTS 2 | system 3 | serialization 4 | thread 5 | filesystem 6 | regex 7 | REQUIRED 8 | ) 9 | 10 | find_package(CURL REQUIRED) 11 | find_package(OpenCV REQUIRED) 12 | 13 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 14 | 15 | # create a shared library to deal with the different DB components 16 | add_library(object_recognition_core_db 17 | SHARED 18 | db.cpp 19 | db_couch.cpp 20 | db_filesystem.cpp 21 | opencv.cpp 22 | ../../include/object_recognition_core/common/json_spirit/json_spirit_reader.cpp 23 | ../../include/object_recognition_core/common/json_spirit/json_spirit_value.cpp 24 | ../../include/object_recognition_core/common/json_spirit/json_spirit_writer.cpp 25 | model_utils.cpp 26 | observations.cpp 27 | view.cpp 28 | ) 29 | 30 | target_link_libraries(object_recognition_core_db ${Boost_LIBRARIES} 31 | ${catkin_LIBRARIES} 32 | ${CURL_LIBRARIES} 33 | ${OpenCV_LIBRARIES} 34 | ) 35 | 36 | install(TARGETS object_recognition_core_db 37 | DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 38 | ) 39 | 40 | # create a Python module to wrap the DB functionalities 41 | add_library(db_interface SHARED 42 | module_python.cpp 43 | wrap_db_parameters.cpp 44 | wrap_db_documents.cpp 45 | wrap_object_db.cpp 46 | ) 47 | 48 | target_link_libraries(db_interface 49 | object_recognition_core_common 50 | object_recognition_core_db 51 | ) 52 | 53 | set_target_properties(db_interface PROPERTIES 54 | LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION}/boost 55 | OUTPUT_NAME interface 56 | PREFIX "" 57 | ) 58 | 59 | install(TARGETS db_interface 60 | DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}/boost 61 | ) 62 | 63 | # Create the ecto module with a few cells 64 | ectomodule(db DESTINATION object_recognition_core/ecto_cells 65 | INSTALL 66 | module.cpp 67 | ModelWriter.cpp 68 | ObservationReader.cpp 69 | ObservationWriter.cpp 70 | ) 71 | 72 | link_ecto(db 73 | object_recognition_core_db 74 | ) 75 | -------------------------------------------------------------------------------- /src/db/ObservationReader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define DEFAULT_COUCHDB_URL "http://localhost:5984" 16 | using ecto::tendrils; 17 | namespace object_recognition_core 18 | { 19 | namespace prototypes 20 | { 21 | 22 | using db::Document; 23 | 24 | struct ObservationReader 25 | { 26 | static void 27 | declare_io(const tendrils& params, tendrils& inputs, tendrils& outputs) 28 | { 29 | inputs.declare(&ObservationReader::observation_, "document", "The observation id to load."); 30 | Observation::declare(outputs, false); //not required 31 | } 32 | 33 | int 34 | process(const tendrils& inputs, const tendrils& outputs) 35 | { 36 | Observation obs; 37 | obs << &(*observation_); 38 | obs >> outputs; 39 | return 0; 40 | } 41 | ecto::spore observation_; 42 | }; 43 | } 44 | } 45 | ECTO_CELL(db, object_recognition_core::prototypes::ObservationReader, "ObservationReader", 46 | "Reads observations from the database.") 47 | -------------------------------------------------------------------------------- /src/db/ObservationWriter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using ecto::tendrils; 12 | 13 | namespace object_recognition_core 14 | { 15 | namespace prototypes 16 | { 17 | using db::Document; 18 | 19 | struct ObservationInserter 20 | { 21 | static void 22 | declare_params(tendrils& params) 23 | { 24 | params.declare < std::string > ("object_id", "The object id, to associate this frame with.").required(true); 25 | params.declare < std::string > ("session_id", "The session id, to associate this frame with.").required(true); 26 | 27 | params.declare(&ObservationInserter::db_params_, "db_params", "The database parameters"); 28 | } 29 | static void 30 | declare_io(const tendrils& params, tendrils& inputs, tendrils& outputs) 31 | { 32 | Observation::declare(inputs, true); //required 33 | } 34 | 35 | ObservationInserter() 36 | : 37 | frame_number(0) 38 | { 39 | } 40 | void 41 | on_object_id_change(const std::string& id) 42 | { 43 | object_id = id; 44 | } 45 | void 46 | on_session_id_change(const std::string& id) 47 | { 48 | session_id = id; 49 | frame_number = 0; 50 | } 51 | void 52 | configure(const tendrils& params, const tendrils& inputs, const tendrils& outputs) 53 | { 54 | db = db_params_->generateDb(); 55 | ecto::spore < std::string > object_id = params["object_id"]; 56 | object_id.set_callback(boost::bind(&ObservationInserter::on_object_id_change, this, _1)); 57 | ecto::spore < std::string > session_id = params["session_id"]; 58 | session_id.set_callback(boost::bind(&ObservationInserter::on_session_id_change, this, _1)); 59 | } 60 | int 61 | process(const tendrils& inputs, const tendrils& outputs) 62 | { 63 | Observation obs; 64 | obs << inputs; 65 | // Use the frame_number tendril if provided 66 | if (inputs.find("frame_number")->second->user_supplied()) 67 | frame_number = inputs.get("frame_number"); 68 | 69 | std::cout << "Inserting frame: " << frame_number << std::endl; 70 | obs.frame_number = frame_number++; 71 | 72 | obs.object_id = object_id; 73 | obs.session_id = session_id; 74 | Document doc; 75 | doc.set_db(db); 76 | obs >> &doc; 77 | doc.Persist(); 78 | return ecto::OK; 79 | } 80 | int frame_number; 81 | std::string object_id, session_id; 82 | ecto::spore db_params_; 83 | db::ObjectDbPtr db; 84 | }; 85 | } 86 | } 87 | 88 | ECTO_CELL(db, object_recognition_core::prototypes::ObservationInserter, "ObservationInserter", 89 | "Inserts observations into the database.") 90 | -------------------------------------------------------------------------------- /src/db/db_default.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #ifndef LOCAL_ORK_CORE_DB_DEFAULT_H_ 37 | #define LOCAL_ORK_CORE_DB_DEFAULT_H_ 38 | 39 | #include 40 | 41 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 42 | 43 | namespace object_recognition_core { 44 | namespace db { 45 | 46 | template 47 | struct ObjectDbDefaults { 48 | static object_recognition_core::db::ObjectDbParametersRaw default_raw_parameters(); 49 | static object_recognition_core::db::DbType type(); 50 | }; 51 | } 52 | } 53 | 54 | #endif /* LOCAL_ORK_CORE_DB_DEFAULT_H_ */ 55 | -------------------------------------------------------------------------------- /src/db/module.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | ECTO_DEFINE_MODULE(db) 4 | { 5 | } 6 | -------------------------------------------------------------------------------- /src/db/module_python.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace object_recognition_core 4 | { 5 | namespace db 6 | { 7 | void 8 | wrap_db_documents(); 9 | void 10 | wrap_db_models(); 11 | void 12 | wrap_db_parameters(); 13 | void 14 | wrap_object_db_local(); 15 | } 16 | } 17 | 18 | BOOST_PYTHON_MODULE(interface) 19 | { 20 | using namespace object_recognition_core::db; 21 | wrap_db_documents(); 22 | wrap_db_models(); 23 | wrap_object_db_local(); 24 | wrap_db_parameters(); 25 | } 26 | -------------------------------------------------------------------------------- /src/db/observations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using ecto::tendrils; 13 | 14 | namespace object_recognition_core 15 | { 16 | namespace prototypes 17 | { 18 | void 19 | Observation::declare(ecto::tendrils& t, bool required) 20 | { 21 | t.declare("image", "An rgb full frame image.").required(required); 22 | t.declare("depth", "The 16bit depth image.").required(required); 23 | t.declare("mask", "The mask.").required(required); 24 | t.declare("R", "The orientation.").required(required); 25 | t.declare("T", "The translation.").required(required); 26 | t.declare("K", "The camera intrinsic matrix").required(required); 27 | t.declare("frame_number", "The frame number"); 28 | } 29 | void 30 | operator>>(Observation& o, db::DummyDocument* doc) 31 | { 32 | std::map intrinsics, extrinsics; 33 | intrinsics["K"] = o.K; 34 | extrinsics["R"] = o.R; 35 | extrinsics["T"] = o.T; 36 | std::stringstream intr_ss, extr_ss; 37 | object_recognition_core::db::mats2yaml(intrinsics, intr_ss); 38 | object_recognition_core::db::mats2yaml(extrinsics, extr_ss); 39 | 40 | object_recognition_core::db::png_attach(o.image, *doc, "image"); 41 | object_recognition_core::db::png_attach(o.depth, *doc, "depth"); 42 | object_recognition_core::db::png_attach(o.mask, *doc, "mask"); 43 | doc->set_attachment_stream("intrinsics.yml", intr_ss, "text/x-yaml"); 44 | doc->set_attachment_stream("extrinsics.yml", extr_ss, "text/x-yaml"); 45 | doc->set_field("Type", "Observation"); 46 | doc->set_field("object_id", o.object_id); 47 | doc->set_field("session_id", o.session_id); 48 | doc->set_field("frame_number", o.frame_number); 49 | } 50 | 51 | void 52 | operator<<(Observation& o, const db::DummyDocument* doc) 53 | { 54 | o.object_id = doc->get_field("object_id"); 55 | o.session_id = doc->get_field("session_id"); 56 | o.frame_number = doc->get_field("frame_number"); 57 | object_recognition_core::db::get_png_attachment(o.image, *doc, "image"); 58 | object_recognition_core::db::get_png_attachment(o.depth, *doc, "depth"); 59 | object_recognition_core::db::get_png_attachment(o.mask, *doc, "mask"); 60 | std::stringstream intr_ss, extr_ss; 61 | doc->get_attachment_stream("intrinsics.yml", intr_ss); 62 | doc->get_attachment_stream("extrinsics.yml", extr_ss); 63 | std::map intrinsics, extrinsics; 64 | intrinsics["K"] = cv::Mat(); 65 | extrinsics["R"] = cv::Mat(); 66 | extrinsics["T"] = cv::Mat(); 67 | object_recognition_core::db::yaml2mats(intrinsics, intr_ss); 68 | object_recognition_core::db::yaml2mats(extrinsics, extr_ss); 69 | o.K = intrinsics["K"]; 70 | o.R = extrinsics["R"]; 71 | o.T = extrinsics["T"]; 72 | } 73 | void 74 | operator>>(Observation& obs, const ecto::tendrils& o) 75 | { 76 | o["image"] << obs.image; 77 | o["depth"] << obs.depth; 78 | o["mask"] << obs.mask; 79 | o["R"] << obs.R; 80 | o["T"] << obs.T; 81 | o["K"] << obs.K; 82 | o["frame_number"] << obs.frame_number; 83 | } 84 | 85 | void 86 | operator<<(Observation& obs, const ecto::tendrils& i) 87 | { 88 | i["image"] >> obs.image; 89 | i["mask"] >> obs.mask; 90 | i["depth"] >> obs.depth; 91 | if (obs.depth.depth() == CV_32F) 92 | { 93 | obs.depth.clone().convertTo(obs.depth, CV_16UC1, 1000); 94 | } 95 | i["R"] >> obs.R; 96 | i["T"] >> obs.T; 97 | i["K"] >> obs.K; 98 | } 99 | 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/db/opencv.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace fs = boost::filesystem; 11 | 12 | namespace object_recognition_core 13 | { 14 | namespace db 15 | { 16 | std::string 17 | temporary_yml_file_name(bool do_gzip) 18 | { 19 | std::string fname; 20 | { 21 | char buffer[L_tmpnam]; 22 | char* p = std::tmpnam(buffer); 23 | if (p != NULL) 24 | { 25 | fname = std::string(buffer) + ".yml"; 26 | if (do_gzip) 27 | fname += ".gz"; 28 | } 29 | else 30 | throw std::runtime_error("Could not create temporary filename!"); 31 | } 32 | return fname; 33 | } 34 | 35 | void 36 | mats2yaml(const std::map& mm,std::ostream& out, bool do_gzip) 37 | { 38 | std::string fname = temporary_yml_file_name(do_gzip); 39 | { 40 | cv::FileStorage fs(fname, cv::FileStorage::WRITE); 41 | typedef std::pair pair_t; 42 | BOOST_FOREACH(const pair_t& x, mm) 43 | { 44 | fs << x.first << x.second; 45 | } 46 | } 47 | { 48 | std::ifstream reader(fname.c_str()); 49 | out << reader.rdbuf(); 50 | } 51 | fs::remove(fname.c_str()); 52 | } 53 | 54 | void 55 | yaml2mats(std::map& mm,std::istream& in, bool do_gzip) 56 | { 57 | std::string fname = temporary_yml_file_name(do_gzip); 58 | { 59 | std::ofstream writer(fname.c_str()); 60 | writer << in.rdbuf(); 61 | } 62 | { 63 | cv::FileStorage fs(fname, cv::FileStorage::READ); 64 | 65 | typedef std::pair pair_t; 66 | BOOST_FOREACH(const pair_t& x, mm) 67 | { 68 | fs[x.first] >> mm[x.first]; 69 | } 70 | } 71 | fs::remove(fname.c_str()); 72 | } 73 | 74 | void 75 | png_attach(cv::Mat image, db::DummyDocument& doc, const std::string& name) 76 | { 77 | std::vector buffer; 78 | std::stringstream ss; 79 | cv::imencode(".png", image, buffer); 80 | std::copy(buffer.begin(), buffer.end(), std::ostream_iterator(ss)); 81 | doc.set_attachment_stream(name, ss, "image/png"); 82 | } 83 | 84 | void 85 | get_png_attachment(cv::Mat& image, const db::DummyDocument& doc, const std::string& name) 86 | { 87 | std::stringstream ss; 88 | doc.get_attachment_stream(name, ss); 89 | std::streampos length = ss.tellp(); 90 | std::vector buffer(length); 91 | ss.read((char*) buffer.data(), length); 92 | image = cv::imdecode(buffer, cv::IMREAD_ANYDEPTH | cv::IMREAD_ANYCOLOR); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/db/wrap_object_db.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #include 37 | 38 | namespace bp = boost::python; 39 | 40 | namespace object_recognition_core 41 | { 42 | namespace db 43 | { 44 | /** Function used to create an ObjectDb object from Python 45 | * @param db_params 46 | * @param python_document_ids 47 | * @return 48 | */ 49 | ObjectDbPtr 50 | ObjectDbConstructor(const ObjectDbParameters & db_params) 51 | { 52 | return db_params.generateDb(); 53 | } 54 | 55 | void 56 | wrap_object_db_local() 57 | { 58 | wrap_object_db("ObjectDb", ObjectDbConstructor); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/filters/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # deal with the detection TOD module 2 | ectomodule(filters DESTINATION object_recognition_core/ecto_cells 3 | INSTALL 4 | depth_filter.cpp 5 | module.cpp 6 | ) 7 | 8 | link_ecto(filters 9 | ${OpenCV_LIBS} 10 | ${Boost_LIBRARIES} 11 | ) 12 | -------------------------------------------------------------------------------- /src/filters/depth_filter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #include 37 | 38 | #include 39 | 40 | #include 41 | 42 | namespace object_recognition_core 43 | { 44 | namespace filters 45 | { 46 | struct DepthFilter 47 | { 48 | static void 49 | declare_params(ecto::tendrils& params) 50 | { 51 | params.declare("d_min", "The minimal distance at which object become interesting (in meters)", 52 | -std::numeric_limits::max()); 53 | params.declare("d_max", "The maximal distance at which object become interesting (in meters)", 54 | std::numeric_limits::max()); 55 | } 56 | 57 | void 58 | configure(const ecto::tendrils& params, const ecto::tendrils& inputs, const ecto::tendrils& outputs) 59 | { 60 | d_min_ = params.get("d_min"); 61 | } 62 | 63 | static void 64 | declare_io(const ecto::tendrils& params, ecto::tendrils& inputs, ecto::tendrils& outputs) 65 | { 66 | inputs.declare("points3d", "The 3d points: width by height by 3 channels"); 67 | outputs.declare("mask", "The mask of what is within the depth range in the image"); 68 | } 69 | 70 | int 71 | process(const ecto::tendrils& inputs, const ecto::tendrils& outputs) 72 | { 73 | // Get the depth 74 | std::vector channels(3); 75 | cv::split(inputs.get("points3d"), channels); 76 | 77 | cv::Mat output = ((d_min_ < channels[2]) & (channels[2] < d_max_)); 78 | 79 | outputs["mask"] << output; 80 | return ecto::OK; 81 | } 82 | private: 83 | float d_min_, d_max_; 84 | }; 85 | } 86 | } 87 | 88 | ECTO_CELL(filters, object_recognition_core::filters::DepthFilter, "depth_filter", 89 | "Given a depth image, return the mask of what is between two depths.") 90 | -------------------------------------------------------------------------------- /src/filters/module.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #include 37 | 38 | ECTO_DEFINE_MODULE(filters) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /src/io/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # deal with the basci io cells 2 | ectomodule(io DESTINATION object_recognition_core/ecto_cells 3 | INSTALL 4 | module.cpp 5 | csv.cpp 6 | GuessCsvWriter.cpp 7 | GuessTerminalWriter.cpp 8 | PipelineInfo.cpp 9 | ) 10 | 11 | link_ecto(io ${OpenCV_LIBRARIES} 12 | object_recognition_core_common 13 | ) 14 | 15 | # deal with the basic voter cells 16 | ectomodule(voter DESTINATION object_recognition_core/ecto_cells 17 | INSTALL 18 | Aggregator.cpp 19 | module_voter.cpp 20 | ) 21 | 22 | link_ecto(voter ${OpenCV_LIBRARIES} 23 | object_recognition_core_db 24 | ) 25 | -------------------------------------------------------------------------------- /src/io/GuessTerminalWriter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #include 37 | 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | 44 | #include 45 | 46 | using ecto::tendrils; 47 | using object_recognition_core::common::PoseResult; 48 | using object_recognition_core::db::ObjectId; 49 | 50 | namespace object_recognition_core 51 | { 52 | namespace io 53 | { 54 | /** Ecto implementation of a module that takes object id and poses and that 55 | * outputs them to the command line 56 | */ 57 | struct GuessTerminalWriter 58 | { 59 | static void 60 | declare_params(tendrils& p) 61 | { 62 | p.declare("base_directory", "Base directory"); 63 | p.declare("config_file", "Configuration file"); 64 | } 65 | 66 | static void 67 | declare_io(const tendrils& params, tendrils& inputs, tendrils& outputs) 68 | { 69 | inputs.declare(&GuessTerminalWriter::pose_results_, "pose_results", "The results of object recognition"); 70 | } 71 | 72 | /** Get the 2d keypoints and figure out their 3D position from the depth map 73 | * @param inputs 74 | * @param outputs 75 | * @return 76 | */ 77 | int 78 | process(const tendrils& inputs, const tendrils& outputs) 79 | { 80 | // match to our objects 81 | BOOST_FOREACH(const common::PoseResult & pose_result, *pose_results_) 82 | { 83 | const ObjectId & object_id = pose_result.object_id(); 84 | cv::Matx33f R = pose_result.R(); 85 | cv::Vec3f T = pose_result.T(); 86 | 87 | //poseInfo.frame = point_cloud.header.seq; 88 | std::cout << "Found object " << object_id << " with pose (R,t) = " << std::endl << cv::Mat(R) << " " << cv::Mat(T) 89 | << std::endl; 90 | } 91 | 92 | return 0; 93 | } 94 | private: 95 | /** The object recognition results */ 96 | ecto::spore > pose_results_; 97 | }; 98 | } 99 | } 100 | 101 | ECTO_CELL(io, object_recognition_core::io::GuessTerminalWriter, "GuessTerminalWriter", 102 | "Given guesses, writes them to the terminal.") 103 | -------------------------------------------------------------------------------- /src/io/PipelineInfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * twoDToThreeD.cpp 3 | * 4 | * Created on: Jun 16, 2011 5 | * Author: vrabaud 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | using ecto::tendrils; 15 | 16 | namespace object_recognition_core 17 | { 18 | namespace io 19 | { 20 | /** Ecto implementation of a module that takes object recognition results and writes them to a CSV file 21 | */ 22 | struct PipelineInfo 23 | { 24 | static void 25 | declare_params(tendrils& p) 26 | { 27 | p.declare(&PipelineInfo::parameters_str_, "parameters", "The JSON parameters of the pipeline."); 28 | } 29 | 30 | static void 31 | declare_io(const tendrils& params, tendrils& inputs, tendrils& outputs) 32 | { 33 | outputs.declare(&PipelineInfo::parameters_str_, "parameters_str", "The parameters as a JSON string."); 34 | outputs.declare(&PipelineInfo::parameters_, "parameters", "The parameters as a JSON dict."); 35 | } 36 | 37 | void 38 | configure(const tendrils& params, const tendrils& inputs, const tendrils& outputs) 39 | { 40 | *parameters_ = object_recognition_core::to_json(*parameters_str_); 41 | } 42 | 43 | int 44 | process(const tendrils& inputs, const tendrils& outputs) 45 | { 46 | return ecto::OK; 47 | } 48 | private: 49 | ecto::spore parameters_str_; 50 | ecto::spore parameters_; 51 | }; 52 | } 53 | } 54 | 55 | ECTO_CELL(io, object_recognition_core::io::PipelineInfo, "PipelineInfo", 56 | "Spits out the parameters given as a JSON sting.") 57 | -------------------------------------------------------------------------------- /src/io/module.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #include 37 | 38 | ECTO_DEFINE_MODULE(io) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /src/io/module_voter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #include 37 | 38 | ECTO_DEFINE_MODULE(voter) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /src/pipelines/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Eigen) 2 | include_directories(SYSTEM ${Eigen_INCLUDE_DIRS}) 3 | 4 | # module with a pipeline that returns a constant value 5 | ectomodule(pipelines DESTINATION object_recognition_core/ecto_cells 6 | INSTALL 7 | module.cpp 8 | ConstantPipeline.cpp 9 | ) 10 | 11 | link_ecto(pipelines ${OpenCV_LIBRARIES} 12 | object_recognition_core_common 13 | ) 14 | -------------------------------------------------------------------------------- /src/pipelines/module.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Software License Agreement (BSD License) 3 | * 4 | * Copyright (c) 2009, Willow Garage, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following 15 | * disclaimer in the documentation and/or other materials provided 16 | * with the distribution. 17 | * * Neither the name of Willow Garage, Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived 19 | * from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | #include 37 | 38 | ECTO_DEFINE_MODULE(pipelines) 39 | { 40 | } 41 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/test.cmake) 2 | 3 | # deal with the subdirectories as they contain macros 4 | add_subdirectory(db) 5 | 6 | object_recognition_core_pytest(test_import) 7 | object_recognition_core_pytest(test_config) 8 | 9 | object_recognition_core_desktop_test(view_observations) 10 | 11 | # check that at least the help completes correctly 12 | object_recognition_core_help_test(${CMAKE_CURRENT_SOURCE_DIR}/../apps/detection) 13 | object_recognition_core_help_test(${CMAKE_CURRENT_SOURCE_DIR}/../apps/training) 14 | 15 | # check the different sources 16 | object_recognition_core_source_test(OpenNI "object_recognition_core.io" "{}") 17 | 18 | # check the different sinks 19 | object_recognition_core_sink_test(GuessCsvWriter "object_recognition_core.io" "{}") 20 | 21 | # check the constant pipeline 22 | object_recognition_core_config_test(${CMAKE_CURRENT_SOURCE_DIR}/detection.test.ork) 23 | -------------------------------------------------------------------------------- /test/db/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # test some Python interfaces 2 | object_recognition_core_pytest(db_test) 3 | 4 | # TODO reenable but only locally so that the test does not fail on the farm 5 | return() 6 | # Testing core functionalities 7 | catkin_add_gtest(or-db-test main.cpp 8 | db_test.cpp 9 | ) 10 | add_dependencies(or-db-test object_recognition_core_db) 11 | target_link_libraries(or-db-test object_recognition_core_db) 12 | -------------------------------------------------------------------------------- /test/db/couch_surfing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import couchdb 4 | import sys 5 | 6 | def create_db(db_name,couch): 7 | if db_name in couch: 8 | db = couch[db_name] 9 | else: 10 | db = couch.create(db_name) 11 | return db 12 | 13 | server_url = 'http://localhost:5984' 14 | couch = couchdb.Server(server_url) 15 | 16 | bag_name = sys.argv[1] 17 | db = create_db('bags',couch) 18 | doc = { 'bag': bag_name.split('/')[-1] } 19 | db.save(doc) 20 | db.put_attachment(doc=doc,content=open(bag_name),filename='data.bag',content_type='application/octet-stream') 21 | couch.delete('bags') -------------------------------------------------------------------------------- /test/db/db_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from object_recognition_core.db import ObjectDbTypes, ObjectDb, ObjectDbParameters 4 | from object_recognition_core.db.tools import db_params_to_db 5 | from object_recognition_core.db.object_db import core_db_types 6 | 7 | print 'Existing core types: ' + str(core_db_types()) 8 | 9 | str_to_enum = {'CouchDB': ObjectDbTypes.COUCHDB, 'filesystem': ObjectDbTypes.FILESYSTEM, 'empty': ObjectDbTypes.EMPTY } 10 | 11 | # test default parameters 12 | for db_params_raw in [{'type': 'CouchDB', 'root': 'http://localhost:5984', 'collection': 'object_recognition'}, 13 | {'path': '/tmp', 'type': 'filesystem', 'collection': 'object_recognition'}, 14 | {'type': 'empty'}]: 15 | type_str = db_params_raw['type'] 16 | print 'starting type ' + type_str 17 | db_params = ObjectDbParameters(db_params_raw) 18 | 19 | db = ObjectDb(db_params) 20 | db_params_new = db.parameters().raw 21 | 22 | for dic1, dic2 in [(db_params_raw, db_params_new), (db_params_new, db_params_raw)]: 23 | for k, v in dic1.items(): 24 | if (k not in dic2) or (k in dic2 and dic2[k] != v): 25 | raise RuntimeError('Key "%s" in %s but not in %s' % (str(k), str(dic1), str(dic2))) 26 | 27 | if str_to_enum[type_str] != db_params.type: 28 | raise RuntimeError('The "type" argument in db_params are wrong for db of type %s' % type_str) 29 | 30 | print 'ending type ' + type_str 31 | 32 | # test that we can convert a JSON string to an ObjectDbParameters type 33 | db_params_to_db(db_params) 34 | 35 | print 'all good' 36 | -------------------------------------------------------------------------------- /test/db/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char** argv) 4 | { 5 | ::testing::InitGoogleTest(&argc, argv); 6 | return RUN_ALL_TESTS(); 7 | } 8 | -------------------------------------------------------------------------------- /test/detection.test.ork: -------------------------------------------------------------------------------- 1 | pipeline: 2 | type: ConstantDetector 3 | module: object_recognition_core.ecto_cells.pipelines 4 | -------------------------------------------------------------------------------- /test/test_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | This script test the robustness of the pipeline to different kinds of config files 4 | """ 5 | 6 | import yaml 7 | from object_recognition_core.utils.training_detection_args import read_arguments_from_string, OrkConfigurationError 8 | 9 | if __name__ == '__main__': 10 | # Now, check a few problematic strings 11 | for config_string in [ 12 | # non-yaml string 13 | """ 14 | lkdg 15 | random_crap: 16 | """, 17 | # string with unknown keys 18 | """ 19 | custom: 'hello' 20 | """, 21 | # empty parameters 22 | """ 23 | """, 24 | # module required elements are missing 25 | """ 26 | pipeline: 27 | type: whatever 28 | """ 29 | ]: 30 | try: 31 | read_arguments_from_string(config_string) 32 | except yaml.scanner.ScannerError: 33 | continue 34 | except OrkConfigurationError: 35 | continue 36 | -------------------------------------------------------------------------------- /test/test_import.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from object_recognition_core import * 3 | from object_recognition_core.io.sink import * 4 | from object_recognition_core.io.source import * 5 | from object_recognition_core.io.voter import * 6 | -------------------------------------------------------------------------------- /test/view_observations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import argparse 5 | import time 6 | import tempfile 7 | import os 8 | import math 9 | import subprocess 10 | 11 | import couchdb 12 | 13 | import ecto 14 | from ecto_opencv import highgui 15 | import object_recognition 16 | from object_recognition_core.db import tools as dbtools, models 17 | from object_recognition_core.dbcells import ObservationReader 18 | 19 | db_url = dbtools.DEFAULT_SERVER_URL 20 | 21 | #database ritual 22 | couch = couchdb.Server(db_url) 23 | dbs = dbtools.init_object_databases(couch) 24 | sessions = dbs['sessions'] 25 | observations = dbs['observations'] 26 | results = models.Session.all(sessions) 27 | obs_ids = [] 28 | 29 | for session in results: 30 | obs_ids += models.find_all_observations_for_session(observations, session.id) 31 | 32 | if len(obs_ids) == 0: 33 | raise RuntimeError("There are no observations available.") 34 | 35 | db_reader = capture.ObservationReader('db_reader', db_params=ObjectDbParameters({'type':'CouchDB', 'root':db_url, 36 | 'collection':'observations'})) 37 | #observation dealer will deal out each observation id. 38 | observation_dealer = ecto.Dealer(tendril=db_reader.inputs.at('observation'), iterable=obs_ids) 39 | fps = highgui.FPSDrawer('FPS drawer') 40 | plasm = ecto.Plasm() 41 | #View all of the observations. 42 | plasm.connect( 43 | observation_dealer[:] >> db_reader['observation'], 44 | db_reader['image'] >> fps[:], 45 | fps[:] >> highgui.imshow('image display', name='image')[:], 46 | db_reader['depth'] >> highgui.imshow('depth display', name='depth')[:], 47 | db_reader['mask'] >> highgui.imshow('mask display', name='mask')[:], 48 | ) 49 | from ecto.opts import doit 50 | doit(plasm, "View observations from the database.", locals=vars()) 51 | -------------------------------------------------------------------------------- /web_ui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # install the web interface 2 | install(DIRECTORY _attachments 3 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}/web_ui/ 4 | ) 5 | install(FILES _id 6 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}/web_ui/ 7 | ) 8 | install(PROGRAMS push.sh 9 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}/web_ui/ 10 | ) 11 | 12 | # create a target to install a web interface 13 | find_program(COUCHAPP couchapp) 14 | 15 | if(COUCHAPP-NOTFOUND) 16 | message(STATUS "In order to install the webui, please install couchapp.") 17 | message(STATUS "sudo pip install -U couchapp") 18 | return() 19 | endif() 20 | 21 | add_custom_target(or_web_ui) 22 | 23 | set(OR_WEB_UI_LOCATION http://localhost:5984/or_web_ui CACHE STRING "The location for the web ui to be installed to.") 24 | add_custom_command(TARGET or_web_ui 25 | COMMAND ${COUCHAPP} push ${CMAKE_CURRENT_SOURCE_DIR} ${OR_WEB_UI_LOCATION} 26 | ) 27 | -------------------------------------------------------------------------------- /web_ui/_attachments/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Object Recognition DB 4 | 5 | 6 |

7 | Welcome the Object Recognition Database UI. 8 |
9 |

13 |

14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /web_ui/_attachments/objects.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 44 | 45 | 46 | 47 |

Object Listing

48 |
49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /web_ui/_id: -------------------------------------------------------------------------------- 1 | _design/viewer 2 | -------------------------------------------------------------------------------- /web_ui/push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #sudo pip install -U couchapp" 3 | DIR="$( cd "$( dirname "$0" )" && pwd )" 4 | couchapp push ${DIR} http://localhost:5984/or_web_ui 5 | --------------------------------------------------------------------------------