From 0efa18f9166403598b1cf04c74f0fa36a7042732 Mon Sep 17 00:00:00 2001 From: Bhavin Jawade Date: Wed, 23 Feb 2022 14:04:17 -0500 Subject: [PATCH] camera app added --- .DS_Store | Bin 0 -> 6148 bytes Camera-app/README.md | 2 + Camera-app/Untitled-1 | 15 ++ Camera-app/annotate.html | 72 ++++++ Camera-app/annotate.js | 286 +++++++++++++++++++++ Camera-app/app.js | 76 ++++++ Camera-app/app.py | 25 ++ Camera-app/draw.js | 119 +++++++++ Camera-app/fruits.txt | 412 ++++++++++++++++++++++++++++++ Camera-app/images/camera_icon.png | Bin 0 -> 4709 bytes Camera-app/index.html | 51 ++++ Camera-app/manifest.json | 34 +++ Camera-app/style.css | 224 ++++++++++++++++ 13 files changed, 1316 insertions(+) create mode 100644 .DS_Store create mode 100644 Camera-app/README.md create mode 100644 Camera-app/Untitled-1 create mode 100644 Camera-app/annotate.html create mode 100644 Camera-app/annotate.js create mode 100644 Camera-app/app.js create mode 100644 Camera-app/app.py create mode 100644 Camera-app/draw.js create mode 100644 Camera-app/fruits.txt create mode 100644 Camera-app/images/camera_icon.png create mode 100644 Camera-app/index.html create mode 100644 Camera-app/manifest.json create mode 100644 Camera-app/style.css diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6566c3bf56c2b3c800cf5cb7f059de6c60e37166 GIT binary patch literal 6148 zcmeHKO->sz7=2D68YL*orfQe7LfwFrHB=gCD%5q>2$D$%i1|}!`m>u&578rV4i3N} zP*2bUwC}S`m6;?c8!CjpFS4J<^WIo~&U_vNFh}!o59k7DvIsU>tX72Fm$DQ!-_s!) z`;2p3Vv0R{N3z7$4s}2scy12JyW7SoB4kLh`2NP9;w&1)*@z5D5Bn_d{@7qkQo<=> z4Ee5SnBz09EBu=ZzeDcGbN84ZhM3_BWA=PSTGpC373~(;*ZfVE$1y)D+!j8Nosc^t z?y}^_%g@IFH9r^TvQiUIdxI!Ta&jMHB`?YPeeY9q=k?^*$^Gpi1#7tDjk)>7X5)Vu z%+feZryP@67_V^5xhHllV@%33H^0ePT*d7&o4GsYibS|7>uSS_uE{(v{^qz~&X20A zU%RXDJ7lF??Fqhdj7L|${=TB+rN$FDApaIdv+Yo8bwC|Z2mU!A`5|Bt3_TVOZR%iU zj{w95yKS&79}A)hJcb?%hrGiuPD*rA + + + + + + + + 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 0000000000000000000000000000000000000000..1a28c7c8fab5468b8f62f408c107389548b309fe GIT binary patch literal 4709 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 literal 0 HcmV?d00001 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