diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..6566c3b Binary files /dev/null and b/.DS_Store differ diff --git a/Camera-app/README.md b/Camera-app/README.md new file mode 100644 index 0000000..d7ecf85 --- /dev/null +++ b/Camera-app/README.md @@ -0,0 +1,2 @@ +# SCC Camera App +--- \ No newline at end of file diff --git a/Camera-app/Untitled-1 b/Camera-app/Untitled-1 new file mode 100644 index 0000000..0bc0b4f --- /dev/null +++ b/Camera-app/Untitled-1 @@ -0,0 +1,15 @@ +[ +["image_1","https://c8.alamy.com/comp/E3J6G6/red-and-green-grapes-and-other-fruit-on-market-stall-E3J6G6.jpg"], +["image_2","https://media.istockphoto.com/photos/square-background-made-of-vegetables-and-fruits-picture-id1253828014"], +["image_3","https://c8.alamy.com/comp/E3J6G6/red-and-green-grapes-and-other-fruit-on-market-stall-E3J6G6.jpg"], +["image_4","https://media.istockphoto.com/photos/square-background-made-of-vegetables-and-fruits-picture-id1253828014"], +["image_4","https://c8.alamy.com/comp/E3J6G6/red-and-green-grapes-and-other-fruit-on-market-stall-E3J6G6.jpg"], +["image_4","https://media.istockphoto.com/photos/square-background-made-of-vegetables-and-fruits-picture-id1253828014"], +["image_4","https://media.istockphoto.com/photos/square-background-made-of-vegetables-and-fruits-picture-id1253828014"], +["image_4","https://media.istockphoto.com/photos/square-background-made-of-vegetables-and-fruits-picture-id1253828014"], +["image_4","https://c8.alamy.com/comp/E3J6G6/red-and-green-grapes-and-other-fruit-on-market-stall-E3J6G6.jpg"], +["image_4","https://c8.alamy.com/comp/E3J6G6/red-and-green-grapes-and-other-fruit-on-market-stall-E3J6G6.jpg"], +["image_4","https://media.istockphoto.com/photos/square-background-made-of-vegetables-and-fruits-picture-id1253828014"], +["image_4","https://media.istockphoto.com/photos/square-background-made-of-vegetables-and-fruits-picture-id1253828014"]] + +"{\"attrs\":{\"x\":78.53045654296875,\"y\":98.27029857535037,\"width\":100,\"height\":90,\"fill\":\"transparent\",\"name\":\"box_0\",\"draggable\":true},\"className\":\"Rect\"}" \ No newline at end of file diff --git a/Camera-app/annotate.html b/Camera-app/annotate.html new file mode 100644 index 0000000..b2ca386 --- /dev/null +++ b/Camera-app/annotate.html @@ -0,0 +1,72 @@ + + + + + + + + + Camera App + + + + + + + + + + + + + + + + + + + +
+ + Home +
+
+ +
+
+
+ Class Labels + +
+
Select Classes
+ + +
+
+
+ + + diff --git a/Camera-app/annotate.js b/Camera-app/annotate.js new file mode 100644 index 0000000..66796f1 --- /dev/null +++ b/Camera-app/annotate.js @@ -0,0 +1,286 @@ +'use strict'; +var open = false; + +var ImageAnnotations = {} +var currentImage = "" + +fetch('./fruits.txt') + .then(response => response.text()) + .then(text => { + console.log(text); + var fruits = text.split('\n'); + for (var i=0; i < fruits.length; i++){ + document.getElementById("fruits_selector").innerHTML += '' + } + }) + // outputs the content of the text file + +document.getElementById("save_btn").addEventListener("click", function(){ + var attributes = []; + var allElements = document.querySelectorAll(".select2-selection__choice"); + for (var i = 0; i < allElements.length; i++) { + if (allElements[i].getAttribute("title")) { + attributes.push(allElements[i].getAttribute("title")); + } + } + ImageAnnotations["img_"+currentImage]["tags"] = attributes; + ImageAnnotations["img_"+currentImage]["image"] = images[currentImage][1]; + sendImages(ImageAnnotations["img_"+currentImage]) +}); + +document.getElementById("icon_exp").addEventListener("click", function(){ + if (!open){ + document.getElementById("label_box").style.height="32%"; + document.getElementById("label_box").style.opacity=1; + document.getElementById("arrowoicon").style.transform="rotate(180deg)"; + open = true; + }else { + document.getElementById("label_box").style.height="8%"; + document.getElementById("label_box").style.opacity=1; + document.getElementById("arrowoicon").style.transform="rotate(360deg)"; + open = false; + } +}); + +$(document).ready(function() { + $('.js-example-basic-multiple').select2(); +}); + +var images = localStorage.getItem("images_scc"); +images = JSON.parse(images); +console.log(images) +var width = window.innerWidth; +var height = window.innerHeight; + +var imghtml = "" +i = 0 +for (const item of images) { + imghtml += '' + i += 1; +} + +document.getElementById("img_thumbnails").innerHTML = imghtml; + +function changeImage(evt){ + var thumbnails = document.getElementsByClassName("imgthumb"); + for (var i = 0; i < thumbnails.length; i++ ) { + thumbnails[i].style.width = "50px"; + thumbnails[i].style.height = "50px"; + } + document.getElementById("container").innerHTML = "" + evt.currentTarget.style.width = "55px"; + evt.currentTarget.style.height = "55px"; +} + +var elements = document.getElementsByClassName("imgthumb"); +for (var i = 0; i < elements.length; i++) { + elements[i].data_id = i; + elements[i].addEventListener('click', function (evt) { + currentImage = evt.currentTarget.data_id; + ImageAnnotations["img_" + evt.currentTarget.data_id] = {image_id: evt.currentTarget.data_id} + console.log(ImageAnnotations) + changeImage(evt) + var imageObj = new Image(); + imageObj.src = evt.srcElement.currentSrc; + console.log(imageObj.width, imageObj.height, evt.currentTarget.data_id); + var stage = new Konva.Stage({ + container: 'container', + width: width, + height: (imageObj.height / imageObj.width) * width, + }); + + var layer = new Konva.Layer(); + stage.add(layer); + + + imageObj.onload = function () { + var image = new Konva.Image({ + x: 0, + y: 0, + image: imageObj, + width: width, + height: (imageObj.height / imageObj.width) * width + }); + layer.add(image) + + // add a new feature, lets add ability to draw selection rectangle + var selectionRectangle = new Konva.Rect({ + fill: 'rgba(0,0,255,0.5)', + visible: false, + }); + + layer.add(selectionRectangle); + + var x1, y1, x2, y2; + stage.on('mousedown touchstart', (e) => { + // do nothing if we mousedown on any shape + if (e.target !== stage) { + return; + } + e.evt.preventDefault(); + x1 = stage.getPointerPosition().x; + y1 = stage.getPointerPosition().y; + x2 = stage.getPointerPosition().x; + y2 = stage.getPointerPosition().y; + + selectionRectangle.visible(true); + selectionRectangle.width(0); + selectionRectangle.height(0); + }); + + + stage.on('mousemove touchmove', (e) => { + // do nothing if we didn't start selection + if (!selectionRectangle.visible()) { + return; + } + e.evt.preventDefault(); + x2 = stage.getPointerPosition().x; + y2 = stage.getPointerPosition().y; + + selectionRectangle.setAttrs({ + x: Math.min(x1, x2), + y: Math.min(y1, y2), + width: Math.abs(x2 - x1), + height: Math.abs(y2 - y1), + }); + }); + + stage.on('mouseup touchend', (e) => { + // do nothing if we didn't start selection + if (!selectionRectangle.visible()) { + return; + } + e.evt.preventDefault(); + // update visibility in timeout, so we can check it in click event + setTimeout(() => { + selectionRectangle.visible(false); + }); + + var shapes = stage.find('.rect'); + var box = selectionRectangle.getClientRect(); + var selected = shapes.filter((shape) => + Konva.Util.haveIntersection(box, shape.getClientRect()) + ); + tr.nodes(selected); + }); + var rect_count = 0 + function createRect(x, y) { + console.log("Inside createRect") + var group = new Konva.Group({ + name: 'rect_btn_grp' + }) + var rect2 = new Konva.Rect({ + x: x, + y: y, + width: 100, + height: 90, + fill: 'transparent', + name: 'rect', + draggable: true, + }); + rect2.name('box_'+rect_count) + rect_count += 1 + var button = new Konva.Label({ + x: x, + y: y, + opacity: 0.75, + }); + button.add(new Konva.Tag({ + fill: 'white', + lineJoin: 'round', + shadowColor: 'white', + shadowBlur: 10, + shadowOffset: 10, + shadowOpacity: 0.5 + })); + + button.add(new Konva.Text({ + text: 'X', + fontSize: 18, + padding: 5, + fill: 'black' + })); + // layer.add(rect2); + // layer.add(button); + // layer.add(tr1); + + var tr1 = new Konva.Transformer(); + tr1.borderStrokeWidth(3); + tr1.borderStroke("white") + // by default select all shapes + var nodelist = [rect2, button] + tr1.nodes(nodelist); + group.add(rect2) + group.add(button) + group.add(tr1) + layer.add(group); + button.on('click tap', function (e) { + tr1.destroy(); + rect2.destroy(); + button.destroy(); + group.destroy(); + layer.draw(); + }); + } + + stage.on('dblclick dbltap', function (e) { + console.log(e.target.className) + // if we are selecting with rect, do nothing + if (e.target.className == 'Rect') { + console.log("Rectangle", e.target.attrs.name) + return; + } + + // if click on empty area - remove all selections + if (e.target === stage) { + console.log("Empty Area") + tr.nodes([]); + return; + } + + // do nothing if clicked NOT on our rectangles + + if (e.target.className == 'Image') { + console.log("Empty Area - not rect", e) + var pos = stage.getPointerPosition(); + createRect(pos.x, pos.y) + var all_rectangles = layer.find('.rect_btn_grp'); + console.log(all_rectangles) + return; + } + }); + }; + }); +} + +elements[0].click() + +function sendImages(dataToSend){ + let headers = new Headers(); + + headers.append('Content-Type', 'application/json'); + headers.append('Accept', 'application/json'); + headers.append('Origin','http://localhost:8080/scc_server_receive/'); + console.log(dataToSend) + var req = fetch('http://localhost:8080/scc_server_receive/', { + method: 'POST', + body: JSON.stringify(dataToSend), /* or aFile[0]*/ + mode: 'no-cors', + credentials: 'include', + headers: headers + }); // returns a promise + + req.then(function(response) { + if (response.ok) { + + } else { + } + }, function(error) { + console.error('failed due to network error or cross domain') + }) +} + + + +// imageObj.src = 'https://previews.123rf.com/images/posinote/posinote1711/posinote171100095/91013749-mixed-many-type-of-fruits-with-full-frame-and-vertical-photo-.jpg' \ No newline at end of file diff --git a/Camera-app/app.js b/Camera-app/app.js new file mode 100644 index 0000000..3d63727 --- /dev/null +++ b/Camera-app/app.js @@ -0,0 +1,76 @@ +// Set constraints for the video stream +var constraints = { video: { facingMode: {exact: 'environment'}}, audio: false }; +var track = null; +var fd = new FormData(); + +// Define constants +const cameraView = document.querySelector("#camera--view"), + cameraOutput = document.querySelector("#camera--output"), + cameraSensor = document.querySelector("#camera--sensor"), + cameraTrigger = document.querySelector("#camera--trigger"); + +document.getElementById("annotate").addEventListener("click", function(){ + console.log("clicked on button"); + datadict = {} + for(var pair of fd.entries()) { + datadict[pair[0]] = pair[1]; + } + localStorage.setItem("images_scc", JSON.stringify(Array.from(Object.entries(datadict)))); + window.location.href = 'annotate.html'; +}); + +// Access the device camera and stream to cameraView +function cameraStart() { + navigator.mediaDevices + .getUserMedia(constraints) + .then(function(stream) { + track = stream.getTracks()[1]; + cameraView.srcObject = stream; + }) + .catch(function(error) { + console.error("Oops. Something is broken.", error); + }); +} +count = 0 +// Start the video stream when the window loads +window.addEventListener("load", cameraStart, false); + +// Take a picture when cameraTrigger is tapped +cameraTrigger.onclick = function() { + + count += 1 + cameraSensor.width = cameraView.videoWidth; + cameraSensor.height = cameraView.videoHeight; + cameraSensor.getContext("2d").drawImage(cameraView, 0, 0); + cameraOutput.src = cameraSensor.toDataURL("image/webp"); + console.log(cameraOutput.src) + cameraOutput.classList.add("taken"); + console.log(cameraOutput); + document.getElementById('camera--output').style.display = "block"; + fd.append('image_' + count, cameraOutput.src) + // track.stop(); +}; + +function sendImages(){ + let headers = new Headers(); + + headers.append('Content-Type', 'application/json'); + headers.append('Accept', 'application/json'); + headers.append('Origin','https://291f-68-133-40-138.ngrok.io/scc_server_receive/'); + + var req = fetch('https://291f-68-133-40-138.ngrok.io/scc_server_receive/', { + method: 'POST', + body: fd, /* or aFile[0]*/ + mode: 'no-cors', + credentials: 'include', + headers: headers + }); // returns a promise + + req.then(function(response) { + if (response.ok) { + } else { + } + }, function(error) { + console.error('failed due to network error or cross domain') + }) +} diff --git a/Camera-app/app.py b/Camera-app/app.py new file mode 100644 index 0000000..421fe82 --- /dev/null +++ b/Camera-app/app.py @@ -0,0 +1,25 @@ +from flask import Flask, request, jsonify +import base64 +import sys +import random +import string +import json +BASE_ADR = "../" +app = Flask(__name__) + +@app.route('/scc_server_receive/', methods=['GET', 'POST']) +def scc_server_receive(): + name = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(8)) + content = json.loads(request.data) + print(content, file=sys.stderr) + with open(BASE_ADR + "/image_dataset/image_" + str(content["image_id"]) + "_" + name + ".png", "wb") as fh: + imgdata = base64.b64decode(content["image"].split(",")[1]) + fh.write(imgdata) + with open(BASE_ADR + "/image_dataset/data_" + str(content["image_id"]) + "_" + name + ".json", "w") as file: + del content["image"] + json.dump(content, file) + + return {"status": 200} + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=8080) \ No newline at end of file diff --git a/Camera-app/draw.js b/Camera-app/draw.js new file mode 100644 index 0000000..db60c18 --- /dev/null +++ b/Camera-app/draw.js @@ -0,0 +1,119 @@ +var canvas = document.getElementById('camera--sensor'), +ctx = canvas.getContext('2d'), +rect = {}, +drag = false, +mouseX, +mouseY, +closeEnough = 10, +dragTL = dragBL = dragTR = dragBR = false; + +function init() { +canvas.addEventListener('mousedown', mouseDown, false); +canvas.addEventListener('mouseup', mouseUp, false); +canvas.addEventListener('mousemove', mouseMove, false); + +rect = { + startX: 20, + startY: 20, + w: 150, + h: 100 +} +} + +function mouseDown(e) { +mouseX = e.pageX - this.offsetLeft; +mouseY = e.pageY - this.offsetTop; + +// if there isn't a rect yet +if (rect.w === undefined) { + rect.startX = mouseY; + rect.startY = mouseX; + dragBR = true; +} + +// if there is, check which corner +// (if any) was clicked +// +// 4 cases: +// 1. top left +else if (checkCloseEnough(mouseX, rect.startX) && checkCloseEnough(mouseY, rect.startY)) { + dragTL = true; +} +// 2. top right +else if (checkCloseEnough(mouseX, rect.startX + rect.w) && checkCloseEnough(mouseY, rect.startY)) { + dragTR = true; + +} +// 3. bottom left +else if (checkCloseEnough(mouseX, rect.startX) && checkCloseEnough(mouseY, rect.startY + rect.h)) { + dragBL = true; + +} +// 4. bottom right +else if (checkCloseEnough(mouseX, rect.startX + rect.w) && checkCloseEnough(mouseY, rect.startY + rect.h)) { + dragBR = true; + +} +// (5.) none of them +else { + // handle not resizing +} + +ctx.clearRect(0, 0, canvas.width, canvas.height); +draw(); + +} + +function checkCloseEnough(p1, p2) { +return Math.abs(p1 - p2) < closeEnough; +} + +function mouseUp() { +dragTL = dragTR = dragBL = dragBR = false; +} + +function mouseMove(e) { +mouseX = e.pageX - this.offsetLeft; +mouseY = e.pageY - this.offsetTop; +if (dragTL) { + rect.w += rect.startX - mouseX; + rect.h += rect.startY - mouseY; + rect.startX = mouseX; + rect.startY = mouseY; +} else if (dragTR) { + rect.w = Math.abs(rect.startX - mouseX); + rect.h += rect.startY - mouseY; + rect.startY = mouseY; +} else if (dragBL) { + rect.w += rect.startX - mouseX; + rect.h = Math.abs(rect.startY - mouseY); + rect.startX = mouseX; +} else if (dragBR) { + rect.w = Math.abs(rect.startX - mouseX); + rect.h = Math.abs(rect.startY - mouseY); +} +ctx.clearRect(0, 0, canvas.width, canvas.height); +draw(); +} + +function draw() { +ctx.fillStyle = "#222222"; +ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h); +drawHandles(); +} + +function drawCircle(x, y, radius) { +ctx.fillStyle = "#FF0000"; +ctx.beginPath(); +ctx.arc(x, y, radius, 0, 2 * Math.PI); +ctx.fill(); +} + +function drawHandles() { +drawCircle(rect.startX, rect.startY, closeEnough); +drawCircle(rect.startX + rect.w, rect.startY, closeEnough); +drawCircle(rect.startX + rect.w, rect.startY + rect.h, closeEnough); +drawCircle(rect.startX, rect.startY + rect.h, closeEnough); +} + +init(); \ No newline at end of file diff --git a/Camera-app/fruits.txt b/Camera-app/fruits.txt new file mode 100644 index 0000000..a0ce729 --- /dev/null +++ b/Camera-app/fruits.txt @@ -0,0 +1,412 @@ +apple +apricot +avocado +banana +bell pepper +bilberry +blackberry +blackcurrant +blood orange +blueberry +boysenberry +breadfruit +canary melon +cantaloupe +cherimoya +cherry +chili pepper +clementine +cloudberry +coconut +cranberry +cucumber +currant +damson +date +dragonfruit +durian +eggplant +elderberry +feijoa +fig +goji berry +gooseberry +grape +grapefruit +guava +honeydew +huckleberry +jackfruit +jambul +jujube +kiwi fruit +kumquat +lemon +lime +loquat +lychee +mandarine +mango +mulberry +nectarine +nut +olive +orange +papaya +passionfruit +peach +pear +persimmon +physalis +pineapple +plum +pomegranate +pomelo +purple mangosteen +quince +raisin +rambutan +raspberry +redcurrant +rock melon +salal berry +satsuma +star fruit +strawberry +tamarillo +tangerine +tomato +ugli fruit +watermelon +Aburana +Acorn squash/Pepper squash +Ahipa +Alfalfa sprouts +Amaranth +American groundnuts +Anise +Aonori +Arame +Arracacha +Arrowhead +Arrowroot +Artichoke/Globe artichoke +Arugula/Salad rocket +Asparagus +Azuki beans +Bamboo shoots/Bamboo sprouts +Banana squash +Basil/Sweet basil +Beans +Bean sprouts +Beet +Belgian endive +Bell pepper/Sweet pepper +Bitter leaf +Bitter melon/Bitter gourd/Bitter squash +Black beans +Black cumin +Black-eyed peas +Bok choy/Chinese cabbage +Borage +Borlotti beans +Bottle gourd/Calabash +Breadfruit +Broadleaf arrowhead +Broccoli +Broccolini/Baby broccoli +Brussels sprout +Bull's blood +Burdock +Butter beans/Lima beans +Buttercup squash +Butterhead lettuce +Butternut pumpkin/Butternut squash +Cabbage +Cabbage sprouts +Cactus leaves +Caigua +Camas +Cape gooseberry +Caraway +Cardoon/Artichoke thistle +Carola +Carrot +Cassava/Yuca +Catsear +Cauliflower +Cayenne pepper +Celeriac +Celery +Celtuce +Ceylon spinach +Chaya/Tree spinach +Chayote/Christophene +Cherry tomatoes +Cucumber +Chickweed +Chicory +Chile peppers +Chinese chives/Garlic chives +Chinese mallow +Chinese snow peas +Chives +Choy sum +Chrysanthemum leaves +Cilantro/Coriander +Collard greens +Coral lettuce +Corn +Corn salad/Lamb's lettuce +Dabberlocks/badderlocks +Dandelion +Delicata squash +Dill/Lao coriander +Dinosaur kale/Lacinato kale +Dolichos beans +Drumsticks +Dulse +Daikon +Earthnut pea +Edamame +Eggplant/Aubergine +Elephant foot yam +Elephant garlic +Endive +English peas/Peas +Ensete +Epazote +Escarole +Fat hen +Fava beans/Broad beans +Fennel/Finocchio +Fiddlehead fern +Florence fennel +Flowering cabbage +Fluted pumpkin +French beans/Green beans +Garbanzo beans/Chickpeas +Garden cress/Cress +Garden rocket +Garlic +Gem squash +Gherkin +Ginger +Globe eggplant +Gobo +Golden nugget squash +Guar +Golden Samphire +Good King Henry +Gourd +Grape tomato +Greater plantain +Green cabbage +Green cauliflower +Green onion +Green pepper +Groundnuts +Habanero chili +Hakurei turnip +Hamburg rooted parsley +Haricot beans +Hijiki +Horse gram +Horseradish +Hothouse cucumber +Hubbard squash +Hyacinth beans +Ice plant +Indian peas +Irish moss +Italian sweet pepper +Italian red onion +Jalapeño +Japanese bunching onion +Japanese eggplant +Japanese pumpkin/Kabocha squash +Japanese turnips +Jerusalem artichoke/Sunchoke +Jícama +Kabu +Kai-lan/Chinese broccoli +Kale +Kelps +Kidney beans +Kohlrabi/German turnip +Komatsuna +Kombu +Kuka +Kurrat +Lagos bologi +Land cress +Laver +Leafy greens +Lebanese cucumber +Leeks +Lemon +Lentils +Lemon grass +Lettuce +Lima beans +Lime +Lizard's tail +Lotus root +Luffa +Mache +Malabar gourd +Mange tout +Marjoram +Marrow +Melons +Miner's lettuce +Minikin +Mitsuba +Myoga +Mizuna +Morel/Morchella +Moth beans +Mountain pepper +Mozuku +Mung beans +Mulukhiyah +Mushroom +Mustard plant +Napa cabbage +Nasturtium +Nasu +Navy beans +Negi +Nettles +New Zealand spinach +Nopales +Nori +Oakleaf lettuce +Ogonori +Okra +Onions +Olives +Orache +Ostrich fern +Oyster plant +Pak choi/Chinese cabbage +Palm heart +Paracress +Parsley +Parsnips +Pattypan squash +Peanut +Pea sprouts/leaves +Pigeon pea +Pignut +Pinto beans +Plectranthus +Poblano +Pohole +Pointed gourd +Poke +Pokeweed +Potatoes +Prairie turnip +Prussian asparagus +Pumpkins +Purslane +Quince +Radicchio +Radish +Rainbow chard +Rapeseed +Rapini/Broccoli rabé +Red bell peppers +Red cabbage +Red kidney beans +Renkon +Rhubarb +Ridge cucumber +Ridge gourd +Rocket +Rockmelon +Romaine lettuce/Cos lettuce +Romanesco broccoli +Romano beans +Rosemary +Runner beans +Rutabaga/Swedish turnips +Salad turnip +Salsify +Samphire +Savoy cabbage +Satoimo +Satsumaimo​/Sweet potato +Scallions/Spring onions +Scorzonera +Sculpit/Stridolo +Sea beet +Sea grape +Sea kale +Sea lettuce +Shallots +Shiso/Ohba +Sierra leone bologi +Silverbeet/Chard +Skirret +Sloke +Snake beans +Snake gourd +Snake squash +Snow peas +Soko/Lagos spinach +Sorrel +Soybeans +Spaghetti squash +Spinach +Spring greens +Squash +Squash blossoms +Striped marrow +Sugar snap peas +Sweet corn +Tabasco pepper +Taro +Tarwi +Tatsoi/Spinach mustard +Tepary beans +Thyme +Tigernut +Tinda +Tomatillo +Tomato +T-plant +Turnips +Tuscan kale +Ulluco +Urad bean +Velvet bean +Vidalia onion +Wakame +Wasabi +Water chestnut +Watercress +Water spinach +Welsh onion +West Indian gherkin +West Indian pumpkin +White eggplant +White salad onion +Wild leek +Winged beans +Winter melon +Winter purslane +Winter squash +Xemenia +Xigua +Yacón +Yam +Yamaimo +Yardlong beans +Yarrow +Yau chow +Yellow squash +Yow choy +Yu choy sum +Zucchini/Courgette \ No newline at end of file diff --git a/Camera-app/images/camera_icon.png b/Camera-app/images/camera_icon.png new file mode 100644 index 0000000..1a28c7c Binary files /dev/null and b/Camera-app/images/camera_icon.png differ diff --git a/Camera-app/index.html b/Camera-app/index.html new file mode 100644 index 0000000..ab0659c --- /dev/null +++ b/Camera-app/index.html @@ -0,0 +1,51 @@ + + + + + + + + Camera App + + + + + + + + + + + + + +
+ +
+ +
+ + +
Annotate
+
+
+ + + + + + + + + + + +
+ +
+ + + + + + diff --git a/Camera-app/manifest.json b/Camera-app/manifest.json new file mode 100644 index 0000000..21aa56e --- /dev/null +++ b/Camera-app/manifest.json @@ -0,0 +1,34 @@ +{ + "name": "SCC-App", + "short_name": "SCC-App", + "start_url": ".", + "display": "standalone", + "background_color": "#fff", + "description": "Image Capture and Annotation Tool for SCC Project", + "icons": [{ + "src": "images/camera_icon.png", + "sizes": "48x48", + "type": "image/png" + }, { + "src": "images/camera_icon.png", + "sizes": "72x72", + "type": "image/png" + }, { + "src": "images/camera_icon.png", + "sizes": "96x96", + "type": "image/png" + }, { + "src": "images/camera_icon.png", + "sizes": "144x144", + "type": "image/png" + }, { + "src": "images/camera_icon.png", + "sizes": "168x168", + "type": "image/png" + }, { + "src": "images/camera_icon.png", + "sizes": "192x192", + "type": "image/png" + }] + } + \ No newline at end of file diff --git a/Camera-app/style.css b/Camera-app/style.css new file mode 100644 index 0000000..0d91e31 --- /dev/null +++ b/Camera-app/style.css @@ -0,0 +1,224 @@ +html,body{ + overflow: hidden; + overflow: hidden; + margin: 0; + padding: 0; +} + +#camera--output{ + display: none; +} + +#title{ + float: right; + margin-right: 3%; +} + +#annotate { + float: right; +} + +#annotate-button{ + float: right; + padding: 3%; + clear: both; + margin-top: -26px; + background-color: #e2e2e2; + border-radius: 6px; +} + +#glabel{ + padding: 5%; + border-bottom: 2px solid #e5e4e4; + font-weight: 800; +} + +.label_box{ + position: fixed; + bottom: 0; + /* padding: 3%; */ + width: 100%; + box-shadow: 0px 2px 15px 5px #838383; + font-family: 'Montserrat'; + /* padding-left: 4%; */ + height: 8%; + opacity: 1; + background-color:white; + transition:0.4s; + z-index:1000; + border-top-left-radius: 20px; + border-top-right-radius: 20px; +} + +#save_btn{ + outline: #3bd100; + border-color: #31ab00; + width: 73%; + margin-left: 5%; + padding: 4%; + margin-top: 3%; + background-color: #03dd00; + text-align: center; + border-radius: 6px; + display: inline-block; + font-size: 0.9em; + font-family: 'Montserrat'; + outline: none; +} + +#del_btn{ + width: 6%; + margin-left: 2%; + padding: 4%; + margin-top: 3%; + background-color: #ff0000; + text-align: center; + border-radius: 6px; + color: white; + display: inline-block; + font-size: 1.3em; +} + +#camera--header{ + font-family: 'Montserrat', sans-serif; + display: block; + height: 0%; + padding: 7%; + padding-bottom: 13%; + display: inline-block; + font-weight: 800; + width: 89vw; + background-color: white; + box-shadow: 0px 2px 25px #d8d6d6; +} + +#arrowoicon{ + transition:0.7s; +} + +.select2-container{ + padding: 5% !important; + width: 100% !important; + padding-bottom: 0 !important; + padding-top: 2% !important; +} + +#icon_exp{ + float: right; + border-radius: 45px; + padding: 8px; + padding-right: 10px; + clear: both; + margin-top: -2%; + background-color: #f5f5f5; +} + +/* #camera--header{ + font-family: 'Montserrat', sans-serif; + display: block; + height: 0%; + padding: 7%; + padding-bottom: 13%; + font-weight: 800; + width: 100%; + background-color: white; + box-shadow: 0px 2px 25px #d8d6d6; +} */ + +#camera, #camera--view, #camera--sensor, #camera--output{ + position: fixed; + height: 100%; + width: 100%; + object-fit: cover; +} + +#camera--view, #camera--sensor, #camera--output{ + transform: scaleX(1); +} + +#shutter_holder{ + position: fixed; + bottom: 5%; + width: 100%; +} + +#shutter_holder img{ + margin-left: auto; + margin-right: auto; + display: block; +} + +#camera--trigger{ + width: 18%; + background-color: white; + box-shadow: 0px 2px 25px #c1c1c1; + border-radius: 100px; +} + +.taken{ + height: 100px!important; + width: 100px!important; + transition: all 0.5s ease-in; + border: solid 3px white; + box-shadow: 0 5px 10px 0 rgba(0,0,0,0.2); + top: 15%; + right: 20px; + z-index: 2; +} + +#img_thumbnails { + width: 100%; + height: 55px; + margin: 3%; + overflow-x: scroll; + overflow-y: hidden; + display: block; + white-space: nowrap; + padding-bottom: 5%; + margin-bottom: 0; +} + +.imgthumb{ + width: 50; + border-radius: 8px; + height: 50; + box-shadow: 0px 2px 2px 2px #e2e2e2; + display: inline-block; + margin-right: 5px; + transition:0.2s; +} + +.select2-selection{ + border: none; + border: 1px solid #b5b5b5 !important; + border-radius: 7px; + min-height: 47px !important; + height: 47px; + font-size: 1.4em; + padding: 1%; + padding-left:1%; + overflow: scroll; + padding-bottom: 3% !important; +} + +.select2-dropdown{ + font-family: 'Montserrat'; + border: 2px solid #e2e2e2; + width: 100%; +} + +.select2-selection__choice{ + background-color:white !important; + border:None; + padding-bottom: 4px !important; + padding-top: 2px !important; + padding-right: 3px !important; + margin-top: 0px !important; +} +.select2-selection__choice__remove{ + border:None !important; +} + +.select2-search__field{ + height:100% !important; +} \ No newline at end of file