<file_sep>filteredArray = []

function buildImages() {
    url = '/fetch/api'

    d3.json(url).then(data => {
        // d3.select(".image_container").remove()
        var input = d3.select("#input").property("value");
        var input2 = d3.select("#input2").property("value");
        var color_input = d3.select("#color").property("value");
        var inputs = [input, input2]
        filteredArray = data;
        // test if both inputs are empy to display blank page
        if (input === '' && input2 === '') {
            filteredArray = []
        }

        inputs.forEach( (filter, index) => {
            if (filter) {
                // filter based on class from user input
                filteredArray = filteredArray.filter((dict) => dict['classes_detected'].includes(filter));
                // filter out anything with a certainty less than 99%
                filteredArray = filteredArray.filter( (dict) => {
                    index_of_score = dict['classes_detected'].indexOf(filter);
                    return dict['scores'][index_of_score] > 0.99
                })
            }
        });

        // filteredArray = filteredArray.slice(2);
        // filteredArray = colorFilter(filteredArray);
        createImageDivs(filteredArray);

    });
}

function colorFilter() {

    var color_input = d3.select("#color").property("value");
    // filter for color
    switch(color_input) {
        case 'red':
            coloredArray = filteredArray.filter((dict) => dict['color_percentages'].red > 50);
          break;
        case 'blue':
            coloredArray = filteredArray.filter((dict) => dict['color_percentages'].blue > 50);
          break;
        case 'purple':
            coloredArray = filteredArray.filter((dict) => dict['color_percentages'].purple > 50);
          break;
        case 'orange':
            coloredArray = filteredArray.filter((dict) => dict['color_percentages'].orange > 50);
          break;
        default:
            coloredArray = filteredArray;
      }
      createImageDivs(coloredArray)
}

function createImageDivs(filteredArray) {
    d3.select(".image_container").remove()
        
    var container = d3.select("main")
                    .append("div")
                    .attr("class", "image_container container-fluid");

    container.selectAll('img')
        .data(filteredArray)
        .enter()
        .append('div')
        .attr('class','col')
        .append('div')
        .attr('class','thumbnail')
        .append('img')
        .attr('class', 'img-fluid img-thumbnail')
        .attr('src', d => d.image_url);
}

function buildPieChart(img_url) {

    var data = filteredArray.filter((dict) => dict.image_url === img_url);
    var colors = [];
    var values = [];
    var color_object = data[0]['color_percentages'];
    var colorData = {'colors': colors, 'values':values};


    Object.entries(color_object).forEach(([key,value]) => {
        colors.push(key);
        values.push(value);
    });
    

    var myDuration = 600;
    var firstTime = true;

    var width = 960,
    height = 500,
    radius = Math.min(width, height) / 2;

    var width = 960,
    height = 500,
    radius = Math.min(width, height) / 2;
    var color = d3.scaleOrdinal(d3.schemeCategory10);

    var pie = d3.pie()
        .value(function(d) { return colorData.values; })
        .sort(null);

    var arc = d3.arc()
        .innerRadius(radius - 100)
        .outerRadius(radius - 20);

    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    var colorsByValue = d3.nest()
        .key(function(d) { return colorData.colors; })
        .entries(colorData)
        .reverse();

    var label = d3.select("form").selectAll("label")
        .data(colorsByValue)
        .enter().append("label");

    label.append("input")
        .attr("type", "radio")
        .attr("name", "fruit")
        .attr("value", function(d) { return d.key; })
        .on("change", change)
        .filter(function(d, i) { return !i; })
        .each(change)
        .property("checked", true);

    label.append("span")
        .text(function(d) { return d.key; });

    function change(region) {
        var path = svg.selectAll("path");
        var data0 = path.data(),
        data1 = pie(region.values);

        path = path.data(data1, key);

        path
        .transition()
        .duration(myDuration)
        .attrTween("d", arcTween)


        path
        .enter()
        .append("path")
        .each(function(d, i) {
            var narc = findNeighborArc(i, data0, data1, key) ;
            if(narc) {          
            this._current = narc;
            this._previous = narc;
            } else {          
            this._current = d;
            }
        }) 
        .attr("fill", function(d,i) { 
        return color(d.data.region)
        })
        .transition()
        .duration(myDuration)
        .attrTween("d", arcTween)


        path
        .exit()
        .transition()
        .duration(myDuration)
        .attrTween("d", function(d, index) {

            var currentIndex = this._previous.data.region;
            var i = d3.interpolateObject(d,this._previous);
            return function(t) {
            return arc(i(t))
            }

        })
        .remove()
    }
    function key(d) {
        return d.data.region;
      }
    
      function type(d) {
        d.count = +d.count;
        return d;
      }
    
      function findNeighborArc(i, data0, data1, key) {
        var d;
        if(d = findPreceding(i, data0, data1, key)) {
    
          var obj = cloneObj(d)
          obj.startAngle = d.endAngle;
          return obj;
    
        } else if(d = findFollowing(i, data0, data1, key)) {
    
          var obj = cloneObj(d)
          obj.endAngle = d.startAngle;
          return obj;
    
        }
    
        return null
    
    
    }
    
    // Find the element in data0 that joins the highest preceding element in data1.
    function findPreceding(i, data0, data1, key) {
      var m = data0.length;
      while (--i >= 0) {
        var k = key(data1[i]);
        for (var j = 0; j < m; ++j) {
          if (key(data0[j]) === k) return data0[j];
        }
      }
    }
    
    // Find the element in data0 that joins the lowest following element in data1.
    function findFollowing(i, data0, data1, key) {
      var n = data1.length, m = data0.length;
      while (++i < n) {
        var k = key(data1[i]);
        for (var j = 0; j < m; ++j) {
          if (key(data0[j]) === k) return data0[j];
        }
      }
    }
    
    function arcTween(d) {
    
      var i = d3.interpolate(this._current, d);
    
      this._current = i(0);
    
      return function(t) {
        return arc(i(t))
      }
    
    }
    
    
    function cloneObj(obj) {
      var o = {};
      for(var i in obj) {
        o[i] = obj[i];
      }
      return o;
    }
}
// added a bunch of event listeners because I can't figure out which one works best
d3.select("#color").on("change", colorFilter);
// d3.select("body").on("click", colorFilter);


d3.select("body").on("keydown", buildImages);

d3.select("form").on("keydown", buildImages);

d3.select("html").on("keydown", buildImages);
d3.select("html").on("click", colorFilter);


// buildImages()<file_sep>from flask import Flask, render_template, request, jsonify, redirect
import pymongo
import os
from maskImage import *
from videoToImage import videoToImage


app = Flask(__name__)
stored_object = {}
output_images = []
APP_ROOT = os.path.abspath("Upload_Scrape_Mongo_Push/")

target = os.path.join(APP_ROOT, 'static','images')
output_dir = os.path.join(APP_ROOT, 'static','output')
videos_out = os.path.join(APP_ROOT, 'static','processedVideoImage')
# output_dir = 'static/output'

if not os.path.isdir(target):
    os.mkdir(target)
else:
    print("Couldn't create upload directory: {}".format(target))
if not os.path.isdir(output_dir):
    os.mkdir(output_dir)
else:
    print("Couldn't create output directory: {}".format(output_dir))

@app.route("/")
def uploadfiles():
    output_images = ['static/output/' + img for img in os.listdir(output_dir)]
    print(output_images)
    output_videos = ['static/processedVideoImage/' + img for img in os.listdir(videos_out)]
    return render_template('upload.html', output_images=output_images, output_videos=output_videos)

@app.route('/saveimages', methods=["POST"])
def saveimages():
    model = startModel()
    for upload in request.files.getlist("file"):
        print("{} is the filename".format(upload.filename))
        filename = upload.filename
        destination = os.path.join(target, filename)
        # destination = "/".join([target, filename])
        print("Accept incoming file:", filename)
        # image_path = target + upload.filename
        # print("Save it to:", destination)
        upload.save(destination)
        file_name_root = upload.filename.split('.')[0]
        # create an output file name 
        file_output_name = file_name_root + '_output.png'
        # append file output name for later
        output_images.append(file_output_name)
        # run ML function
        output_name = os.path.join(output_dir, file_output_name)
        maskImage(destination, model, output_name)
        # os.remove(destination)
    
    return redirect("/")
    
@app.route('/savevideos', methods=['POST'])
def savevideos():
    # redirect to home page
    target = os.path.join(APP_ROOT, 'static', 'videoToImage')
    for upload in request.files.getlist("file"):
        print("{} is the filename".format(upload.filename))
        filename = upload.filename
        destination = os.path.join(target, filename)
        print("Accept incoming file:", filename)
        # image_path = 'static/videoToImage/' + upload.filename
        # print("Save it to:", destination)
        upload.save(destination)
        # file_name_root = upload.filename.split('.')[0]
        # create an output file name 
        # file_output_name = file_name_root + '_output.png'
        # append file output name for later
        # output_images.append(file_output_name)
        # run videoToImage
        videoToImage(destination)

    return redirect("/")


if __name__ == "__main__":
    app.run(debug=False)<file_sep>def scrape_images():
    from google_images_download2.google_images_download import google_images_download
    # redirect sys.stdout to a buffer
    class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',
                'bus', 'train', 'truck', 'boat', 'traffic light',
                'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',
                'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',
                'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',
                'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
                'kite', 'baseball bat', 'baseball glove', 'skateboard',
                'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',
                'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
                'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
                'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',
                'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',
                'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
                'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
                'teddy bear', 'hair drier', 'toothbrush','london','paris','new york','tour de france']
    class_names_arg = ', '.join(class_names)

    response = google_images_download.googleimagesdownload()
    args = {"keywords":class_names_arg, "limit":100,"print_urls":True}
    absolute_image_paths, errors, image_urls = response.download(args)
    # print(image_urls)
    # temporarily place into .csv 
    import pandas as pd
    try:
        # iterate over dict items b/c arrays of different length
        df = pd.DataFrame({ key:pd.Series(value) for key, value in image_urls.items() })
        df.to_csv('scrape_urls.csv')
    except:
        print('could not build build df/csv using image_url.items()')

    return df
<file_sep>from flask import Flask, render_template, request, jsonify, redirect
import pymongo
import os
from mongoFetch import mongoFetchClasses

app = Flask(__name__)
stored_object = {}
output_images = []
target = 'static/images'
output_dir = 'static/output'

if not os.path.isdir(target):
    os.mkdir(target)
else:
    print("Couldn't create upload directory: {}".format(target))
if not os.path.isdir(output_dir):
    os.mkdir(output_dir)
else:
    print("Couldn't create output directory: {}".format(output_dir))

@app.route("/")
def homepage():
    # store mongo data in gloval variable
    global stored_object
    # fetch all db data and place into api
    stored_object = mongoFetchClasses()
    return render_template('index.html')

@app.route("/fetch/api")
def fetchapi():
    # return mongoDB as JSON data
    return jsonify(stored_object)

@app.route("/uploadfiles")
def uploadfiles():
    output_images = ['static/output/' + img for img in os.listdir('static/output/')]
    return render_template('upload.html', output_images=output_images)

@app.route('/uploadfiles/saveimages', methods=["POST"])
def saveimages():
    for upload in request.files.getlist("file"):
        print("{} is the filename".format(upload.filename))
        filename = upload.filename
        destination = "/".join([target, filename])
        print("Accept incoming file:", filename)
        image_path = 'static/images/' + upload.filename
        # print("Save it to:", destination)
        upload.save(destination)
        file_name_root = upload.filename.split('.')[0]
        # create an output file name 
        file_output_name = file_name_root + '_output.png'
        # append file output name for later
        output_images.append(file_output_name)
        # run ML function
        image, output_image_matrix, classes_detected = maskImage(destination, ('website/static/output/' + file_output_name))
        os.remove(destination)

    # redirect to home page
    return redirect("/uploadfiles")







if __name__ == "__main__":
    app.run(debug=False)<file_sep># Project_3
Objective:
Image Recognition using Mask_RCNN Machine Learning Algoirthm. 

Build an interactive UI/application using Python Flask/Pandas/Numpy, MongoDB, HTML, CSS, Javascript, MS Coco database, Mask_RCNN model, Heroku.

Steps:
a. Upload the image in the UI, and display the raw image in the UI

b. Store the raw image in the DB

c. Use Mask_RCNN model to process and identify the object using MS Coco database and determine if the image can be identified (classified) and masked; otherwise pass a message stating 'Image cannot be recognized'

d. Display the processed/Masked image in the UI

e. Possibly Store the Masked image in Mongo DB (possibly constrained by free space available for use on MongoDB )

f. Upload videos and split the video into multiple frames/photos

g. Repeat steps a-e above

<!--Determining the Relationship betweent Uber Demand and the Weather (NYC)-->

<!--This project aims to determine the relationship between Uber ride demand and the historical weather. The team predicts that riderhsip will increase dramatically under less-than-ideal conditions (rain, snow).-->

<!--Reach Goal: Compare demand and weather to average subway ridership and locations per day-->

<!--## Datasets-->
<!--* [Kaggle](https://www.kaggle.com/fivethirtyeight/uber-pickups-in-new-york-city#uber-raw-data-jun14.csv)-->
<!--* [Weather](https://openweathermap.org/history)-->
<!--* [MTA Ridership (bonus)](http://web.mta.info/nyct/facts/ridership/ridership_sub.htm)-->
<!--    * [Weekly Turnstile Data](http://web.mta.info/developers/turnstile.html)--><file_sep>from maskImage import maskImage
from maskImage import startModel
from mongoPush import db_push
from googleImageScrape import scrape_images
import os 
import pandas as pd
from natsort import natsorted

model = startModel()
# scrape 100 images of each type 
df_urls = scrape_images()
# df_urls = pd.read_csv('scrape_urls.csv')

main_directory = os.getcwd()
downloads = os.path.join(main_directory, 'downloads')


for _, d, _ in os.walk(downloads):
    for folder in sorted(d):
        print(folder)
        current_folder = os.path.join(downloads, folder)
        print(current_folder)
        for _, _, f in os.walk(current_folder):
            for file in natsorted(f):
                try:
                    print(file)
                    # use this index embedded in the file name to prevent conflict with random, inexplicable nan values
                    index = int(file.split('.')[0]) - 1
                    current_file = os.path.join(current_folder, file)
                    # locate url in df based on folder name and index
                    img_url = df_urls[folder].iloc[index] 
                    print(img_url)
                    # return info from function
                    classes_detected, scores, mask_locations, class_percentages, image_shape = maskImage(current_file, model)
                    # pass into db
                    db_push(classes_detected, scores, mask_locations, img_url, class_percentages, image_shape)
                except:
                    print('error thrown for file: ', file)
            
<file_sep>import pymongo
def mongoFetchClasses():
    client = pymongo.MongoClient("mongodb+srv://team123:<EMAIL>/test?retryWrites=true")
    db = client.test
    collection = db.image_store

    # retrieve object based on given class
    stored_objects = collection.find() #{'classes_detected': class_to_lookup}
    # remove the id since it is not json serializable
    cleaned_objects = []
    for obj in stored_objects:
        obj.pop('_id')
        cleaned_objects.append(obj)
    # grab image url
    # image_url = stored_object['image_url']
    # print(image_url)
    # return url for use in the html page
    return cleaned_objects






<file_sep>gunicorn==19.9.0
pymongo==3.7.2
Flask==1.0.2
dnspython==1.16.0
<file_sep>import cv2
import numpy as np 
def colorPercentage(img):
    # input image as matrix
    imgHSV = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
    
    red = [0, 25]
    orange = [25, 30]
    yellow = [30, 40]
    green = [40, 80]
    blue = [80, 130]
    purple = [130, 179]

    colors = [blue, red, green, yellow, orange, purple]
    colorStrings = ["blue", "red", "green", "yellow", "orange", "purple"]

    cp = {}
    ranges = []

    for i in range(len(colors)):
        ranges.append([np.array([colors[i][0], 20, 40]), np.array([colors[i][1], 255, 255])])
        mask = cv2.inRange(imgHSV, ranges[i][0], ranges[i][1])
        percentage = round(np.sum(mask == 255) / (mask.shape[0] * mask.shape[1]) * 100)
        cp[colorStrings[i]] = percentage

    whiteRange = [np.array([0, 0, 240]), np.array([255, 20, 255])]
    blackRange = [np.array([0, 0, 0]), np.array([255, 255, 39])]

    bw = [whiteRange, blackRange]
    bwStrings = ["white", "black"]

    for i in range(len(bw)):

        ranges.append(bw[i])
        mask = cv2.inRange(imgHSV, ranges[i+6][0], ranges[i+6][1])
        percentage = round(np.sum(mask == 255) / (mask.shape[0] * mask.shape[1]) * 100)
        print(bwStrings[i], percentage)
        cp[bwStrings[i]] = percentage

    return cp<file_sep>def db_push(classes_detected, scores, mask_locations, image_url, color_percentages, image_shape):
    
    import pymongo
    import pandas as pd
    import datetime
  
    client = pymongo.MongoClient("mongodb+srv://ecalzolaio:<EMAIL>/test?retryWrites=true")
    db = client.test
    collection = db.image_store

    # image_rescaled = image_rescaled.tolist()
    mask_locations = mask_locations.tolist()
    to_insert = {
        # "image_rescaled": image_rescaled,
        "classes_detected": classes_detected,
        "scores":[float(score) for score in scores],
        "mask_locations": mask_locations,
        "image_url": image_url,
        "color_percentages": color_percentages,
        "image_shape": image_shape,
        "date": datetime.datetime.now()
    }

    collection.insert_one(to_insert)


    # Issue the serverStatus command and print the results
    # serverStatusResult=db.command("serverStatus")
    # pprint(serverStatusResult)<file_sep>import cv2
import numpy as np
import os
import sys
from maskImage import maskImage, startModel
def videoToImage(file_name):
    model = startModel()
    APP_ROOT = os.path.abspath("Upload_Scrape_Mongo_Push/")
    vid_image_dir = os.path.join(APP_ROOT,'static','videoToImage')

    print(vid_image_dir)
    if not os.path.isdir(vid_image_dir):
        os.mkdir(vid_image_dir)
    else:
        print("Couldn't create raw directory: {}".format(vid_image_dir))

    processed_video_dir = os.path.join(APP_ROOT,'static', 'processedVideoImage')

    if not os.path.isdir(processed_video_dir):
        os.mkdir(processed_video_dir)
    else:
        print("Couldn't create crop directory: {}".format(processed_video_dir))
    # def videoToFrames(video, everyNthFrame=30)
    # cap = cv2.VideoCapture(video)
    file_location = os.path.join(vid_image_dir, file_name)
    cap = cv2.VideoCapture(file_location)
    frameList = []
    currentFrame = 1
    while(True):
        # Capture frame-by-frame
        ret, frame = cap.read()
        if ret == False:
            break
        # Saves every Nth frame as jpg file
        # if currentFrame % everyNthFrame == 0:
        if currentFrame % 30 == 0:

            name = str(currentFrame) + '.jpg'
            image_location = os.path.join(vid_image_dir, name) 
            print ('Creating...' + name)

            cv2.imwrite(image_location, frame)

            output_name = os.path.join(processed_video_dir, name)
            maskImage(image_location, model, output_name)
            # frameList.append(frame)
        # To stop duplicate images
        currentFrame += 1
        # return frameList
