Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
993d0a0
Update function documentation, minor change to README
everittB Feb 17, 2019
655e6b7
Update installation directions
alyciakb Feb 17, 2019
69128c3
Fix typo
alyciakb Feb 17, 2019
ff00e06
Merge pull request #21 from RayceRossum/master
RayceRossum Feb 17, 2019
ea9cfe9
Merge pull request #23 from RayceRossum/master
RayceRossum Feb 17, 2019
6619563
Merge pull request #24 from RayceRossum/master
RayceRossum Feb 17, 2019
fad7156
Update rotate function to ensure consistency with other functions
everittB Feb 17, 2019
a6e4863
Merge branch 'update-rotate-scripts' of https://github.com/UBC-MDS/Au…
everittB Feb 17, 2019
4a05383
Merge pull request #19 from UBC-MDS/update-rotate-scripts
alyciakb Feb 17, 2019
7788c2c
Merge pull request #25 from RayceRossum/master
RayceRossum Feb 17, 2019
bb992af
Merge pull request #22 from UBC-MDS/raycer
alyciakb Feb 17, 2019
65659bc
Add lower() to mirror, small edits to README
Feb 17, 2019
4f0de21
Merge pull request #26 from UBC-MDS/alycia
everittB Feb 17, 2019
de99583
Adding validation for file path in function and test for this validation
everittB Mar 2, 2019
c091ac3
Add full usage example to readme
Mar 2, 2019
30859a1
Address issue with displaying the original image
everittB Mar 2, 2019
29b96e8
Revert "Address issue with displaying the original image"
everittB Mar 3, 2019
1e471e7
Merge pull request #29 from UBC-MDS/update-rotate-scripts
alyciakb Mar 3, 2019
3206d6b
Add usage and test output
Mar 3, 2019
431a0c5
Merge pull request #31 from UBC-MDS/alycia
everittB Mar 3, 2019
b2a28ca
First attempt at travis integration
everittB Mar 5, 2019
764a483
Second attempt at travis
everittB Mar 5, 2019
ea19372
Third attempt at travis
everittB Mar 5, 2019
4e4df8e
Updating test scripts to correct error with travis
everittB Mar 5, 2019
1a900ca
Trying to get travis build working still
everittB Mar 5, 2019
d0c1e1a
Trying to get travis build working still, again
everittB Mar 5, 2019
38dd05d
More travis issues
everittB Mar 6, 2019
f54481b
More travis issues again
everittB Mar 6, 2019
200e30f
Forgot to correct translate file
everittB Mar 6, 2019
e44ab1a
Trying to fix travis path issues
everittB Mar 6, 2019
d6fcb5a
Merge branch 'master' into master
RayceRossum Mar 6, 2019
f9d94e5
Add python coverage
Mar 6, 2019
1f28c5c
Add title to coverage
Mar 6, 2019
9f25ae7
Add better titles
Mar 6, 2019
1be9b3c
Remove local file paths
RayceRossum Mar 6, 2019
99561c1
More travis file path issues
everittB Mar 6, 2019
589c7ae
Merge pull request #34 from UBC-MDS/raycer
alyciakb Mar 6, 2019
df754e4
Another attempt at travis path issues
everittB Mar 6, 2019
6536cc7
File path issues still
everittB Mar 6, 2019
575d906
More travis testing
everittB Mar 6, 2019
8e603eb
Path issues continued
everittB Mar 6, 2019
bcd3630
File path issues still
everittB Mar 6, 2019
2ba6eb8
File paths never going to work
everittB Mar 6, 2019
67fcc87
One final try of file path issue
everittB Mar 6, 2019
fe402f3
Trying Alycia recommend fix
everittB Mar 6, 2019
2cb8ffb
Removing pycache files
everittB Mar 6, 2019
9f20658
Fix merge conflicts
everittB Mar 6, 2019
90d0bf6
Setup Travis and integrate Travis badge on README
everittB Mar 6, 2019
c79d602
Merge pull request #35 from UBC-MDS/update-rotate-scripts
alyciakb Mar 6, 2019
1e8bba9
Add code coverage
Mar 6, 2019
97bda1e
Fix typo in travis
Mar 6, 2019
ce3dc94
Fix error in codecov section of travis
Mar 6, 2019
f7e415c
More codecov error fixing
Mar 6, 2019
9ad5ede
Add logo and codecov badge
Mar 6, 2019
247e78d
grammar fixes
Mar 6, 2019
64c8c0e
Add logo image file
Mar 6, 2019
f17b27b
Fix logo link
alyciakb Mar 6, 2019
8b84837
Small edits to full usage example
alyciakb Mar 6, 2019
195ea1a
Merge pull request #36 from UBC-MDS/alycia
everittB Mar 6, 2019
f205daa
Delete .coverage
RayceRossum Mar 6, 2019
2c11c24
Add basic exception handling to python project
Mar 7, 2019
cc8ee7d
Merge branch 'master' of https://github.com/UBC-MDS/AutoTransformPy i…
Mar 7, 2019
ec78867
merge upstream
Mar 7, 2019
0048cab
Add filenotfound test to translate
Mar 7, 2019
a571410
Merge pull request #37 from UBC-MDS/raycer
everittB Mar 8, 2019
24f5fda
Fix a section title
alyciakb Mar 9, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .coverage

This file was deleted.

22 changes: 22 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
language: python
python:
- "3.6"

# command to install dependencies
install:
- pip install -r requirements.txt
- pip install codecov
- pip install pytest-cov

# command to run tests & document coverage
addons:
apt:
packages:
- python-coverage
script:
- pytest
- pytest --cov=AutoTransformPy tests/

# code coverage badge
after_success:
- codecov
1 change: 1 addition & 0 deletions AutoTransformPy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name = "AutoTransformPy"
31 changes: 19 additions & 12 deletions AutoTransformPy/mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,38 @@ def mirror (image_path, direction = 'all'):
mirrored_images: np.array
"""

# check for valid input parameters
try:
# check for valid input parameters
if not isinstance(image_path, str):
raise TypeError("The file path must be a string.")

if not isinstance(image_path, str):
raise TypeError("The file path must be a string.")
if not isinstance(direction, str):
raise TypeError("The direction must be a string: 'horizontal', 'vertical', or 'all'")

if not isinstance(direction, str):
raise TypeError("The direction must be a string: 'horizontal', 'vertical', or 'all'")
if not direction.lower() in ["horizontal","vertical", "all"]:
raise ValueError("The direction must be 'horizontal', 'vertical' or 'all'")

if not direction in ["horizontal","vertical", "all"]:
raise ValueError("The direction must be 'horizontal', 'vertical' or 'all'")
img = imread(image_path)

if not os.path.isfile(image_path):
raise FileNotFoundError("No image found at path")
except TypeError as e:
print("Invalid parameter types. Correct parameter types: image_path: str, num_images: int, direction: string")
raise e
except ValueError as e:
print("Invalid direction value. The direction must be a string: 'horizontal', 'vertical', or 'all'")
raise e
except FileNotFoundError as e:
raise e

# import image as array
img = imread(image_path)
mirrored_images = [img]

# flip horizontally
if direction == 'horizontal' or direction == 'all':
if direction.lower() == 'horizontal' or direction.lower() == 'all':
horiz_image = np.fliplr(img)
mirrored_images.append(horiz_image)

# flip vertically
if direction == 'vertical' or direction == 'all':
if direction.lower() == 'vertical' or direction.lower() == 'all':
vert_image = img[::-1]
mirrored_images.append(vert_image)

Expand Down
46 changes: 32 additions & 14 deletions AutoTransformPy/rotate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Copyright 2019 Brenden Everitt
# Licensed under the MIT License
# Use of this file must be in compliance with the License, LICENSE.md
#
# February 2019
# This script is for AutoTransformPy function Rotate.

from skimage.io import imread
from skimage.transform import rotate as rot
import numpy as np
import os

def rotate (image_path, num_images, max_rotation):
"""Returns an array of images of length num_images randomly rotated a random degree up to max_rotation
Expand All @@ -24,27 +32,37 @@ def rotate (image_path, num_images, max_rotation):
rotated_images: np.array
"""

# Check for valid input paramters types
if not isinstance(image_path, str):
raise TypeError("The file path must be a string.")
try:
# Check for valid input paramters types
if not isinstance(image_path, str):
raise TypeError("The file path must be a string.")

if not isinstance(num_images, int):
raise TypeError("The number of images returned must be an integer.")

if not isinstance(num_images, int):
raise TypeError("The number of images returned must be an integer.")
if not isinstance(max_rotation, int):
raise TypeError("The maximum rotation of images must be an integer.")

if not isinstance(max_rotation, int):
raise TypeError("The maximum rotation of images must be an integer.")
# Check for valid input paramter values
if num_images < 1:
raise ValueError("The number of images returned must be 1 or greater.")

# Check for valid input paramter values
if num_images < 1:
raise ValueError("The number of images returned must be 1 or greater.")
if max_rotation < 1 or max_rotation > 360:
raise ValueError("The maximum rotation must be between 1 and 360.")

if max_rotation < 1 or max_rotation > 360:
raise ValueError("The maximum rotation must be between 1 and 360.")
org_image = imread(image_path)
except TypeError as e:
print("Invalid parameter types. Correct parameter types: image_path: str, num_images: int, max_rotation: int")
raise e
except ValueError as e:
print("Invalid max_rotation value. max_rotation must be greater than 1 and less than 360.")
raise e
except FileNotFoundError as e:
raise e

# Perform image rotation
rotations = np.random.randint(-max_rotation, max_rotation, num_images)
org_image = imread(image_path)
rotated_images = []
rotated_images = [org_image]

for a_rotation in rotations:
rotated_images.append(rot(org_image, a_rotation, resize=False))
Expand Down
34 changes: 22 additions & 12 deletions AutoTransformPy/translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,33 @@ def translate (image_path, num_images, max_translation):
"""

# Check for valid input paramters types
if not isinstance(image_path, str):
raise TypeError("The file path must be a string.")
try:
if not isinstance(image_path, str):
raise TypeError("The file path must be a string.")

if not isinstance(num_images, int):
raise TypeError("The number of images returned must be an integer.")
if not isinstance(num_images, int):
raise TypeError("The number of images returned must be an integer.")

if not isinstance(max_translation, int):
raise TypeError("The maximum translation of images must be an integer.")
if not isinstance(max_translation, int):
raise TypeError("The maximum translation of images must be an integer.")

# Check for valid input paramter values
if num_images < 1:
raise ValueError("The number of images returned must be 1 or greater.")
# Check for valid input paramter values
if num_images < 1:
raise ValueError("The number of images returned must be 1 or greater.")

org_image = imread(image_path)
org_image = imread(image_path)

if max_translation >= org_image.shape[0] or max_translation >= org_image.shape[1]:
raise ValueError("The maximum translation must be less than the width and height of the image.")
if max_translation >= org_image.shape[0] or max_translation >= org_image.shape[1]:
raise ValueError("The maximum translation must be less than the width and height of the image.")

except TypeError as e:
print("Invalid parameter types. Correct parameter types: image_path: str, num_images: int, max_translation: int")
raise e
except ValueError as e:
print("Invalid max_translation value. max_translation must be greater than 1 and less than the width and height of the image.")
raise e
except FileNotFoundError as e:
raise e

# Perform image translation
translations = (np.random.randint(-max_translation, max_translation, num_images), np.random.randint(-max_translation, max_translation, num_images))
Expand Down
95 changes: 65 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
# AutoTransform
# AutoTransformPy <img src="docs/logopy.png" width="160" align="right"/>

### Contributors
[![Build Status](https://travis-ci.org/UBC-MDS/AutoTransformPy.svg?branch=master)](https://travis-ci.org/UBC-MDS/AutoTransformPy)
[![codecov](https://codecov.io/gh/UBC-MDS/AutoTransformPy/branch/master/graph/badge.svg)](https://codecov.io/gh/UBC-MDS/AutoTransformPy)


## Contributors

| Name | GitHub |
|---|---|
| Alycia Butterworth | [alyciakb](https://github.com/alyciakb) |
| Brenden Everitt | [everittB](https://github.com/everittB) |
| Rayce Rossum | [RayceRossum](https://github.com/RayceRossum) |

To contribute to this project, you must adhere to the terms outlined in our [Code of Conduct.](https://github.com/UBC-MDS/AutoTransformPy/blob/master/CONDUCT.md)

### Overview
## Overview

A common application of supervised machine learning is identifying the object of an image. One issue that users encounter is a model misclassifying a new image because the object is rotated or translated in some way that was not captured in the training images. The purpose of this package is to create a more robust set of images for users to train their model with. The package will accept an image as an input, apply a series of transformations to it, and return an array of transformed pixel values. Transformations include: rotating, mirroring, and translating (shifting the object's location in the frame).

### Functions
## Installation

In your console, type:

`pip install git+https://github.com/UBC-MDS/AutoTransformPy.git`

## Functions

#### Rotate

Expand All @@ -28,31 +39,24 @@ Mirrors an image in the horizontal and/or vertical direction and returns the pix
Translate will move an image within its frame, so that the topic of the image will be shifted to a new location in the frame. The distance and direction of translation will be chosen randomly, but the user specifies the maximum distance of the translation and the number of images they want generated. It returns the pixel values of the translated images.


### Python Environment
## Python Environment

Scikit-image is a image processing package that contains functions for performing various operations to images, such as rotating or resizing, among many others. AutoTransformPy utilizes some of this packages functionality and builds it out, so the user can easily gain many variations of an image. The intended usage of this package is for the development of a larger set of training images for the training of an image classification algorithms.


### Installation
## Usage

To install AuttoTransformPy:
### Rotate

1. Clone AutoTransformPy to your local machine: `git clone https://github.com/UBC-MDS/AutoTransformPy.git`
2. Navigate to the repository in your terminal.
3. Install input: `python setup.py install`
4. You can now use AutoTransformPy. Seee usage instructions below:
```
from AutoTransformPy.rotate import rotate

### Usage

#### Rotate

`from AutoTransformPy.rotate import rotate`

`rotate(image_path, num_images, max_rotation)`
rotate(image_path, num_images, max_rotation)
```

**Arguments:**

- `image_path`: file path of the imput image (string)
- `image_path`: file path of the input image (string)
- `num_images`: number of randomly rotated images to be returned (integer)
- `max_rotation`: maximum allowable degrees of rotation of the images (integer) between 1 and 360

Expand All @@ -65,15 +69,17 @@ To install AuttoTransformPy:
- `rotate("../tests/imgs/milad.jpg", 10, 280)`


#### Mirror
### Mirror

`from AutoTransformPy.mirror import mirror`
```
from AutoTransformPy.mirror import mirror

`mirror(image_path, direction)`
mirror(image_path, direction)
```

**Arguments:**

- `image_path`: file path of the imput image (string)
- `image_path`: file path of the input image (string)
- `direction`: direction of mirroring (string, optional) 'horizontal', 'vertical', or 'all'. If not specified, defaults to 'all'

**Output:**
Expand All @@ -85,11 +91,13 @@ To install AuttoTransformPy:
- `mirror("../tests/imgs/milad.jpg", "horizontal")`


#### Translate
### Translate

`from AutoTransformPy.translate import translate`
```
from AutoTransformPy.translate import translate

`translate(image_path, num_images, max_translation)`
translate(image_path, num_images, max_translation)
```

**Arguments:**

Expand All @@ -106,14 +114,41 @@ To install AuttoTransformPy:
- `translate("../tests/imgs/milad.jpg", 5, 80)`


### Package Dependencies
## Package Dependencies

- `numpy`
- `skimage`
- `os`


| File | Description |
|---|---|
| [Lab x Solution](https://github.ubc.ca/MDS-2018-19/DSCI_) | My solution file to Lab x |
## Full Usage Example

```
# pip install git+https://github.com/UBC-MDS/AutoTransformPy.git

from AutoTransformPy.mirror import mirror
from AutoTransformPy.rotate import rotate
from AutoTransformPy.translate import translate

# perform transformations
m = mirror("../tests/imgs/milad.jpg", "horizontal")
r = rotate("../tests/imgs/milad.jpg", 10, 280)
t = translate("../tests/imgs/milad.jpg", 5, 80)

# view dimensions of returned arrays
# it will be a 4D array, with the 1st dimension representing how many photos are in the array
m.shape # mirror function
r.shape # rotate function
t.shape # translate function

# You can use skimage.io to view the transformed images:
from skimage.io import imshow

# display original image
imshow(m[0]) # using mirror function as example

# display one of the transformed images
imshow(m[1]) # mirror function
imshow(r[1]) # rotate function
imshow(t[1]) # translate function
```
Binary file added docs/logopy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
python_version>='3.6'
numpy>=1.14
scikit-image>=0.13
2 changes: 1 addition & 1 deletion tests/.coverage
Original file line number Diff line number Diff line change
@@ -1 +1 @@
!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/rayce/Assignments/Block 5/DSCI 524/AutoTransformPy-Master/AutoTransformPy/mirror.py":[8,9,10,12,35,38,39,36,41,42,44,45,48,49,52,53,54,57,62,64,58,59],"/home/rayce/Assignments/Block 5/DSCI 524/AutoTransformPy-Master/AutoTransformPy/__init__.py":[1],"/home/rayce/Assignments/Block 5/DSCI 524/AutoTransformPy-Master/AutoTransformPy/rotate.py":[1,2,3,5,28,29,31,32,34,35,38,41,42,39,45,46,47,49,50,52],"/home/rayce/Assignments/Block 5/DSCI 524/AutoTransformPy-Master/AutoTransformPy/translate.py":[1,2,3,5,27,28,30,31,33,34,37,40,42,43,38,46,47,49,50,51,53]}}
!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/rayce/Assignments/Block 5/DSCI 524/AutoTransformPy/AutoTransformPy/mirror.py":[8,9,10,12,33,35,38,39,46,47,48,36,41,42,49,50,51,44,52,53,56,59,60,61,64,69,71,65,66],"/home/rayce/Assignments/Block 5/DSCI 524/AutoTransformPy/AutoTransformPy/__init__.py":[1],"/home/rayce/Assignments/Block 5/DSCI 524/AutoTransformPy/AutoTransformPy/rotate.py":[8,9,10,11,13,35,37,38,54,55,56,40,41,43,44,47,50,51,57,58,59,48,53,60,61,64,65,67,68,70],"/home/rayce/Assignments/Block 5/DSCI 524/AutoTransformPy/AutoTransformPy/translate.py":[1,2,3,5,27,28,29,46,47,48,31,32,34,35,38,41,43,44,49,50,51,39,56,57,59,60,61,63]}}
Loading