{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# The Nature Conservancy\n", "## Detecting Coral Reefs and Scuba Diving Imagery\n", "\n", "### Background\n", "\n", "This proof of concept will be focused on detecting corals, scuba diving equipment, and other reef-related images located in user-defined geospatial locations. We will also explore a potential edge case with skydiving, as colors and gear visually is similar to scuba diving.\n", "\n", "#### First Image: Coral Reef \n", "\n", "Our first image is very obviously a photo of a coral reef with wildlife and fish; the keyword `reef` is included in the JSON response that we obtain from Cognitive Services. To extract similar images from your corpus of files, you would first filter by geospatial location and then search for `reef` in Cognitive Services JSON responses.\n", "\n", "![](https://timeincsecure-a.akamaihd.net/rtmp_uds/293884104/201703/2681/293884104_5360456295001_5360434467001-vs.jpg?pubId=293884104&videoId=5360434467001)\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Define the Subscription key for making API calls.\n", "secret = 'INSERT YOUR API KEY HERE'" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Import required libraries for request headers and json extraction.\n", "import http.client, urllib.request, urllib.parse, urllib.error, base64, json\n", "\n", "# Replace the subscription_key string value with your valid subscription key.\n", "subscription_key = secret\n", "\n", "# Replace to match your region.\n", "\n", "uri_base = 'westcentralus.api.cognitive.microsoft.com'\n", "\n", "headers = {\n", " # Request headers.\n", " 'Content-Type': 'application/json',\n", " 'Ocp-Apim-Subscription-Key': subscription_key,\n", "}\n", "\n", "params = urllib.parse.urlencode({\n", " # Request parameters. All of them are optional.\n", " 'visualFeatures': 'Description,Color,Tags',\n", " 'language': 'en',\n", "})" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Response:\n", "{\n", " \"color\": {\n", " \"accentColor\": \"048AC7\",\n", " \"dominantColorBackground\": \"Brown\",\n", " \"dominantColorForeground\": \"Brown\",\n", " \"dominantColors\": [],\n", " \"isBWImg\": false\n", " },\n", " \"description\": {\n", " \"captions\": [\n", " {\n", " \"confidence\": 0.266922154795059,\n", " \"text\": \"a group of colorful underwater\"\n", " }\n", " ],\n", " \"tags\": [\n", " \"nature\",\n", " \"covered\",\n", " \"colorful\",\n", " \"orange\",\n", " \"reef\",\n", " \"lot\",\n", " \"colored\",\n", " \"many\",\n", " \"sitting\",\n", " \"table\",\n", " \"surrounded\",\n", " \"painted\",\n", " \"colors\",\n", " \"fire\",\n", " \"old\",\n", " \"field\",\n", " \"water\",\n", " \"large\",\n", " \"group\",\n", " \"underwater\",\n", " \"blue\",\n", " \"display\",\n", " \"room\",\n", " \"hydrant\",\n", " \"umbrella\",\n", " \"people\",\n", " \"standing\",\n", " \"street\",\n", " \"white\"\n", " ]\n", " },\n", " \"metadata\": {\n", " \"format\": \"Jpeg\",\n", " \"height\": 720,\n", " \"width\": 1280\n", " },\n", " \"requestId\": \"452dd51a-49c7-448b-8c08-1705633a8514\",\n", " \"tags\": [\n", " {\n", " \"confidence\": 0.8286102414131165,\n", " \"name\": \"nature\"\n", " },\n", " {\n", " \"confidence\": 0.47426894307136536,\n", " \"name\": \"colorful\"\n", " },\n", " {\n", " \"confidence\": 0.4733331501483917,\n", " \"name\": \"orange\"\n", " },\n", " {\n", " \"confidence\": 0.39928770065307617,\n", " \"name\": \"reef\"\n", " },\n", " {\n", " \"confidence\": 0.28420546650886536,\n", " \"name\": \"colored\"\n", " },\n", " {\n", " \"confidence\": 0.1980312019586563,\n", " \"name\": \"surrounded\"\n", " },\n", " {\n", " \"confidence\": 0.17965476214885712,\n", " \"name\": \"painted\"\n", " }\n", " ]\n", "}\n" ] } ], "source": [ "body = \"{'url':'https://timeincsecure-a.akamaihd.net/rtmp_uds/293884104/201703/2681/293884104_5360456295001_5360434467001-vs.jpg?pubId=293884104&videoId=5360434467001'}\"\n", "\n", "try:\n", " # Execute the REST API call and get the response.\n", " conn = http.client.HTTPSConnection('westcentralus.api.cognitive.microsoft.com')\n", " conn.request(\"POST\", \"/vision/v1.0/analyze?%s\" % params, body, headers)\n", " response = conn.getresponse()\n", " data = response.read()\n", "\n", " # 'data' contains the JSON data. The following formats the JSON data for display.\n", " parsed = json.loads(data.decode())\n", " print (\"Response:\")\n", " print (json.dumps(parsed, sort_keys=True, indent=2))\n", " conn.close()\n", "\n", "except Exception as e:\n", " print('Error:')\n", " print(e)\n", "\n", "####################################" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Second Image: Scuba Diver\n", "\n", "The second image is not as straightforward to parse; however, you would be able to deduce that this is a scuba diving photo by searching through geospatially-filtered JSON responses for `water sport` and `underwater`, as well as potentially `man` or `woman` and `swimming`.\n", "\n", "![](https://www.deeperblue.com/wp-content/uploads/2016/03/AdobeStock_62701813.jpeg)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Response:\n", "{\n", " \"color\": {\n", " \"accentColor\": \"016BCA\",\n", " \"dominantColorBackground\": \"Blue\",\n", " \"dominantColorForeground\": \"Blue\",\n", " \"dominantColors\": [\n", " \"Blue\"\n", " ],\n", " \"isBWImg\": false\n", " },\n", " \"description\": {\n", " \"captions\": [\n", " {\n", " \"confidence\": 0.3619696364682312,\n", " \"text\": \"a statue of person in a swimming pool\"\n", " }\n", " ],\n", " \"tags\": [\n", " \"sport\",\n", " \"swimming\",\n", " \"statue\",\n", " \"water\",\n", " \"small\",\n", " \"sitting\",\n", " \"air\",\n", " \"top\",\n", " \"man\",\n", " \"holding\",\n", " \"flying\",\n", " \"yellow\",\n", " \"riding\",\n", " \"boat\",\n", " \"blue\"\n", " ]\n", " },\n", " \"metadata\": {\n", " \"format\": \"Jpeg\",\n", " \"height\": 3456,\n", " \"width\": 5184\n", " },\n", " \"requestId\": \"baf20f4c-7e65-4051-b72c-1db944696017\",\n", " \"tags\": [\n", " {\n", " \"confidence\": 0.9971852898597717,\n", " \"name\": \"sky\"\n", " },\n", " {\n", " \"confidence\": 0.9742870926856995,\n", " \"name\": \"sport\"\n", " },\n", " {\n", " \"confidence\": 0.9645830988883972,\n", " \"hint\": \"sport\",\n", " \"name\": \"swimming\"\n", " },\n", " {\n", " \"confidence\": 0.9560804963111877,\n", " \"hint\": \"sport\",\n", " \"name\": \"water sport\"\n", " },\n", " {\n", " \"confidence\": 0.45918408036231995,\n", " \"name\": \"statue\"\n", " },\n", " {\n", " \"confidence\": 0.013368669897317886,\n", " \"name\": \"ocean floor\"\n", " }\n", " ]\n", "}\n" ] } ], "source": [ "body = \"{'url':'https://www.deeperblue.com/wp-content/uploads/2016/03/AdobeStock_62701813.jpeg'}\"\n", "\n", "try:\n", " # Execute the REST API call and get the response.\n", " conn = http.client.HTTPSConnection('westcentralus.api.cognitive.microsoft.com')\n", " conn.request(\"POST\", \"/vision/v1.0/analyze?%s\" % params, body, headers)\n", " response = conn.getresponse()\n", " data = response.read()\n", "\n", " # 'data' contains the JSON data. The following formats the JSON data for display.\n", " parsed = json.loads(data.decode())\n", " print (\"Response:\")\n", " print (json.dumps(parsed, sort_keys=True, indent=2))\n", " conn.close()\n", "\n", "except Exception as e:\n", " print('Error:')\n", " print(e)\n", "\n", "####################################" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Image 3: Scuba Diving\n", "\n", "Similar to the image above; but `ocean floor`, `underwater`, and `swimming`.\n", "\n", "![](http://www2.padi.com/blog/wp-content/uploads/2016/10/scuba-diving-reef-e1476482719834.jpg)\n" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Response:\n", "{\n", " \"color\": {\n", " \"accentColor\": \"0143C6\",\n", " \"dominantColorBackground\": \"Blue\",\n", " \"dominantColorForeground\": \"Blue\",\n", " \"dominantColors\": [\n", " \"Blue\"\n", " ],\n", " \"isBWImg\": false\n", " },\n", " \"description\": {\n", " \"captions\": [\n", " {\n", " \"confidence\": 0.36038400178616214,\n", " \"text\": \"a group of people in a swimming pool\"\n", " }\n", " ],\n", " \"tags\": [\n", " \"swimming\",\n", " \"sitting\",\n", " \"table\",\n", " \"laptop\",\n", " \"man\",\n", " \"orange\",\n", " \"woman\",\n", " \"colorful\",\n", " \"group\",\n", " \"computer\",\n", " \"many\",\n", " \"people\",\n", " \"holding\",\n", " \"blue\",\n", " \"water\",\n", " \"large\",\n", " \"standing\",\n", " \"display\",\n", " \"underwater\"\n", " ]\n", " },\n", " \"metadata\": {\n", " \"format\": \"Jpeg\",\n", " \"height\": 465,\n", " \"width\": 995\n", " },\n", " \"requestId\": \"dfa2f409-a28b-4b9e-8bdd-8830300c23a8\",\n", " \"tags\": [\n", " {\n", " \"confidence\": 0.7886989116668701,\n", " \"name\": \"sport\"\n", " },\n", " {\n", " \"confidence\": 0.5646587610244751,\n", " \"hint\": \"sport\",\n", " \"name\": \"swimming\"\n", " },\n", " {\n", " \"confidence\": 0.013779879547655582,\n", " \"name\": \"ocean floor\"\n", " }\n", " ]\n", "}\n" ] } ], "source": [ "body = \"{'url':'http://www2.padi.com/blog/wp-content/uploads/2016/10/scuba-diving-reef-e1476482719834.jpg'}\"\n", "\n", "try:\n", " # Execute the REST API call and get the response.\n", " conn = http.client.HTTPSConnection('westcentralus.api.cognitive.microsoft.com')\n", " conn.request(\"POST\", \"/vision/v1.0/analyze?%s\" % params, body, headers)\n", " response = conn.getresponse()\n", " data = response.read()\n", "\n", " # 'data' contains the JSON data. The following formats the JSON data for display.\n", " parsed = json.loads(data.decode())\n", " print (\"Response:\")\n", " print (json.dumps(parsed, sort_keys=True, indent=2))\n", " conn.close()\n", "\n", "except Exception as e:\n", " print('Error:')\n", " print(e)\n", "\n", "####################################" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Testing 4: Skydiving\n", "\n", "Our final test image would be a potential edge case, as skydiving and scuba diving are very visually similar. However, you can see that Cognitive Services detects this is an aerial photo with high confidence. This would not be filtered as a potential scuba photo.\n", "\n", "![](http://www.skydiveoz.com.au/wp-content/uploads/2016/12/B-Licence-Pic-1.jpg)\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Response:\n", "{\n", " \"color\": {\n", " \"accentColor\": \"133A7B\",\n", " \"dominantColorBackground\": \"White\",\n", " \"dominantColorForeground\": \"White\",\n", " \"dominantColors\": [\n", " \"White\"\n", " ],\n", " \"isBWImg\": false\n", " },\n", " \"description\": {\n", " \"captions\": [\n", " {\n", " \"confidence\": 0.8847015046488436,\n", " \"text\": \"a man flying through the air on a cloudy day\"\n", " }\n", " ],\n", " \"tags\": [\n", " \"outdoor\",\n", " \"air\",\n", " \"flying\",\n", " \"water\",\n", " \"cloudy\",\n", " \"surfing\",\n", " \"clouds\",\n", " \"blue\",\n", " \"top\",\n", " \"riding\",\n", " \"man\",\n", " \"high\",\n", " \"ocean\",\n", " \"wave\",\n", " \"jumping\",\n", " \"skiing\",\n", " \"snow\",\n", " \"plane\",\n", " \"board\",\n", " \"trick\",\n", " \"large\",\n", " \"colorful\",\n", " \"doing\",\n", " \"standing\",\n", " \"boat\",\n", " \"white\",\n", " \"airplane\",\n", " \"field\"\n", " ]\n", " },\n", " \"metadata\": {\n", " \"format\": \"Jpeg\",\n", " \"height\": 1307,\n", " \"width\": 2321\n", " },\n", " \"requestId\": \"231ebc16-cc50-419f-81a9-3e1e4b1653da\",\n", " \"tags\": [\n", " {\n", " \"confidence\": 0.9999339580535889,\n", " \"name\": \"sky\"\n", " },\n", " {\n", " \"confidence\": 0.9850667715072632,\n", " \"name\": \"outdoor\"\n", " },\n", " {\n", " \"confidence\": 0.5827982425689697,\n", " \"name\": \"air\"\n", " },\n", " {\n", " \"confidence\": 0.4614807963371277,\n", " \"name\": \"cloudy\"\n", " },\n", " {\n", " \"confidence\": 0.4217190742492676,\n", " \"hint\": \"sport\",\n", " \"name\": \"surfing\"\n", " },\n", " {\n", " \"confidence\": 0.404719740152359,\n", " \"name\": \"clouds\"\n", " },\n", " {\n", " \"confidence\": 0.2684488892555237,\n", " \"name\": \"high\"\n", " },\n", " {\n", " \"confidence\": 0.20249073207378387,\n", " \"name\": \"day\"\n", " }\n", " ]\n", "}\n" ] } ], "source": [ "body = \"{'url':'http://www.skydiveoz.com.au/wp-content/uploads/2016/12/B-Licence-Pic-1.jpg'}\"\n", "\n", "try:\n", " # Execute the REST API call and get the response.\n", " conn = http.client.HTTPSConnection('westcentralus.api.cognitive.microsoft.com')\n", " conn.request(\"POST\", \"/vision/v1.0/analyze?%s\" % params, body, headers)\n", " response = conn.getresponse()\n", " data = response.read()\n", "\n", " # 'data' contains the JSON data. The following formats the JSON data for display.\n", " parsed = json.loads(data.decode())\n", " print (\"Response:\")\n", " print (json.dumps(parsed, sort_keys=True, indent=2))\n", " conn.close()\n", "\n", "except Exception as e:\n", " print('Error:')\n", " print(e)\n", "\n", "####################################" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3.6", "language": "python", "name": "python36" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" } }, "nbformat": 4, "nbformat_minor": 2 }