Skip to content

Commit

Permalink
updated Chapter 09 Visual Recognition
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Dill committed Jan 5, 2018
1 parent f3e5b5a commit fa026dc
Show file tree
Hide file tree
Showing 8 changed files with 356 additions and 115 deletions.
2 changes: 1 addition & 1 deletion Chapter09/Documentation/answers/images_complete.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var busboy = require('connect-busboy');
var watson = require('watson-developer-cloud');
var request = require('request');
var apiKey = require("../../env.json").visual_recognition.api_key;
var vr_classifier = require("../../env.json").vr_classifier_id;
var vr_classifier = require("../../env.json").visual_recognition.classifier_id;


/**
Expand Down
92 changes: 13 additions & 79 deletions Chapter09/Documentation/answers/z2c-image_complete.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,6 @@
*/
// z2c-images.js
var b_Droppable, _url, _image, droppedFiles, $form, c_res ;
// in this app, collections and locations are matched JSON objects. The logic, in retrospect, would be simpler if these were
// combined into a single json object. If you want to do that, a structure that would be more effective would be:
// {"<collection_name>": {"id": "<image_id>", "path": "<path>"}, "<collection_name2>": {"id": "<image_id>", "path": "<path>"}, etc}
// for example, using the first two image sets below:
// {"water": {"id": "water_8fe4c6", "path": "/images/Landscape/Water/"},"collage": {"id": "collage_fe9bf8", "path": "/images/Collage/"}}
var collections = {
"water": "water_8fe4c6",
"collage": "collage_fe9bf8",
"still": "still_36b472",
"forest": "forest_2c108f",
"abstract": "abstract_626032",
"beach": null,
"building": null,
"garden": null
};
var locations = {
"water": "/images/Landscape/Water/",
"collage": "/images/Collage/",
"still": "/images/Still/",
"forest": "\\images\\Landscape\\Forest\\",
"abstract": "\\images\\Abstract\\",
"beach": "\\images\\Landscape\\Beach\\",
"building": "\\images\\Landscape\\Building\\",
"garden": "\\images\\Landscape\\Garden\\"
};

// visual recognition has an image limit of 2Mb
var maxSize = 2097152;
Expand Down Expand Up @@ -152,68 +127,27 @@ function displayImageClassificationResults(_target, _data)
console.log("displayImageClassificationResults entered with: "+_data);
// turn the returned string back into a JSON object
var imageResults = JSON.parse(_data);
console.log("displayImageClassificationResults parsed results: ",imageResults);

// create a display table
var _tbl = "<table width=90%><tr><th>Image Class</th><th>Probability</th><tr>";

var _image = imageResults.images[0].image;
// iterate through the classification results, displaying one table row for each result row
for (each in imageResults.images[0].classifiers[0].classes)
{ (function (_idx, _obj) {
var _disabled = (collections[_obj[_idx].class] == null) ? ", mic_disabled" : "";
_tbl += '<tr><td class="col-md-6'+_disabled+'"><a onclick="findInCollection(\''+_image+'\',\''+_obj[_idx].class+'\')" class="btn btn-primary, showfocus">'+_obj[_idx].class+'</a></td><td>'+_obj[_idx].score+'</td></tr>"';
})(each, imageResults.images[0].classifiers[0].classes)
if (imageResults.images[0].classifiers.length === 0)
{ _tbl += "<tr><td>No Results with higher than 50% probability</td></tr>"}
else
{
for (each in imageResults.images[0].classifiers[0].classes)
{
(function (_idx, _obj) {
_tbl += '<tr class="showFocus"><td class="col-md-6"><b>'+_obj[_idx].class+'</b></td><td>'+_obj[_idx].score+'</td></tr>';
})(each, imageResults.images[0].classifiers[0].classes)
}
}
// close the table
_tbl += "</table>";
// and append it to the target.
console.log(_tbl);
_target.append(_tbl);
}

/**
* find an image within an image collection
* @param {String} image - the image to search for in the provided set
* @param {String} collection - the name of the collection to search
*/
function findInCollection(image, collection)
{
// empty the target and display an animated gif
c_res.empty(); c_res.append("<center><img src='icons/loading.gif' /></center>");
// if the collection is not available, update the page with an appropriate message
if(collections[collection] == null) {c_res.append("<p>I'm sorry, but the "+collection+" is not yet available.")}
console.log("requesting search for image "+image+" in collection: "+collection);
// set the post options
var options = {};
options.image = image; options.collection = collections[collection];
// find a similar image
$.when($.post('/images/find', options)).done(function(res){
console.log(res);
// display the find results
displayCollectionResults(collection, res);
});

}
/**
* set the document cookies to update the previous and next steps
* @param {String} type - the classified type of image
* @param {String} _collection - the result set from the find similar process
*/
function displayCollectionResults(type, _collection)
{
// empty the html target
c_res.empty();
var found = _collection;
// get the name of the source file
var sourceName = found.image_file;
// create a display table
var tableOut = "<table width='95%'><tr><th>Image Name</th><th>Image</th><th>Confidence</th><tr>";
// iterate through the found images, displaying each one with it's name, a picture and the confidence level
for (each in found.similar_images)
{(function(_idx, _obj){
tableOut += "<tr><td>"+_obj[_idx].image_file+"</td><td><center><img class='showfocus' src='"+locations[type]+_obj[_idx].image_file+"', height=200 /></center></td><td>"+_obj[_idx].score+"</td></tr>";
})(each, found.similar_images);}
// close the table
tableOut += "</table>";
// and display it
c_res.append(tableOut);

}
31 changes: 0 additions & 31 deletions Chapter09/HTML/js/z2c-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,6 @@
*/
// z2c-alchemy.js
var b_Droppable, _url, _image, droppedFiles, $form, c_res ;
var collections = {
"water": "water_8fe4c6",
"collage": "collage_fe9bf8",
"still": "still_36b472",
"forest": "forest_2c108f",
"abstract": "abstract_626032",
"beach": null,
"building": null,
"garden": null
};
var locations = {
"water": "/images/Landscape/Water/",
"collage": "/images/Collage/",
"still": "/images/Still/",
"forest": "/images/Landscape/Forest/",
"abstract": "/images/Abstract/",
"beach": "/images/Landscape/Beach/",
"building": "/images/Landscape/Building/",
"garden": "/images/Landscape/Garden/"
};

var maxSize = 2097152;

Expand All @@ -56,14 +36,3 @@ function displayImageClassificationResults(_target, _data)
_target.empty();

}

function findInCollection(image, collection)
{
c_res.empty(); c_res.append("<center><img src='icons/loading.gif' /></center>");

}
function displayCollectionResults(type, _collection)
{
c_res.empty(); c_res.append("<center><img src='icons/loading.gif' /></center>");

}
4 changes: 2 additions & 2 deletions Chapter09/controller/env.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@
"visual_recognition": {
"url": "",
"note": "It may take up to 5 minutes for this key to become active",
"api_key": ""
"api_key": "",
"classifier_id": ""
},
"vr_classifier_id": "",
"sessionSecret" : ""
}
4 changes: 2 additions & 2 deletions Chapter09/controller/restapi/features/images.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ var path = require('path');
var busboy = require('connect-busboy');
var watson = require('watson-developer-cloud');
var request = require('request');
var apiKey = require("../../env.json").visual_recognition.apikey;
var vr_classifier = require("../../env.json").vr_classifier_id;
var apiKey = require("../../env.json").visual_recognition.api_key;
var vr_classifier = require("../../env.json").visual_recognition.classifier_id;


exports.upload= function(req, res){
Expand Down
78 changes: 78 additions & 0 deletions Chapter09/neg_images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/bash
# create negative image zips from faces94 images

YELLOW='\033[1;33m'
RED='\033[1;31m'
GREEN='\033[1;32m'
RESET='\033[0m'

# indent text on echo
function indent() {
c='s/^/ /'
case $(uname) in
Darwin) sed -l "$c";;
*) sed -u "$c";;
esac
}

# displays where we are, uses the indent function (above) to indent each line
function showStep ()
{
echo -e "${YELLOW}=====================================================" | indent
echo -e "${RESET}-----> $*" | indent
echo -e "${YELLOW}=====================================================${RESET}" | indent
}

# Grab the current directory
function getCurrent()
{
showStep "getting current directory"
DIR="$( pwd )"
echo "DIR in getCurrent is: ${DIR}"
THIS_SCRIPT=`basename "$0"`
showStep "Running '${THIS_SCRIPT}'"
}
declare basePath='images'
declare negBase='faces94'
declare -a folders=('male' 'female')
declare posZip="${2}"
declare curl_cmd="curl -X POST -F \"${2}_positive_examples=@${2}.zip\""
declare api_key="${1}"
declare url="https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classifiers?api_key=${api_key}&version=2016-05-20"
showStep "image folders are located here: ${basePath}/${negBase}"
for i in "${folders[@]}"
do
showStep "Processing folders in ${basePath}/${negBase}/${i}"
pushd "${basePath}/${negBase}/${i}"
declare -a currentSet=($(ls -d -- */))
# echo "current path is ${PWD}"
# echo "${currentSet}"
popd
# echo "current path is ${PWD}"
for j in "${currentSet[@]}"
do
let len=${#j}-1
# echo "Creating zip from images in ${basePath}/${negBase}/${i}/${j}"
# zip images/"${j:0:len}".zip "${basePath}/${negBase}/${i}/${j:0:len}"/*.jpg -q
# copy first image from each folder to ${i}
cp "${basePath}/${negBase}/${i}/${j:0:len}"/"${j:0:len}".1.jpg "${basePath}/${negBase}/${i}"/"${j:0:len}".1.jpg
# curl_cmd+=" -F \"${j:0:len}_positive_examples=@${j:0:len}.zip\""
done
showStep "Creating zip from images in ${basePath}/${negBase}/${i}"
zip images/"${i}".zip "${basePath}/${negBase}/${i}"/*.jpg -q
rm ${basePath}/${negBase}/${i}/*.jpg
curl_cmd+=" -F \"${i}_positive_examples=@${i}.zip\""
done

curl_cmd+=" -F \"name=visualAuthenticate\" \"${url}\""

showStep " about to execute this command to create your classifier: \n $curl_cmd"
pushd "${basePath}"
declare vr_classifier_id=$(eval $curl_cmd | jq '.classifier_id')
# eval $curl_cmd
showStep "Save this classifier id ==>${RED}${vr_classifier_id}${RESET}<== to your env.json file"
showStep "You can check the status of your classifier by executing the following command, you're looking for a 'ready' state'\n${RED}curl -X GET \"https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classifiers/${vr_classifier_id}?api_key=${api_key}&version=2016-05-20\"${RESET}"
popd

# curl -X GET "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classifiers/dogs_1477088859?api_key=${api_key}&version=2016-05-20"
# curl -X GET "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classifiers/visualAuthenticate_1048061842?api_key=a1107d9d670354018cf2d899ba8740c4855f466a&version=2016-05-20"
Loading

0 comments on commit fa026dc

Please sign in to comment.