{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Image processing APIs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You will need to generate a private key at [RapidAPI](https://rapidapi.com/), then you can use it here."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"\n",
"# I keep mine in another file, which is not sent to GitHub\n",
"# Or put yours in the string 'key' below\n",
"try:\n",
" from secrets import mashape as key\n",
"except ImportError as e:\n",
" key = \" KEY GOES HERE \""
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## Face recognition\n",
"\n",
"Face++ has a comprehensive API, some of which is free. [Their site](http://www.faceplusplus.com/) allows you to build apps to do all kinds of clever things.\n",
"\n",
"We're going to use their free API via RapidAPI, which is a convenient place to try APIs for all sorts of things. Let's try a simple detection on this face...\n",
"\n",
""
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"url = \"https://faceplusplus-faceplusplus.p.rapidapi.com/facepp/v3/detect\"\n",
"target = \"https://static1.squarespace.com/static/549dcda5e4b0a47d0ae1db1e/t/5af31248562fa79d0f19ca68/1525879588450/?format=300w\"\n",
"\n",
"params = {'image_url': target}\n",
"\n",
"headers={\n",
" \"X-Mashape-Key\": key,\n",
" \"Content-Type\": \"application/x-www-form-urlencoded\"\n",
" }\n",
"\n",
"response = requests.post(url, headers=headers, data=params)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'image_id': 'NOknGGbV/+A3ERkzEq8tJw==',\n",
" 'request_id': '1553365760,c737662c-c122-40a1-bf0d-153021043a4d',\n",
" 'time_used': 376,\n",
" 'faces': [{'face_rectangle': {'width': 82,\n",
" 'top': 78,\n",
" 'left': 60,\n",
" 'height': 82},\n",
" 'face_token': '167b1cf6cd8b52093596f1327dc3c8e3'}]}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"response.json()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## With face attributes\n",
"\n",
"Turns out we can ask for lots of other information, e.g. about the facial expression."
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"attributes = ['gender',\n",
" 'age',\n",
" 'smiling',\n",
" 'headpose',\n",
" 'facequality',\n",
" 'blur',\n",
" 'eyestatus',\n",
" 'emotion',\n",
" 'ethnicity',\n",
" 'beauty',\n",
" 'mouthstatus',\n",
" 'eyegaze',\n",
" 'skinstatus'\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"params = {'image_url': target,\n",
" 'return_attributes': ','.join(attributes),\n",
" }\n",
"\n",
"response = requests.post(url, headers=headers, data=params)"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'image_id': 'sAqOk498IudAZHDVDfWUJg==',\n",
" 'request_id': '1553186533,491b9f79-18a5-460e-8f7f-3cd69cd713e5',\n",
" 'time_used': 288,\n",
" 'faces': [{'attributes': {'emotion': {'sadness': 0.0,\n",
" 'neutral': 0.0,\n",
" 'disgust': 0.008,\n",
" 'anger': 0.002,\n",
" 'surprise': 0.002,\n",
" 'fear': 0.002,\n",
" 'happiness': 99.987},\n",
" 'beauty': {'female_score': 67.194, 'male_score': 56.279},\n",
" 'gender': {'value': 'Male'},\n",
" 'age': {'value': 49},\n",
" 'mouthstatus': {'close': 0.01,\n",
" 'surgical_mask_or_respirator': 0.0,\n",
" 'open': 99.99,\n",
" 'other_occlusion': 0.0},\n",
" 'glass': {'value': 'None'},\n",
" 'skinstatus': {'dark_circle': 3.044,\n",
" 'stain': 40.645,\n",
" 'acne': 20.696,\n",
" 'health': 2.109},\n",
" 'headpose': {'yaw_angle': -13.445905,\n",
" 'pitch_angle': 4.7359223,\n",
" 'roll_angle': 11.515112},\n",
" 'blur': {'blurness': {'threshold': 50.0, 'value': 8.219},\n",
" 'motionblur': {'threshold': 50.0, 'value': 8.219},\n",
" 'gaussianblur': {'threshold': 50.0, 'value': 8.219}},\n",
" 'smile': {'threshold': 50.0, 'value': 100.0},\n",
" 'eyestatus': {'left_eye_status': {'normal_glass_eye_open': 0.037,\n",
" 'no_glass_eye_close': 0.0,\n",
" 'occlusion': 0.002,\n",
" 'no_glass_eye_open': 99.959,\n",
" 'normal_glass_eye_close': 0.0,\n",
" 'dark_glasses': 0.002},\n",
" 'right_eye_status': {'normal_glass_eye_open': 1.236,\n",
" 'no_glass_eye_close': 0.0,\n",
" 'occlusion': 0.0,\n",
" 'no_glass_eye_open': 98.763,\n",
" 'normal_glass_eye_close': 0.0,\n",
" 'dark_glasses': 0.0}},\n",
" 'facequality': {'threshold': 70.1, 'value': 58.089},\n",
" 'ethnicity': {'value': 'WHITE'},\n",
" 'eyegaze': {'right_eye_gaze': {'position_x_coordinate': 0.442,\n",
" 'vector_z_component': 0.992,\n",
" 'vector_x_component': -0.058,\n",
" 'vector_y_component': 0.108,\n",
" 'position_y_coordinate': 0.367},\n",
" 'left_eye_gaze': {'position_x_coordinate': 0.377,\n",
" 'vector_z_component': 0.794,\n",
" 'vector_x_component': -0.361,\n",
" 'vector_y_component': -0.49,\n",
" 'position_y_coordinate': 0.363}}},\n",
" 'face_rectangle': {'width': 130, 'top': 131, 'left': 80, 'height': 130},\n",
" 'face_token': '1512868d91c3e9ea2095207ae3ce9c85'}]}"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"response.json()"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## Daydreaming\n",
"\n",
"This is completely made up.\n",
"\n",
"\n",
"\n",
""
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"{u'seismic': [{u'attribute': {u'f_peak': {u'range': 7, u'value': 39},\n",
" u'wavelet': {u'confidence': 89.932, u'value': u'ricker'},\n",
" u'phase': {u'error': 12.23421, u'value': 1.73568},\n",
" u'fresnel': {u'error': 400, u'value': 1750},\n",
" u'colourbar': {u'confidence': 98.53456, u'value': u'black-red'}},\n",
" u'facies': [{u'center': {u'x': 58.583333, u'y': 20.989305},\n",
" u'name': 'parallel',\n",
" u'confidence': 76.45311},\n",
" {u'center': {u'x': 213.556323, u'y': 202.234543},\n",
" u'name': 'mounded',\n",
" u'confidence': 67.3253245},\n",
" {u'center': {u'x': 458.346354, u'y': 120.345636},\n",
" u'name': 'noisy',\n",
" u'confidence': 54.353466}],\n",
" u'img_height': 387,\n",
" u'img_id': u'524305ff333db315e583a4bdb5d03d0d',\n",
" u'img_width': 620,\n",
" u'session_id': u'928365a231974ae1a87ab51ca2066700',\n",
" u'url': u'https://dl.dropboxusercontent.com/u/14965965/seismic_example.png'}\n",
" \n"
]
}
],
"source": [
"# Don't execute this cell.\n",
"url = \"https://imageclass.io/classify/seismic.json\"\n",
"target = \"https://dl.dropboxusercontent.com/u/14965965/seismic_example.png\"\n",
"params = {'url': target,\n",
" 'time': '600,1600', # time range in ms\n",
" 'trace': '1000,1400', # trace range\n",
" 'dx': '25', # trace spacing in m\n",
" 'attribute': 'frequency,facies,resolution', # optional\n",
" }\n",
"headers={\n",
" \"API_key\": key,\n",
" \"Accept\": \"application/json\"\n",
" }\n",
"\n",
"response = unirest.post(url, headers=headers, params=params)\n",
"response.body"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## For realz\n",
"\n",
"I found [some code](https://gist.github.com/endolith/255291) by *[endolith](https://github.com/endolith)* to do frequency estimation.\n",
"\n",
"I got it working for seismic stuff in another notebook, [Frequency_from_image](./Frequency_from_image.ipynb). Then I set up a `Flask` app on [PythonAnywhere](https://www.pythonanywhere.com), which was surprisingly easy. It's serving at http://kwinkunks.pythonanywhere.com.\n",
"\n",
"It's headless — it only accepts API calls. See below for an example.\n",
"\n",
"Let's get the frequency content of the seismic in [this image](https://math.berkeley.edu/~sethian/2006/Applications/Seismic/time_mig_img.jpg). I have already measured the pixel positions of region of the image that I want, in the time range 0 to 3 s, and the *x* range 8 to 16 km.\n",
"\n",
""
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'job_uuid': 'eef5f2a0-4bf6-11e9-819f-0a84fd45cba2',\n",
" 'parameters': {'avg': 'trim',\n",
" 'method': 'xing',\n",
" 'region': '199,141,1608,1087',\n",
" 'time_range': [0.0, 3.0],\n",
" 'trace_spacing': 'regular',\n",
" 'traces': [128, 256, 384, 512, 640, 769, 897, 1025, 1153, 1281],\n",
" 'url': 'https://math.berkeley.edu/~sethian/2006/Applications/Seismic/time_mig_img.jpg'},\n",
" 'result': {'freq': {'max': 157.57,\n",
" 'min': 1.09,\n",
" 'n': 10,\n",
" 'peak': 20.3,\n",
" 'sd': 1.12},\n",
" 'greyscale': True,\n",
" 'histogram': {'bins': [-128.0,\n",
" -99.66666666666667,\n",
" -71.33333333333334,\n",
" -43.0,\n",
" -14.666666666666671,\n",
" 13.666666666666657,\n",
" 42.0,\n",
" 70.33333333333331,\n",
" 98.66666666666666,\n",
" 127.0],\n",
" 'counts': [147566,\n",
" 166666,\n",
" 248099,\n",
" 325574,\n",
" 155382,\n",
" 89953,\n",
" 69530,\n",
" 54919,\n",
" 75225]},\n",
" 'img_size': {'height': 1409, 'width': 946},\n",
" 'phase': {'avg': 3.35, 'n': 10, 'sd': 26.32},\n",
" 'snr': {'avg': 0.46, 'sd': 0.05}}}"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import requests\n",
"\n",
"url = \"http://kwinkunks.pythonanywhere.com/freq\"\n",
"target = \"https://math.berkeley.edu/~sethian/2006/Applications/Seismic/time_mig_img.jpg\"\n",
"params = {'url': target,\n",
" 'method': 'xing',\n",
" 'tmin': 0.0,\n",
" 'tmax': 3.0,\n",
" 'region': '199,141,1608,1087',\n",
" 'avg': 'trim'\n",
" }\n",
"headers={\n",
" \"Accept\": \"application/json\"\n",
" }\n",
"\n",
"response = requests.get(url, headers=headers, params=params)\n",
"response.json()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "geocomp",
"language": "python",
"name": "geocomp"
},
"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.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 1
}