# stitchNsplit
![GitHub](https://img.shields.io/github/license/cypherics/ShapeMerge)
![Python](https://img.shields.io/badge/python-v3.6+-blue.svg)
![Contributions welcome](https://img.shields.io/badge/contributions-welcome-orange.svg)
![Downloads](https://pepy.tech/badge/stitch-n-split)
A Python Library To Stitch And Split Images for any dimension, computing grid and windows over the specified dimension
## Installation
pip install stitch-n-split
- Installing rasterio dependency using conda
conda install -c conda-forge rasterio
- Installing rasterio dependency from [pip](https://rasterio.readthedocs.io/en/latest/installation.html)
## Split
Split Operation can be performed on two sets of Imagery, <b>Geo Referenced</b> and <b>Non Geo Referenced</b>
The Windows formed for the split operation are adjusted based on the split_size and img_size, whenever
<code>img_size%split_size != 0</code> is true, this suggests that there will be overlapping windows.
Overlapping windows are generated only when required.
<table>
<tr>
<td>Original Image</td>
<td>Images After Split</td>
</tr>
<tr>
<td><img src="https://user-images.githubusercontent.com/24665570/89780629-73256d80-db2f-11ea-9db5-ee50573d8c6d.png" width=600 height=200></td>
<td><img src="https://user-images.githubusercontent.com/24665570/89780554-483b1980-db2f-11ea-8830-d13c728eadcd.png" width=2000 height=200></td>
</tr>
</table>
- ##### Geo Referenced
GeoReferenced Imagery have reference coordinate information stored in them.
This is taken into account while splitting geo referenced imagery, assigning correct reference information to the cut images,
thus preserving the over all reference information
> Geo Reference imagery must be of [tiff](https://en.wikipedia.org/wiki/TIFF) format.
- ##### Non GeoReferenced
For Non GeoReferenced the split is straight forward, it gets cropped in to specified dimension
*_Split Entire Directory_:*
```python
from stitch_n_split.split.images import SplitGeo
split = SplitGeo(split_size=(124, 267), img_size=(512, 512))
split.perform_directory_split("dir_path")
```
Performing Split over individual images can be done by accessing split as an iterator.
*_Split Iterator using window_:*
```python
from stitch_n_split.split.images import SplitGeo
from stitch_n_split.utility import open_image
split = SplitGeo(split_size=(124, 267), img_size=(512, 512))
image = open_image("img_path", is_geo_reference=True)
for win_number, window in split:
split_image = split.window_split(image, window)
# perform operation ....
```
## Stitch
While Performing Stitch if there are any overlapping window, those windows are merged seamlessly, without
hampering the pixel information and image dimension
Every Split image can be associated to the original image by the *window number* or the *window* itself.
*_Using stitchNsplit together_:*
```python
from stitch_n_split.stitch.images import Stitch
from stitch_n_split.utility import save_image
from stitch_n_split.split.images import SplitNonGeo
from stitch_n_split.utility import open_image
import numpy as np
split = SplitNonGeo(split_size=(124, 267), img_size=(512, 512, 3))
image = open_image("img_path")
stitched_image = np.zeros((512, 512, 3))
for win_number, window in split:
split_image = split.window_split(image, win_number)
# perform operation ....
stitched_image = Stitch.stitch_image(split_image, stitched_image, window)
save_image("path_to_save", stitched_image)
```
## Mesh Computing
![stitchNsplit](https://user-images.githubusercontent.com/24665570/89779619-6e5fba00-db2d-11ea-8705-d8ba781f72ea.gif)
- #### OverLapping Grid
The grid creation process assumes the provided grid size might not be evenly distributed over the mesh size and
whenever such situation arises, the grid adjusts its position without compromising the grid size, thus generating
overlapping grid in the mesh
- #### NonOverlapping Grid
No matter what the provided grid size, the goal is to find a grid size which can be evenly distributed over the
provided mesh size, if the provided sizes presents the possibility of a overlap then the size of the
grid is adjusted, to provide non overlapping grid
<table>
<tr>
<td>Mesh with Overlapping Grid</td>
<td>Mesh with Non Overlapping Grid</td>
</tr>
<tr>
<td><img src="https://user-images.githubusercontent.com/24665570/89773311-49654a00-db21-11ea-9955-f1230d432989.png" width=812 height=350></td>
<td><img src="https://user-images.githubusercontent.com/24665570/89773649-f8a22100-db21-11ea-8bcc-deeb46939a51.png" width=812 height=350></td>
</tr>
</table>
_*mesh size = (10000, 10000)*, *grid size = (2587, 3000)* were used for above example_
The number of grid generated in both cases are the same, the only difference is, the image in the left doesn't compromises the grid size when it encounters
an overlap, where as the image on the right adjusts its grid size to <code>mesh size // (mesh size / grid size)</code>
to avoid any overlap
#### Mesh Computing From geo-referenced image
The One mandatory Parameter while computing Mesh is the geo referencing transformation matrix.
- When the size of the mesh and the grid are provided in regular dimension, then the position where the mesh is to be drawn is
extracted from the affine transform and conversion of the dimension to reference coordinate system is done with the help
of pixel resolution present in affine transform
mesh = mesh_from_geo_transform(
mesh_size=(w, h),
transform=transfromation_matrix,
grid_size=(w, h)
)
_This will generate a *Mesh* of dimension *(w, h)* which will have *Grid* of dimension *(w, h)*,
which will be bounded within the region *transform * (mesh_size)*_
- When the bounds of mesh are passed, The transformation matrix for the mesh have to be constructed explicitly, the width and
height are computed internally from the given transformation
transfromation_matrix = get_affine_transform(
mesh_bounds[0],
mesh_bounds[-1],
*get_pixel_resolution(image.transform)
)
mesh = mesh_from_geo_transform(
grid_size=(w, h),
transform=transfromation_matrix,
mesh_bounds=mesh_bounds,
)
## Output
Grid can can accessed by the extent() call which is a Generator for providing individual grid along with the information associated
with the grid
mesh_overlap = mesh_from_geo_transform(mesh_size=(10000, 10000, 3), transform=affine_transform,
grid_size=(2587, 3000, 3))
for grid in mesh.extent():
print(grid)
.....
If the coordinate system available is different than the ones listed [here](#Working-Coordinate-System), then the coordinate must be reprojected before
mesh computation
transform=geo_transform_to_26190(w, h, arbitrary_image_coordinate_system.bounds,
arbitrary_image_coordinate_system.crs),
If width and height of the bounds are not known, to calculate it, use
compute_dimension(arbitrary_image_coordinate_system.bounds, pixel_resolution)
## Working Coordinate System
1. EPSG:26910
2. EPSG:26986
Raw data
{
"_id": null,
"home_page": "",
"name": "stitch-n-split",
"maintainer": "",
"docs_url": null,
"requires_python": "~=3.3",
"maintainer_email": "",
"keywords": "GIS Rasterio Sticth Split Mesh Grid Geo Reference",
"author": "Fuzail Palnak",
"author_email": "fuzailpalnak@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/35/f3/bc447179c82767ec79d80bc99f41787ea222b21a88c77d78d4094fc2abb7/stitch_n_split-0.1.2.tar.gz",
"platform": null,
"description": "# stitchNsplit\n![GitHub](https://img.shields.io/github/license/cypherics/ShapeMerge)\n![Python](https://img.shields.io/badge/python-v3.6+-blue.svg)\n![Contributions welcome](https://img.shields.io/badge/contributions-welcome-orange.svg)\n![Downloads](https://pepy.tech/badge/stitch-n-split)\n\nA Python Library To Stitch And Split Images for any dimension, computing grid and windows over the specified dimension\n\n## Installation\n\n pip install stitch-n-split\n \n \n- Installing rasterio dependency using conda\n \n conda install -c conda-forge rasterio\n\n- Installing rasterio dependency from [pip](https://rasterio.readthedocs.io/en/latest/installation.html)\n \n \n## Split\n\nSplit Operation can be performed on two sets of Imagery, <b>Geo Referenced</b> and <b>Non Geo Referenced</b>\nThe Windows formed for the split operation are adjusted based on the split_size and img_size, whenever \n<code>img_size%split_size != 0</code> is true, this suggests that there will be overlapping windows. \nOverlapping windows are generated only when required. \n\n<table>\n <tr>\n <td>Original Image</td>\n <td>Images After Split</td>\n </tr>\n <tr>\n <td><img src=\"https://user-images.githubusercontent.com/24665570/89780629-73256d80-db2f-11ea-9db5-ee50573d8c6d.png\" width=600 height=200></td>\n <td><img src=\"https://user-images.githubusercontent.com/24665570/89780554-483b1980-db2f-11ea-8830-d13c728eadcd.png\" width=2000 height=200></td>\n </tr>\n </table>\n \n- ##### Geo Referenced\n GeoReferenced Imagery have reference coordinate information stored in them.\nThis is taken into account while splitting geo referenced imagery, assigning correct reference information to the cut images,\nthus preserving the over all reference information \n > Geo Reference imagery must be of [tiff](https://en.wikipedia.org/wiki/TIFF) format.\n\n- ##### Non GeoReferenced \n For Non GeoReferenced the split is straight forward, it gets cropped in to specified dimension\n\n*_Split Entire Directory_:*\n```python\nfrom stitch_n_split.split.images import SplitGeo\nsplit = SplitGeo(split_size=(124, 267), img_size=(512, 512))\nsplit.perform_directory_split(\"dir_path\")\n```\nPerforming Split over individual images can be done by accessing split as an iterator.\n\n*_Split Iterator using window_:*\n```python\nfrom stitch_n_split.split.images import SplitGeo\nfrom stitch_n_split.utility import open_image\n\nsplit = SplitGeo(split_size=(124, 267), img_size=(512, 512))\nimage = open_image(\"img_path\", is_geo_reference=True)\nfor win_number, window in split:\n split_image = split.window_split(image, window)\n # perform operation ....\n```\n\n## Stitch \n\nWhile Performing Stitch if there are any overlapping window, those windows are merged seamlessly, without\nhampering the pixel information and image dimension\n\nEvery Split image can be associated to the original image by the *window number* or the *window* itself.\n\n*_Using stitchNsplit together_:*\n```python\nfrom stitch_n_split.stitch.images import Stitch\nfrom stitch_n_split.utility import save_image\nfrom stitch_n_split.split.images import SplitNonGeo\nfrom stitch_n_split.utility import open_image\nimport numpy as np\n\nsplit = SplitNonGeo(split_size=(124, 267), img_size=(512, 512, 3))\nimage = open_image(\"img_path\")\nstitched_image = np.zeros((512, 512, 3))\n\nfor win_number, window in split:\n split_image = split.window_split(image, win_number)\n # perform operation ....\n stitched_image = Stitch.stitch_image(split_image, stitched_image, window)\nsave_image(\"path_to_save\", stitched_image)\n``` \n \n## Mesh Computing\n\n![stitchNsplit](https://user-images.githubusercontent.com/24665570/89779619-6e5fba00-db2d-11ea-8705-d8ba781f72ea.gif)\n\n- #### OverLapping Grid\n \n The grid creation process assumes the provided grid size might not be evenly distributed over the mesh size and\n whenever such situation arises, the grid adjusts its position without compromising the grid size, thus generating \n overlapping grid in the mesh\n \n- #### NonOverlapping Grid\n \n No matter what the provided grid size, the goal is to find a grid size which can be evenly distributed over the\n provided mesh size, if the provided sizes presents the possibility of a overlap then the size of the \n grid is adjusted, to provide non overlapping grid\n \n \n<table>\n <tr>\n <td>Mesh with Overlapping Grid</td>\n <td>Mesh with Non Overlapping Grid</td>\n </tr>\n <tr>\n <td><img src=\"https://user-images.githubusercontent.com/24665570/89773311-49654a00-db21-11ea-9955-f1230d432989.png\" width=812 height=350></td>\n <td><img src=\"https://user-images.githubusercontent.com/24665570/89773649-f8a22100-db21-11ea-8bcc-deeb46939a51.png\" width=812 height=350></td>\n </tr>\n </table>\n \n _*mesh size = (10000, 10000)*, *grid size = (2587, 3000)* were used for above example_\n\nThe number of grid generated in both cases are the same, the only difference is, the image in the left doesn't compromises the grid size when it encounters\nan overlap, where as the image on the right adjusts its grid size to <code>mesh size // (mesh size / grid size)</code> \nto avoid any overlap\n\n\n#### Mesh Computing From geo-referenced image\nThe One mandatory Parameter while computing Mesh is the geo referencing transformation matrix.\n\n- When the size of the mesh and the grid are provided in regular dimension, then the position where the mesh is to be drawn is\nextracted from the affine transform and conversion of the dimension to reference coordinate system is done with the help\nof pixel resolution present in affine transform\n\n mesh = mesh_from_geo_transform(\n mesh_size=(w, h),\n transform=transfromation_matrix, \n grid_size=(w, h)\n )\n\n _This will generate a *Mesh* of dimension *(w, h)* which will have *Grid* of dimension *(w, h)*, \nwhich will be bounded within the region *transform * (mesh_size)*_\n\n- When the bounds of mesh are passed, The transformation matrix for the mesh have to be constructed explicitly, the width and\nheight are computed internally from the given transformation\n\n transfromation_matrix = get_affine_transform(\n mesh_bounds[0],\n mesh_bounds[-1],\n *get_pixel_resolution(image.transform)\n ) \n \n mesh = mesh_from_geo_transform(\n grid_size=(w, h),\n transform=transfromation_matrix,\n mesh_bounds=mesh_bounds,\n )\n\n## Output\n\nGrid can can accessed by the extent() call which is a Generator for providing individual grid along with the information associated \nwith the grid\n\n mesh_overlap = mesh_from_geo_transform(mesh_size=(10000, 10000, 3), transform=affine_transform,\n grid_size=(2587, 3000, 3))\n \n for grid in mesh.extent():\n print(grid)\n .....\n\nIf the coordinate system available is different than the ones listed [here](#Working-Coordinate-System), then the coordinate must be reprojected before \nmesh computation\n \n transform=geo_transform_to_26190(w, h, arbitrary_image_coordinate_system.bounds,\n arbitrary_image_coordinate_system.crs),\n\nIf width and height of the bounds are not known, to calculate it, use\n\n compute_dimension(arbitrary_image_coordinate_system.bounds, pixel_resolution)\n\n \n## Working Coordinate System\n1. EPSG:26910\n2. EPSG:26986 \n\n",
"bugtrack_url": null,
"license": "",
"summary": "Library for stitching and spliting",
"version": "0.1.2",
"project_urls": null,
"split_keywords": [
"gis",
"rasterio",
"sticth",
"split",
"mesh",
"grid",
"geo",
"reference"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "516d8fa4182c8b1a91fe19ca0f06fea2341356853a0371b22701282e9ab87fad",
"md5": "25209a60ba07809b5fc29750b6dd1826",
"sha256": "3d5a8eff56d27eab214544c97b67481af6ea979029b4ebe72cdf0c1b962b1697"
},
"downloads": -1,
"filename": "stitch_n_split-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "25209a60ba07809b5fc29750b6dd1826",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "~=3.3",
"size": 12121,
"upload_time": "2023-05-31T10:36:48",
"upload_time_iso_8601": "2023-05-31T10:36:48.726712Z",
"url": "https://files.pythonhosted.org/packages/51/6d/8fa4182c8b1a91fe19ca0f06fea2341356853a0371b22701282e9ab87fad/stitch_n_split-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "35f3bc447179c82767ec79d80bc99f41787ea222b21a88c77d78d4094fc2abb7",
"md5": "dbfd7a3594fd4131c696acccdcc69a38",
"sha256": "7c8c897d582a96c93b05d5c899f2ef7acccc193cda08a9c6c97af5c36f3eb4d8"
},
"downloads": -1,
"filename": "stitch_n_split-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "dbfd7a3594fd4131c696acccdcc69a38",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "~=3.3",
"size": 12737,
"upload_time": "2023-05-31T10:36:50",
"upload_time_iso_8601": "2023-05-31T10:36:50.903465Z",
"url": "https://files.pythonhosted.org/packages/35/f3/bc447179c82767ec79d80bc99f41787ea222b21a88c77d78d4094fc2abb7/stitch_n_split-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-31 10:36:50",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "stitch-n-split"
}