{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## 1. Import Python libraries\n<p><img src=\"https://assets.datacamp.com/production/project_374/img/honey.jpg\" alt=\"honey bee\">\n<em>A honey bee.</em></p>\n<p>The question at hand is: can a machine identify a bee as a honey bee or a bumble bee? These bees have different <a href=\"http://bumblebeeconservation.org/about-bees/faqs/honeybees-vs-bumblebees/\">behaviors and appearances</a>, but given the variety of backgrounds, positions, and image resolutions it can be a challenge for machines to tell them apart.</p>\n<p>Being able to identify bee species from images is a task that ultimately would allow researchers to more quickly and effectively collect field data. Pollinating bees have critical roles in both ecology and agriculture, and diseases like <a href=\"http://news.harvard.edu/gazette/story/2015/07/pesticide-found-in-70-percent-of-massachusetts-honey-samples/\">colony collapse disorder</a> threaten these species. Identifying different species of bees in the wild means that we can better understand the prevalence and growth of these important insects.</p>\n<p><img src=\"https://assets.datacamp.com/production/project_374/img/bumble.jpg\" alt=\"bumble bee\">\n<em>A bumble bee.</em></p>\n<p>This notebook walks through loading and processing images. After loading and processing these images, they will be ready for building models that can automatically detect honeybees and bumblebees.</p>","metadata":{"deletable":false,"dc":{"key":"3"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"# Used to change filepaths\nfrom pathlib import Path\n\n# We set up matplotlib, pandas, and the display function\n%matplotlib inline\nimport matplotlib.pyplot as plt\nfrom IPython.display import display\nimport pandas as pd\n\nimport numpy as np\n\nfrom PIL import Image\ntest_data =np.random.beta(1,1,size=(100,100,3))\n\ntest_data\nplt.imshow(test_data)","metadata":{"dc":{"key":"3"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Opening images with PIL\n<p>Now that we have all of our imports ready, it is time to work with some real images.</p>\n<p>Pillow is a very flexible image loading and manipulation library. It works with many different image formats, for example, <code>.png</code>, <code>.jpg</code>, <code>.gif</code> and more. For most image data, one can work with images using the Pillow library (which is imported as <code>PIL</code>).</p>\n<p>Now we want to load an image, display it in the notebook, and print out the dimensions of the image. By dimensions, we mean the width of the image and the height of the image. These are measured in pixels. The documentation for <a href=\"https://pillow.readthedocs.io/en/5.1.x/reference/Image.html\">Image</a> in Pillow gives a comprehensive view of what this object can do.</p>","metadata":{"deletable":false,"dc":{"key":"10"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"# open the image\nimg = Image.open('datasets/bee_1.jpg')\n\n# Get the image size\nimg_size = img.size\n\nprint(\"The image size is: {}\".format(img_size))\n\n# Just having the image as the last line in the cell will display it in the notebook\nimg","metadata":{"dc":{"key":"10"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Image manipulation with PIL\n<p>Pillow has a number of common image manipulation tasks built into the library. For example, one may want to resize an image so that the file size is smaller. Or, perhaps, convert an image to black-and-white instead of color. Operations that Pillow provides include:</p>\n<ul>\n<li>resizing</li>\n<li>cropping</li>\n<li>rotating</li>\n<li>flipping</li>\n<li>converting to greyscale (or other <a href=\"https://pillow.readthedocs.io/en/5.1.x/handbook/concepts.html#concept-modes\">color modes</a>)</li>\n</ul>\n<p>Often, these kinds of manipulations are part of the pipeline for turning a small number of images into more images to create training data for machine learning algorithms. This technique is called <a href=\"http://cs231n.stanford.edu/reports/2017/pdfs/300.pdf\">data augmentation</a>, and it is a common technique for image classification.</p>\n<p>We'll try a couple of these operations and look at the results.</p>","metadata":{"deletable":false,"dc":{"key":"17"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"# Crop the image to 25, 25, 75, 75\nimg_cropped =img.crop((25,25,75,75))\ndisplay(img_cropped)\n\n# rotate the image by 45 degrees\nimg_rotated = img.rotate(45,expand=25)\ndisplay(img_rotated)\n\n# flip the image left to right\nimg_flipped =img.transpose(Image.FLIP_LEFT_RIGHT)\ndisplay(img_flipped)","metadata":{"dc":{"key":"17"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. Images as arrays of data\n<p>What is an image? So far, PIL has handled loading images and displaying them. However, if we're going to use images as data, we need to understand what that data looks like.</p>\n<p>Most image formats have three color <a href=\"https://en.wikipedia.org/wiki/RGB_color_model\">\"channels\": red, green, and blue</a> (some images also have a fourth channel called \"alpha\" that controls transparency). For each pixel in an image, there is a value for every channel.</p>\n<p><img src=\"https://assets.datacamp.com/production/project_374/img/AdditiveColor.png\" alt=\"RGB Colors\"></p>\n<p>The way this is represented as data is as a three-dimensional matrix. The width of the matrix is the width of the image, the height of the matrix is the height of the image, and the depth of the matrix is the number of channels. So, as we saw, the height and width of our image are both 100 pixels. This means that the underlying data is a matrix with the dimensions <code>100x100x3</code>.</p>","metadata":{"deletable":false,"dc":{"key":"24"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"# Turn our image object into a NumPy array\nimg_data = np.array(img)\n\n# get the shape of the resulting array\nimg_data_shape = img_data.shape\n\nprint(\"Our NumPy array has the shape: {}\".format(img_data_shape))\n\n# plot the data with `imshow` \nplt.imshow(img_data)\nplt.show()\n\n# plot the red channel\nplt.imshow(img_data[0], cmap=plt.cm.Reds_r)\nplt.show()\n\n# plot the green channel\nplt.imshow(img_data[1], cmap=plt.cm.Greens_r)\nplt.show()\n\n# plot the blue channel\nplt.imshow(img_data[2], cmap=plt.cm.Blues_r)\nplt.show()","metadata":{"dc":{"key":"24"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5. Explore the color channels\n<p>Color channels can help provide more information about an image. A picture of the ocean will be more blue, whereas a picture of a field will be more green. This kind of information can be useful when building models or examining the differences between images.</p>\n<p>We'll look at the <a href=\"https://en.wikipedia.org/wiki/Kernel_density_estimation\">kernel density estimate</a> for each of the color channels on the same plot so that we can understand how they differ.</p>\n<p>When we make this plot, we'll see that a shape that appears further to the right means more of that color, whereas further to the left means less of that color.</p>","metadata":{"deletable":false,"dc":{"key":"31"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"def plot_kde(channel, color):\n    \"\"\" Plots a kernel density estimate for the given data.\n        \n        `channel` must be a 2d array\n        `color` must be a color string, e.g. 'r', 'g', or 'b'\n    \"\"\"\n    data = channel.flatten()\n    return pd.Series(data).plot.density(c=color)\n\n# create the list of channels\nchannels = ['r','g','b']\n    \ndef plot_rgb(image_data):\n    # use enumerate to loop over colors and indexes\n    for ix, color in enumerate(channels):\n        plot_kde(img_data[:, :, ix],color)\n        \n\n    plt.show()\n    \nplot_rgb(img_data)\n","metadata":{"dc":{"key":"31"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 6. Honey bees and bumble bees (i)\n<p>Now we'll look at two different images and some of the differences between them. The first image is of a honey bee, and the second image is of a bumble bee.</p>\n<p>First, let's look at the honey bee.</p>","metadata":{"deletable":false,"dc":{"key":"38"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"# load bee_12.jpg as honey\nhoney=Image.open('datasets/bee_12.jpg')\n\n# display the honey bee image\ndisplay(honey)\n\n# NumPy array of the honey bee image data\nhoney_data=np.array(honey)\n# plot the rgb densities for the honey bee image\nplot_rgb(honey_data)","metadata":{"dc":{"key":"38"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 7. Honey bees and bumble bees (ii)\n<p>Now let's look at the bumble bee.</p>\n<p>When one compares these images, it is clear how different the colors are. The honey bee image above, with a blue flower, has a strong peak on the right-hand side of the blue channel. The bumble bee image, which has a lot of yellow for the bee and the background, has almost perfect overlap between the red and green channels (which together make yellow).</p>","metadata":{"deletable":false,"dc":{"key":"45"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"# load bee_3.jpg as bumble\nbumble=Image.open('datasets/bee_3.jpg')\n\n# display the bumble bee image\ndisplay(bumble)\n\n# NumPy array of the bumble bee image data\nbumble_data=np.array(bumble)\n\n# plot the rgb densities for the bumble bee image\nplot_rgb(bumble_data)","metadata":{"dc":{"key":"45"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8. Simplify, simplify, simplify\n<p>While sometimes color information is useful, other times it can be distracting. In this examples where we are looking at bees, the bees themselves are very similar colors. On the other hand, the bees are often on top of different color flowers. We know that the colors of the flowers may be distracting from separating honey bees from bumble bees, so let's convert these images to <a href=\"https://en.wikipedia.org/wiki/Grayscale\">black-and-white, or \"grayscale.\"</a></p>\n<p>Grayscale is just one of the <a href=\"https://pillow.readthedocs.io/en/5.0.0/handbook/concepts.html#modes\">modes that Pillow supports</a>. Switching between modes is done with the <code>.convert()</code> method, which is passed a string for the new mode.</p>\n<p>Because we change the number of color \"channels,\" the shape of our array changes with this change. It also will be interesting to look at how the KDE of the grayscale version compares to the RGB version above.</p>","metadata":{"deletable":false,"dc":{"key":"52"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"# convert honey to grayscale\nhoney_bw = honey.convert(\"L\")\ndisplay(honey_bw)\n\n# convert the image to a NumPy array\nhoney_bw_arr = np.array(honey_bw)\n\n# get the shape of the resulting array\nhoney_bw_arr_shape = honey_bw_arr.shape\nprint(\"Our NumPy array has the shape: {}\".format(honey_bw_arr_shape))\n\n# plot the array using matplotlib\nplt.imshow(honey_bw_arr, cmap=plt.cm.gray)\nplt.show()\n\n# plot the kde of the new black and white array\nplot_kde(honey_bw_arr, 'k')","metadata":{"dc":{"key":"52"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 9. Save your work!\n<p>We've been talking this whole time about making changes to images and the manipulations that might be useful as part of a machine learning pipeline. To use these images in the future, we'll have to save our work after we've made changes.</p>\n<p>Now, we'll make a couple changes to the <code>Image</code> object from Pillow and save that. We'll flip the image left-to-right, just as we did with the color version. Then, we'll change the NumPy version of the data by clipping it. Using the <code>np.maximum</code> function, we can take any number in the array smaller than <code>100</code> and replace it with <code>100</code>. Because this reduces the range of values, it will increase the <a href=\"https://en.wikipedia.org/wiki/Contrast_(vision)\">contrast of the image</a>. We'll then convert that back to an <code>Image</code> and save the result.</p>","metadata":{"deletable":false,"dc":{"key":"59"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"# flip the image left-right with transpose\nhoney_bw_flip=honey_bw.transpose(Image.FLIP_LEFT_RIGHT)\n\n# show the flipped image\ndisplay(honey_bw_flip)\n\n# save the flipped image\nhoney_bw_flip.save(\"saved_images/bw_flipped.jpg\")\n\n# create higher contrast by reducing range\nhoney_hc_arr=np.maximum(honey_bw_arr,100)\n\n# show the higher contrast version\nplt.imshow(honey_hc_arr, cmap=plt.cm.gray)\n\n# convert the NumPy array of high contrast to an Image\nhoney_bw_hc=Image.fromarray(honey_hc_arr)\n\n# save the high contrast version\nhoney_bw_hc.save(\"saved_images/bw_hc.jpg\")","metadata":{"dc":{"key":"59"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 10. Make a pipeline\n<p>Now it's time to create an image processing pipeline. We have all the tools in our toolbox to load images, transform them, and save the results.</p>\n<p>In this pipeline we will do the following:</p>\n<ul>\n<li>Load the image with <code>Image.open</code> and create paths to save our images to</li>\n<li>Convert the image to grayscale</li>\n<li>Save the grayscale image</li>\n<li>Rotate, crop, and zoom in on the image and save the new image</li>\n</ul>","metadata":{"deletable":false,"dc":{"key":"66"},"run_control":{"frozen":true},"tags":["context"]}},{"cell_type":"code","source":"image_paths = ['datasets/bee_1.jpg', 'datasets/bee_12.jpg', 'datasets/bee_2.jpg', 'datasets/bee_3.jpg']\n\ndef process_image(path):\n    img = Image.open(path)\n\n    # create paths to save files to\n    bw_path = \"saved_images/bw_{}.jpg\".format(path.stem)\n    rcz_path = \"saved_images/rcz_{}.jpg\".format(path.stem)\n\n    print(\"Creating grayscale version of {} and saving to {}.\".format(path, bw_path))\n    bw =img.convert(\"L\")\n    bw.save(bw_path)\n\n    print(\"Creating rotated, cropped, and zoomed version of {} and saving to {}.\".format(path, rcz_path))\n    rcz = bw.rotate(45).crop([25, 25, 75, 75]).resize((100, 100))\n    rcz.save(rcz_path)\n\n# for loop over image paths\nfor img_path in image_paths:\n    process_image(Path(img_path))","metadata":{"dc":{"key":"66"},"tags":["sample_code"],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Hope you like this work It is one the datacamps project which I completed... ","metadata":{}}]}