{ "info": { "author": "S. Filhol, A. Perret, G. Sutter, and L. Girod", "author_email": "simon.filhol@geo.uio.no", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy" ], "description": "\n# Photo4D: open-source time-lapse photogrammetry \n\nContributors by alphabetical orders:\n- Simon Filhol (simon.filhol@geo.uio.no)\n- Luc Girod (luc.girod@geo.uio.no)\n- Alexis Perret (aperret2010@hotmail.fr)\n- Guillaume Sutter (sutterguigui@gmail.com)\n\n## Description\n\nThis project consists of an automated program to generate point cloud from time-lapse set of images from independent cameras. The software: \n1. sorts images by timestamps, \n2. assess the image quality based on lumincace and bluriness, \n3. identify automatically GCPs through the stacks of images, \n4. run Micmac to compute point clouds, and \n5. convert point cloud to rasters. (not implemented)\n\nThe project should be based on open-source libraries, for public release. \n\n## Installation\n1. install the latest version of [micmac](https://micmac.ensg.eu/index.php/Install)\n\n2. install python 3.6, and with anaconda, create a virtual environment with the following packages: \n - opencv \n - pandas \n - matplotlib\n - lxml\n - pillow\n - [pyxif](https://github.com/zenwerk/Pyxif) (that needs to be downloaded from https://github.com/zenwerk/Pyxif)\n ```sh\n wget https://github.com/zenwerk/Pyxif/archive/master.zip\n unzip Pyxif-master.zip\n cd Pyxif-master\n python setup.py install\n ```\n - [PDAL](https://pdal.io/)\n - json\n\n 3. The package is available via Pypi\n\n ```python\n pip install photo4d\n ```\n\n## Usage\n\n### 1. prepare your environment: \n - create a Python >= 3.6 virtual environment in which you install the required libraries (see above)\n - create a folder for the project with inside the project folder a folder called Images containing itself one folder per\n - Organize your photo with one folder per camera. For instance folder /cam1 constains all the images from Camera 1.\n camera\n\n```bash\n\u251c\u2500\u2500 Project\n\u00a0\u00a0 \u2514\u2500\u2500 Images\n\u00a0 \u00a0 \u251c\u2500\u2500 Cam1\n \u251c\u2500\u2500 Cam2\n \u251c\u2500\u2500 Cam3\n \u00a0\u00a0 \u2514\u2500\u2500 Cam...\n```\n\n\n### 2. Use the Photo4d class to process the images through MicMac\n\nSet the path correctly in the file MicmacApp/Class_photo4D.py, and follow these steps\n\n```python\n\n############################################################\n## Part 1\n\nimport photo4d as p4d\n\n# Create a new photo4d object by indicating the Project path\nmyproj = p4d.Photo4d(project_path=\"point to project folder /Project\")\n\n# Algorithm to sort images in triplets, and create the reference table with sets :date, valid set, image names\nmyproj.sort_picture()\n\n# Algorithm to check picture quality (exposure and blurriness)\nmyproj.check_picture_quality()\n\n############################################################\n## Part 2: Estimate camera orientation\n\n# Compute camera orientation using the timeSIFT method:\nmyproj.timeSIFT_orientation()\n\n# Convert a text file containing the GCP coordinates to the proper format (.xml) for Micmac\nmyproj.prepare_gcp_files(path_to_GCP_file, file_format=\"N_X_Y_Z\")\n\n# Select a set to input GCPs\nmyproj.set_selected_set(\"DSC02728.JPG\")\n\n# Input GCPs in 3 steps\n# first select 3 to five GCPs to pre-orient the images\nmyproj.pick_initial_gcps()\n\n# Apply transformation based on the few GCPs previously picked\nmyproj.compute_transform()\n\n# Pick additionnal GCPs, that are now pre-estimated\nmyproj.pick_all_gcps()\n\n############################################################\n## Part2, optional: pick GCPs on extre image set\n## If you need to pick GCPs on another set of images, change selected set (this can be repeated n times):\n#myproj.compute_transform()\n#myproj.set_selected_set(\"DSC02871.JPG\")\n#myproj.pick_all_gcps()\n\n# Compute final transform using all picked GCPs\nmyproj.compute_transform(doCampari=True)\n\n## FUNCTION TO CHANGE FOR TIMESIFT\n# myproj.create_mask() #To be finished\n\n############################################################\n## Part3: Compute point clouds\n\n# Compute point cloud, correlation matrix, and depth matrix for each set of image\nmyproj.process_all_timesteps()\n\n# Clean (remove) the temporary working direction\nmyproj.clean_up_tmp()\n\n```\n\n### 3. Process the point clouds with [PDAL](https://pdal.io/)\n\n**Currently Under Development**\n\n[PDAL](https://pdal.io/) is a python library to process point cloud. It has an extensive library of algorithms available, and here we wrapped a general method to filter and extract Digital Elevation Models (DEMs) from the point clouds derived in the previous step.\n\nMicmac produces point clouds in the format `.ply`. The functions in the python class `pcl_process()` can convert, filter and crop the `.ply` point clouds and save them as `.las` files. Then the function `convert_all_pcl2dem()` will convert all point clouds stored in `my_pcl.las_pcl_flist` to DEMs. \n\nWith the function `my_pcl.custom_pipeline()`, it is possible to build custom processing pipeline following the PDAL JSON syntax. This pipeline can then be executed by running the function `my_pcl.apply_custom_pipeline()`.\n\nSee the source file [Class_pcl_processing.py](./photo4d/Class_pcl_processing.py) for more details.\n\n```python\n\n# Create a pcl_class object, indication the path to the photo4d project\nmy_pcl = p4d.pcl_process(project_path=\"path_to_project_folder\")\n\nmy_pcl.resolution = 1 # set the resolution of the final DEMs\n\n# Set the bounding box the Region of Interest (ROI)\nmy_pcl.crop_xmin = 416100\nmy_pcl.crop_xmax = 416900\nmy_pcl.crop_ymin = 6715900\nmy_pcl.crop_ymax = 6716700\nmy_pcl.nodata = -9999\n\n# add path og the .ply point cloud files to the python class\nmy_pcl.add_ply_pcl()\n\n# filter the point clouds with pdal routine, and save resulting point clouds as .las file\nmy_pcl.filter_all_pcl()\n\n# add path of the .las files\nmy_pcl.add_las_pcl()\n\n# conver the .las point clouds to DEMs (geotiff)\nmy_pcl.convert_all_pcl2dem()\n\n# Extract Value orthophoto from RGB \nmy_pcl.extract_all_ortho_value()\n\n```\n\nAfter this section you have clean point clouds, as well as DEMs in GeoTiff ready!\n\n\n## Ressources\n\n- Micmac: http://micmac.ensg.eu/index.php/Accueil\n- Image processing images: skimage, openCV, Pillow\n- python package to read exif data: https://pip.pypa.io/en/latest/user_guide/\n\n## Development\n\nMessage us to be added as a contributor, then if you can also modify the code to your own convenience with the following steps:\n\nTo work on a development version and keep using the latest change install it with the following\n\n```shell\ngit clone git@github.com:ArcticSnow/photo4D.git\npip install -e [path2folder/photo4D]\n```\n\nand to upload latest change to Pypi.org, simply:\n\n1. change the version number in the file ```photo4d/__version__.py```\n2. run from a terminal from the photo4D folder, given your $HOME/.pyc is correctly set:\n\n```shell\npython setup.py upload\n```\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ArcticSnow/photo4D", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "photo4d", "package_url": "https://pypi.org/project/photo4d/", "platform": "", "project_url": "https://pypi.org/project/photo4d/", "project_urls": { "Homepage": "https://github.com/ArcticSnow/photo4D" }, "release_url": "https://pypi.org/project/photo4d/0.2.2/", "requires_dist": [ "lxml", "pandas", "numpy", "matplotlib", "opencv-python", "pillow", "glob", "pdal ; extra == 'required_to_use_the_class_pcl_process_'", "json ; extra == 'required_to_use_the_class_pcl_process_'" ], "requires_python": ">=3.6.0", "summary": "Open source project to perform time-lapse photogrammetry", "version": "0.2.2" }, "last_serial": 5400497, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "ebdc3af4273906c972006de40a28fdd2", "sha256": "44d42236bbc2eba2c66c6de1c858ac6b3683c28170fc8876f1e091566c5913c6" }, "downloads": -1, "filename": "photo4d-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ebdc3af4273906c972006de40a28fdd2", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 30544, "upload_time": "2018-11-28T14:19:05", "url": "https://files.pythonhosted.org/packages/5f/87/97e237c8ddda7dc0df54c7c74b9f5052e892a8a842e61253cabdd9d20b2a/photo4d-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "38c75e339810f524d30b140977dddd52", "sha256": "f9fd50d0f4e1376e6b93e8b293b6e6bf4642b25166f730e00befb5e065e16403" }, "downloads": -1, "filename": "photo4d-0.1.1.tar.gz", "has_sig": false, "md5_digest": "38c75e339810f524d30b140977dddd52", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 31581, "upload_time": "2018-11-28T14:19:07", "url": "https://files.pythonhosted.org/packages/ba/83/96f7247a8a4f8acd2d333e947c11e72aa13a955ae9117136d0296c7e6a54/photo4d-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "f6c7ef6c7a9dd9521fc1a4306b126e06", "sha256": "585b14cb4b9c60e191cd59d6f5f40896baaa6222f62571bd50022848aea42ee1" }, "downloads": -1, "filename": "photo4d-0.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f6c7ef6c7a9dd9521fc1a4306b126e06", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 25633, "upload_time": "2019-06-13T14:16:40", "url": "https://files.pythonhosted.org/packages/60/67/c55453e24949b0b35bebd5b8c40df8cb8d1a96410f021750e98299abeb5f/photo4d-0.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4b4d1c049a2b3a9db93a782bc485b1b3", "sha256": "84a112a493b3dc430351cd0daa87e2ba6f15a7690fc28886890e48ac9a35d8e6" }, "downloads": -1, "filename": "photo4d-0.2.0.tar.gz", "has_sig": false, "md5_digest": "4b4d1c049a2b3a9db93a782bc485b1b3", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 25505, "upload_time": "2019-06-13T14:16:41", "url": "https://files.pythonhosted.org/packages/ec/7b/f34bc83e1ad0d6b371e474112eb8ff39080730eb092b9b7a17fa71bd15a0/photo4d-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "d219116fb9ff81f05b39ff99e7285997", "sha256": "a038c485fea2e3f296c27057796e0b0689491efe1486ba8e91528eca224f110b" }, "downloads": -1, "filename": "photo4d-0.2.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d219116fb9ff81f05b39ff99e7285997", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 30663, "upload_time": "2019-06-14T13:02:20", "url": "https://files.pythonhosted.org/packages/d8/43/d95d7388394793a4afb72fefe24b4b9fb64041d970e1e41e01ab15296248/photo4d-0.2.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8c7896e399dc93a69a58cb28b8d6c20f", "sha256": "43fbb95e3f0807457c1bc6afc959e64a76a36347cb75ab9fb3b7022cf288ba2d" }, "downloads": -1, "filename": "photo4d-0.2.1.tar.gz", "has_sig": false, "md5_digest": "8c7896e399dc93a69a58cb28b8d6c20f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 30797, "upload_time": "2019-06-14T13:02:22", "url": "https://files.pythonhosted.org/packages/ba/84/5fb2b1dd84f54ace4f97f3d9bea7bb8f524ae2f928a11cf3f7540842b694/photo4d-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "a2f0d8325aa4ceb5288273fa675ad79c", "sha256": "1683f58497450d860bd1289676dabe62680a0b8a292c454202ca8be6ba780206" }, "downloads": -1, "filename": "photo4d-0.2.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "a2f0d8325aa4ceb5288273fa675ad79c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 30489, "upload_time": "2019-06-14T13:07:08", "url": "https://files.pythonhosted.org/packages/df/0e/b95ddf2bbc1774adddc94348e404849f8b411f9ccab89e0851dc90bd2d6b/photo4d-0.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9eaedf8ed9470a2465b7c7787b57a53a", "sha256": "2c037166c27c04b575b86c9f7a3ab7c10227f0cf8118f517016e8de22273a1f0" }, "downloads": -1, "filename": "photo4d-0.2.2.tar.gz", "has_sig": false, "md5_digest": "9eaedf8ed9470a2465b7c7787b57a53a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 30588, "upload_time": "2019-06-14T13:07:09", "url": "https://files.pythonhosted.org/packages/0d/b1/f95075d7dfd46f27b2e9f2bf13f7a38b5c4457143cc5cded88d8d0e0e0b9/photo4d-0.2.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a2f0d8325aa4ceb5288273fa675ad79c", "sha256": "1683f58497450d860bd1289676dabe62680a0b8a292c454202ca8be6ba780206" }, "downloads": -1, "filename": "photo4d-0.2.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "a2f0d8325aa4ceb5288273fa675ad79c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 30489, "upload_time": "2019-06-14T13:07:08", "url": "https://files.pythonhosted.org/packages/df/0e/b95ddf2bbc1774adddc94348e404849f8b411f9ccab89e0851dc90bd2d6b/photo4d-0.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9eaedf8ed9470a2465b7c7787b57a53a", "sha256": "2c037166c27c04b575b86c9f7a3ab7c10227f0cf8118f517016e8de22273a1f0" }, "downloads": -1, "filename": "photo4d-0.2.2.tar.gz", "has_sig": false, "md5_digest": "9eaedf8ed9470a2465b7c7787b57a53a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 30588, "upload_time": "2019-06-14T13:07:09", "url": "https://files.pythonhosted.org/packages/0d/b1/f95075d7dfd46f27b2e9f2bf13f7a38b5c4457143cc5cded88d8d0e0e0b9/photo4d-0.2.2.tar.gz" } ] }