diff --git a/AutoTransformPy/mirror.py b/AutoTransformPy/mirror.py index 0692cdf..ae4bd2c 100644 --- a/AutoTransformPy/mirror.py +++ b/AutoTransformPy/mirror.py @@ -47,7 +47,7 @@ def mirror (image_path, direction = 'all'): # import image as array img = imread(image_path) - mirrored_images = [] + mirrored_images = [img] # flip horizontally if direction == 'horizontal' or direction == 'all': diff --git a/README.md b/README.md index 5335677..788830a 100644 --- a/README.md +++ b/README.md @@ -11,34 +11,103 @@ ### 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 translations to it, as specified by the user, and return an array of translated pixel values. Translations include: rotating, mirroring, and translating (shifting the object's location in the frame). +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 -##### Rotate -- Parameters: - - Image to transform (string: PATH) - - Number of images to generate (integer) - - Maximum rotation in degrees (integer) -- Returns: - - Array of randomly rotated (within max range) images of length based on number of images parameter - -##### Mirror -- Parameters: - - Image to transform (string: PATH) - - Direction of mirroring (string: 'horizontal', 'vertical', 'both') -- Returns: - - Array of mirrored image(s) - -##### Translate -- Parameters: - - Image to transform (string: PATH) - - Number of images to generate (integer) - - Maximum distance in pixels (integer) -- Returns: - - Array of randomly translated (within max range) images of length based on number of images parameter - - -### Similar Packages - -Scikit-image is a image processing package that contains functions for performing various operations to images, such as rotating or resizing, among many others. R has a new package, OpenImageR, that is similar to scikit-image that has functions for image preprocessing, filtering, and image recognition. Our plan is to utilize some of these packages functionality and build them out so a user could pass in example images, from a training dataset for example, and get back different variations of them. We believe this could signficantly help in the training of image classification algorthims. +#### Rotate + +Rotates an image the user-specified number of times. The degree of rotation is chosen randomly and may be in either the clockwise or counter-clockwise direction. The user specifies the maximum rotation angle. It returns the pixel values of the rotated images. + +#### Mirror + +Mirrors an image in the horizontal and/or vertical direction and returns the pixel values of the mirrored image(s). + +#### Translate + +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 + +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 + +To install AuttoTransformPy: + +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: + +### Usage + +#### Rotate + +`from AutoTransformPy.rotate import rotate` + +`rotate(image_path, num_images, max_rotation)` + +**Arguments:** + +- `image_path`: file path of the imput 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 + +**Output:** + +- An np.array of pixel values of the rotated images. Array contains `num_images` + 1 images (original plus all rotated images) + +**Example:** + +- `rotate("../tests/imgs/milad.jpg", 10, 280)` + + +#### Mirror + +`from AutoTransformPy.mirror import mirror` + +`mirror(image_path, direction)` + +**Arguments:** + +- `image_path`: file path of the imput image (string) +- `direction`: direction of mirroring (string, optional) 'horizontal', 'vertical', or 'all'. If not specified, defaults to 'all' + +**Output:** + +- An np.array of pixel values of the mirrored images. Array contains 3 images if `direction = 'all'` (original, horizontally mirrored, vertically mirrored) or 2 images if direction is horizontal or vertical (original image, mirrored image) + +**Example:** + +- `mirror("../tests/imgs/milad.jpg", "horizontal")` + + +#### Translate + +`from AutoTransformPy.translate import translate` + +`translate(image_path, num_images, max_translation)` + +**Arguments:** + +- `image_path`: file path of the input image (string) +- `num_images`: number of randomly translated images to be returned (integer) +- `max_translation`: maximum distance in pixels that the image can be translated (integer) + +**Output** + +- An np.array of pixel values of the translated images. Array contains `num_images` + 1 images (original plus all translated images) + +**Example:** + +- `translate("../tests/imgs/milad.jpg", 5, 80)` + + +### Package Dependencies + +- `numpy` +- `skimage` +- `os` diff --git a/tests/test_mirror.py b/tests/test_mirror.py index 30a461c..5b32dd1 100644 --- a/tests/test_mirror.py +++ b/tests/test_mirror.py @@ -34,13 +34,13 @@ def test_return_imgs(): # Tests that the number of images returned from translat returned_arr_2a = mir.mirror("../tests/imgs/milad.jpg", "all") # should return 2 images returned_arr_2b = mir.mirror("../tests/imgs/milad.jpg") # all is default, should return 2 images - assert returned_arr_1a.shape[0] == 1 # check one image in array - assert returned_arr_1b.shape[0] == 1 # check one image in array - assert returned_arr_2a.shape[0] == 2 # check two images in array - assert returned_arr_2b.shape[0] == 2 # check two images in array + assert returned_arr_1a.shape[0] == 2 # check two image in array (original and mirrored) + assert returned_arr_1b.shape[0] == 2 # check two image in array (original and mirrored) + assert returned_arr_2a.shape[0] == 3 # check three images in array (original and mirrored both directions) + assert returned_arr_2b.shape[0] == 3 # check three images in array (original and mirrored both directions) assert returned_arr_1a.shape[1:] == test_img.shape # check that returned image shapes same as input image shape - assert np.all(returned_arr_1a[0,:,1] == test_img[:,(test_img.shape[1]-2)]) # check that image is correctly mirrored horizontally - assert np.all(returned_arr_1b[0,1,:] == test_img[(test_img.shape[0] - 2),:]) # check that image is correctly mirrored vertically - assert np.all(returned_arr_2b[0,:,1] == test_img[:,(test_img.shape[1] - 2)]) # check horizontal image mirroring on 'all' - assert np.all(returned_arr_2b[1,1,:] == test_img[(test_img.shape[0] - 2),:]) # check vertical image mirroring on 'all' + assert np.all(returned_arr_1a[1,:,1] == test_img[:,(test_img.shape[1]-2)]) # check that image is correctly mirrored horizontally + assert np.all(returned_arr_1b[1,1,:] == test_img[(test_img.shape[0] - 2),:]) # check that image is correctly mirrored vertically + assert np.all(returned_arr_2b[1,:,1] == test_img[:,(test_img.shape[1] - 2)]) # check horizontal image mirroring on 'all' + assert np.all(returned_arr_2b[2,1,:] == test_img[(test_img.shape[0] - 2),:]) # check vertical image mirroring on 'all'