Comparar commits

...

212 Commits

Autor SHA1 Mensagem Data
PythicCoder da7078eb3e Update README.md 2017-08-10 14:00:02 +03:00
PythicCoder 7902110697 Merge pull request #142 from CatalystCode/tf_pascalVOCSupport
Added pascal voc support for tensorflow
2017-08-10 13:53:47 +03:00
aribornstein 401a61e5c6 fixed spacing 2017-08-10 13:53:10 +03:00
aribornstein be33efcfae Tensorflow Support 2017-08-10 13:51:11 +03:00
Ari Bornstein 2154bb9b77 Added support for pascal voc (untested) 2017-08-09 13:12:04 +03:00
aribornstein 99f6c52e68 fixed spacing issue 2017-07-13 17:23:17 +03:00
aribornstein 21d0d5bbbc fixed anacondaPath bug 2017-07-13 17:22:25 +03:00
aribornstein 7331c584e2 added custom anaconda path support to cntk review 2017-07-13 16:44:35 +03:00
PythicCoder 690240ba74 Merge pull request #135 from CatalystCode/bug_fixes
Bug Fixes
2017-07-05 13:35:25 +03:00
aribornstein e20379e073 Bug Fixes
- Added support for evaluating python and brainscript fastrcnn models

- Fixed bug with image path display

- Enabled copy and paste on OSX

- Enabled go to last untagged frame

- Fixed export complete notification bug

- Added Ogg video support
2017-07-05 13:32:27 +03:00
PythicCoder 2f67b6cd16 Update README.md 2017-06-26 10:58:04 +03:00
Ari Bornstein 98a9708b3b Added file pickers to export flow to minimize typing 2017-06-26 09:37:51 +03:00
Ari Bornstein c4c1bd906d Merge branch 'master' of https://github.com/CatalystCode/VOTT 2017-06-26 09:19:00 +03:00
PythicCoder 45b01b7f7a Merge pull request #126 from CatalystCode/yolo_image_fix
Bug fixes

- Updated detection export interface to support custom size image export
- Added support for image extraction for yolo
- Added file selector to model review prompt
2017-06-25 13:10:59 +03:00
aribornstein 269a9098e5 Bug fixes
- Updated detection export interface to support custom size image export
- Added support for image extraction for yolo
- Added file selector to model review prompt
2017-06-25 13:08:00 +03:00
Ari Bornstein cc832c6207 Merge branch 'master' of https://github.com/CatalystCode/VOTT 2017-06-13 15:45:39 +03:00
PythicCoder 5050e00d66 Documentation for Label Names on Review Model 2017-06-13 10:58:26 +03:00
Ari Bornstein 93c3d098ad fixed image indexing and merge state 2017-06-07 13:37:09 +03:00
aribornstein 93d7cfa09f bad merge fixes part 1 2017-06-07 13:24:12 +03:00
PythicCoder 8a5263a2ea Added image directory tagging support
Poster support
2017-06-07 11:52:57 +03:00
PythicCoder 733e57850a Merge branch 'master' into posterSupport 2017-06-07 11:51:10 +03:00
PythicCoder b9ef38cc0f Merge branch 'master' into posterSupport 2017-06-07 11:48:55 +03:00
aribornstein 53ee46ae02 Merge branch 'aribornstein-posterSupport' 2017-06-07 11:34:42 +03:00
aribornstein 5e750fb94c fixed versioning 2017-06-07 11:34:17 +03:00
aribornstein 8e9ceeeaef haha 2017-06-07 10:28:24 +03:00
aribornstein 6990d6083c added image tagging anchor 2017-06-07 10:26:06 +03:00
aribornstein 6647390f1f updated doc 2017-06-07 10:21:57 +03:00
aribornstein 79683b5c34 updated image assests 2017-06-07 10:17:16 +03:00
aribornstein cea3aeb98b updated doc 2017-06-07 10:10:56 +03:00
aribornstein a4a2aed438 updated documentation 2017-06-07 10:08:00 +03:00
aribornstein abf5d416b1 sanatize white spaces from input tags 2017-06-05 11:22:25 +03:00
aribornstein d00dfb1db4 Added support for
- Viewing image filename
- Running model on image directory
2017-06-05 10:53:14 +03:00
aribornstein f85971c309 fixed model evaluation 2017-06-01 17:31:40 +03:00
aribornstein 48b0ef6286 added image index indicator for image tagging 2017-05-28 12:42:45 +03:00
aribornstein a6c3f9508e fixed scale by landscape bug 2017-05-25 13:23:57 +03:00
aribornstein b0588f8434 Added new loading page 2017-05-24 17:09:47 +03:00
aribornstein 0403d4d3c9 Added safeguard to tell if images were in directory 2017-05-24 13:39:52 +03:00
aribornstein 89d84a9b18 Added save support for image tagging 2017-05-24 13:13:05 +03:00
aribornstein 1da7c4dd45 Added image directory tagging support for vertical scale images
Todo
- Implement auto/save option for image directory tagging
- Notifiy if empty directory is tagged
- Add support for width scaling images
- Add rotation support
2017-05-24 09:48:24 +03:00
PythicCoder 4484c4f4f6 Merge pull request #118 from CatalystCode/exportFix
Added Features
2017-05-07 08:42:04 +03:00
aribornstein 028b075055 Added Features
- Updated cntk-rcnn-extension
- Added the ability to toggle scene change detection
- Add the ability to enable region copy
2017-05-03 09:47:23 +03:00
PythicCoder 75317e3616 Merge pull request #117 from CatalystCode/exportFix
Detection Model Bug Fixes
2017-04-26 18:09:54 +03:00
aribornstein 279cae7373 Detection Model Bug Fixes 2017-04-26 18:01:23 +03:00
PythicCoder 6cc3a39aa3 Merge pull request #114 from CatalystCode/exportFix
Fixed bug where export to cntk freezes if first frame has no tags
2017-04-25 12:44:12 +03:00
aribornstein 38fd98030d Fixed bug where export to cntk freezes if first frame has no tags 2017-04-25 12:43:15 +03:00
PythicCoder ae8b7bee61 Merge pull request #111 from CatalystCode/exportFix
Fixed test set generation code
2017-04-24 17:28:26 +03:00
aribornstein d2288e11de fixed export bug 2017-04-23 11:53:27 +03:00
aribornstein 74fbd2098d Fixed test set generation code 2017-04-23 11:34:18 +03:00
aribornstein 774c337ddd Added image support
Todo
- Fix Export scaling
- Test for bugs
2017-04-23 09:48:23 +03:00
PythicCoder ebf28feb92 Update README.md 2017-04-11 16:40:58 +03:00
aribornstein 5dca937c49 fixed aspect ratio to do
Fix scaling
2017-04-09 12:11:09 +03:00
PythicCoder f36f744c69 Merge pull request #105 from CatalystCode/yolo_ui
Object Detection Modular Support
- Organized Code
- Added modular support for additional object detection algorithms including YOLO
- Added some UI improvements for the home page and tagging job configuration plage
2017-04-05 11:53:04 +03:00
aribornstein 1e1ec33804 Made suggested changes
- Added display name to detection algorithm extensions

- Deprecated config file so that all detection algorithm extensions are self contained

- Optimized fisherYates shuffle

- Small ui tweaks with font
2017-04-05 11:31:38 +03:00
aribornstein 3dd2a1ad5a Made suggested changes
-Abstracted reviewer and exporter from DetectionAlgorithmManager

- Added hover on load video
2017-04-04 16:32:16 +03:00
aribornstein 0c1ff392fd fixed yolo 2017-04-03 17:57:59 +03:00
aribornstein 16a66809cd fixed yolo bug 2017-04-03 17:54:57 +03:00
Nadav Bar d7a695cb33 Addressed issue #106 2017-04-03 17:34:21 +03:00
aribornstein 804642234d Made most suggested changes
- Changed testset generator to use fisherYates

- made suggested optimizations

- todo
  Unbundle the exporter and reviewer from the manager class
2017-04-03 16:13:50 +03:00
aribornstein bfc6e662ca Output dir now defaults to same dir as assets 2017-04-03 11:08:50 +03:00
aribornstein 66a3b58b9b renamed cntk to cntkfastrcnn 2017-04-03 10:46:12 +03:00
aribornstein 2c8cdba0f8 replaced all writesync with write 2017-04-03 10:39:11 +03:00
aribornstein 651ce5b672 Made suggested changes
- Removed switch statement in framehandler in detection.js

- Made all cntk notifications generic

- Replaced manual path strings with path.join

- created canvasToJpg function

- added detectionAlgorithmsManager

- added detection.utils

- changed posFrameCount -> taggedFramesCount

- updated references from cntk to CNTK Fast-RCNN

- incorporated async each into the waterfalls
2017-04-02 19:06:09 +03:00
Ari Bornstein fa214ef5a4 removed hardcoded path 2017-03-29 16:51:09 +03:00
Ari Bornstein 75b809d7d1 Detection Bug Fixes
- fixed ipcMain bug that was causing multiple firings

- fixed a reference to self instead of this in videotagging control

- removed rimraf dependency

- added call back to review save frame

- fixed review mode
2017-03-29 16:49:14 +03:00
aribornstein 43bd60844c Export Bug Fixes
- Fixed exporting only of visited frames
- Removed depenency on rimraf
- Added support for exporting multiple videos to same format output directory
2017-03-29 13:25:00 +03:00
aribornstein ab75ff6ea5 Integrated DetectionManager
Todo

- Test and finish review integration
- UI Tweaks
2017-03-29 00:21:38 +03:00
aribornstein 68abe58277 Updates
- Implemented Object Detection Manager
- Deprecated local bootstrap.js

Todo
- Create videotagging-detection-extension module

- Integrate both YOLO and CNTK into the UI
2017-03-28 20:44:46 +03:00
PythicCoder b2d711ece5 Merge pull request #104 from CatalystCode/yolo
Yolo UI merge
2017-03-28 09:20:21 +03:00
PythicCoder 4a58f7c45f Merge branch 'yolo_ui' into yolo 2017-03-27 10:59:33 +03:00
PythicCoder 20160eba9c Merge pull request #102 from CatalystCode/uiupdates
UI updates

- Changed name to VOTT (Visual Object Tagging Tool)
- Optimized Configuration and Dialogs for Export and review
- Fixed export to cntk bug that was causing labels to be swapped with bounding boxes
2017-03-26 10:22:21 +03:00
PythicCoder b73dab7310 Update README.md 2017-03-26 10:19:44 +03:00
PythicCoder 8520f6a559 Update README.md 2017-03-26 10:18:54 +03:00
PythicCoder 9e83f9f516 Update README.md 2017-03-26 10:17:26 +03:00
PythicCoder 2b344cec0b Update README.md 2017-03-26 10:15:46 +03:00
aribornstein fba576c8bd Update Readme 2017-03-26 10:13:57 +03:00
PythicCoder 30f22bc939 Update README.md 2017-03-26 10:11:20 +03:00
aribornstein 09e5c4c233 update image asset 2017-03-26 10:09:54 +03:00
aribornstein d12ca0937d Merge branch 'uiupdates' of https://github.com/CatalystCode/CNTK-Video-Tagging-Tool into uiupdates 2017-03-26 10:08:01 +03:00
aribornstein 7b3e7c37f4 updated image asset 2017-03-26 10:07:33 +03:00
PythicCoder 91d188efd8 Update README.md 2017-03-26 10:06:38 +03:00
aribornstein 8e8e4c3c96 updated image assets 2017-03-26 10:06:09 +03:00
aribornstein f0c385dd8b updated readme 2017-03-26 09:58:43 +03:00
aribornstein 5fc8aaace4 Updated readme 2017-03-26 09:58:20 +03:00
PythicCoder 734abf3104 Update README.md 2017-03-26 09:34:24 +03:00
aribornstein 170470bca1 updated assets to vott 2017-03-26 09:33:21 +03:00
aribornstein 5ff0c94ba1 Renamed to visual object tagging tool 2017-03-26 09:28:58 +03:00
aribornstein 0fd5c2bb54 Added padding 2017-03-26 09:26:21 +03:00
Nadav Bar 4b2d5271d3 Merge pull request #101 from CatalystCode/yolo_int
Version with YOLO exports instead of CNTK
2017-03-26 08:58:29 +03:00
aribornstein 68da794580 fixed bug with switch 2017-03-24 00:20:09 +02:00
Nadav Bar d08a3d5560 Version with YOLO exports instead of CNTK 2017-03-23 20:59:19 +02:00
aribornstein cffc6468ed Fixed bugs stemming from shared popup window 2017-03-23 15:01:16 +02:00
aribornstein d9958b8298 Added Pop Up Configuration Support
Added Pop Up Configuration Support for:

- Review Model
- Export to cntk

Todo:
- Known bug alert doesn't disapear if model is not in correct location

- UI Design review need feedback on best practices for form
2017-03-23 14:19:50 +02:00
Nadav Bar a5b8418f17 Merge pull request #99 from CatalystCode/yolo_integration
Added package files
2017-03-23 11:20:50 +02:00
Nadav Bar e96b3cd4c0 Added package files 2017-03-23 11:20:07 +02:00
Nadav Bar 6b54aff06b Added working YOLO exporter and test 2017-03-23 11:01:45 +02:00
Nadav Bar 22bb7dfc66 Updated interface 2017-03-23 09:52:21 +02:00
Nadav Bar e80a3e9955 Updated interface and added partial implementation of YOLO 2017-03-23 09:21:08 +02:00
Nadav Bar 0ea7ca09f9 added documantation for review method 2017-03-22 16:15:26 +02:00
Nadav Bar 7137281d48 Removed cb param from init method 2017-03-22 15:33:48 +02:00
Nadav Bar a3a36dc2e6 arranged folder structure 2017-03-22 15:29:29 +02:00
Nadav Bar c41fa2f7df Added interface and moved to new directory 2017-03-22 15:27:20 +02:00
Nadav Bar 3ae90c647d Added skeleton for detector abstraction 2017-03-22 15:23:33 +02:00
aribornstein 3cc869524a Updated Config UI
- Updated review menu names
- Only prompt for export data on export
- Only prompt for review model on data
2017-03-21 16:40:43 +02:00
PythicCoder f4788bb7df Merge pull request #96 from sozercan/patch-1
Update README.md
2017-03-20 00:48:22 +02:00
Sertaç Özercan 1cd69df438 Update README.md 2017-03-19 11:24:04 -07:00
PythicCoder b98c2ababf Update README.md 2017-03-18 02:29:10 +02:00
PythicCoder a40939f7cd Merge pull request #95 from sozercan/master
📝 update readme
2017-03-18 02:17:02 +02:00
PythicCoder 59f42bb220 Merge branch 'master' into master 2017-03-18 02:16:54 +02:00
PythicCoder 8da13147fe Update README.md 2017-03-18 02:06:26 +02:00
aribornstein 097387ae0a updated image assets for npm 2017-03-18 02:05:34 +02:00
Sertaç Özercan b8ba83b330 📝 update readme 2017-03-17 17:02:22 -07:00
aribornstein cec934847e Fixed npm module 2017-03-18 01:58:59 +02:00
PythicCoder e0492c8cd2 Update README.md 2017-03-18 01:23:54 +02:00
aribornstein e4e472f28b added support for npm 2017-03-18 01:15:06 +02:00
aribornstein 925da69e02 updated package.json 2017-03-18 01:03:07 +02:00
PythicCoder 0cba9df9f3 Update README.md 2017-03-16 12:42:03 +02:00
aribornstein e2f12dc7f9 Fixed bug in cntk-config 2017-03-16 12:36:55 +02:00
aribornstein 6bb24f0f8a Updated to latest cntk-fastrcnn package 2017-03-16 12:31:29 +02:00
Nadav Bar a23a3ac322 Added dots at line ends 2017-03-16 09:23:25 +02:00
Nadav Bar 3399163387 Moved the CNTK path instructions to the CNTK part. 2017-03-16 09:22:33 +02:00
PythicCoder e8044496b7 Update README.md 2017-03-16 00:23:24 +02:00
aribornstein 7cb91aa2b2 Added tech editor changes to repo 2017-03-15 23:44:55 +02:00
PythicCoder ebafba7c10 Merge pull request #90 from CatalystCode/documentation
Updated Documentation
2017-03-15 19:48:54 +02:00
PythicCoder a3b2ad302e Update README.md 2017-03-15 18:17:29 +02:00
PythicCoder 9f7da7071f Update README.md 2017-03-15 18:16:26 +02:00
PythicCoder 2e8aff7e74 Update README.md 2017-03-15 18:11:48 +02:00
PythicCoder 0d38710ba7 Update README.md 2017-03-15 18:10:07 +02:00
PythicCoder 5ad5420ca9 Update README.md 2017-03-15 16:12:02 +02:00
PythicCoder ddf8ecb6a0 Update README.md 2017-03-15 16:09:52 +02:00
PythicCoder 66f4a5d95e Update README.md 2017-03-15 16:08:40 +02:00
PythicCoder d3e0c8db83 Update README.md 2017-03-15 16:08:17 +02:00
PythicCoder 2acc93107b Update README.md 2017-03-15 16:05:39 +02:00
PythicCoder a659f06d24 Update README.md 2017-03-15 16:04:26 +02:00
aribornstein 1687e29742 Removed point 2017-03-15 15:59:52 +02:00
PythicCoder be416f7e0e Update README.md 2017-03-15 15:53:37 +02:00
PythicCoder 6a15844bcb Update README.md 2017-03-15 15:52:03 +02:00
aribornstein c458f598a3 Merge branch 'documentation' of https://github.com/CatalystCode/CNTK-Object-Recognizer-Video-Tagging-Tool into documentation 2017-03-15 15:49:38 +02:00
aribornstein 9cf2344d80 added endtoend graphic 2017-03-15 15:49:32 +02:00
PythicCoder d6b828284d Update README.md 2017-03-15 15:41:08 +02:00
PythicCoder d777697a94 Update README.md 2017-03-15 15:38:32 +02:00
aribornstein 4cf1ba6375 updated readme 2017-03-15 15:36:07 +02:00
PythicCoder a9e8c862a8 Update README.md 2017-03-15 15:32:41 +02:00
PythicCoder f63da01efa Update README.md 2017-03-15 15:26:04 +02:00
PythicCoder 5a56478d92 Update README.md 2017-03-15 15:21:37 +02:00
aribornstein f46749ef73 added icons for tagging 2017-03-15 15:18:29 +02:00
PythicCoder 59ce75a465 Update README.md 2017-03-15 14:53:23 +02:00
aribornstein c8bb6b93de removed svgs 2017-03-15 13:46:02 +02:00
aribornstein 71e55f8887 added svgs and tinyjpg images 2017-03-15 13:43:03 +02:00
PythicCoder 655f3a892c Update README.md 2017-03-15 13:35:53 +02:00
PythicCoder 1ca29b647a Update README.md 2017-03-15 13:34:51 +02:00
PythicCoder 9fad962f56 Update README.md 2017-03-15 12:01:15 +02:00
PythicCoder 82e0e4e5bb Merge pull request #93 from CatalystCode/testimagesupport
#92 Added support for auto generation of test images
2017-03-15 11:55:28 +02:00
aribornstein fc6f575c3e added support for test images
defaults to 20 percent of tagged images
2017-03-15 11:53:42 +02:00
aribornstein 220ea736c3 added support for testImages 2017-03-15 11:48:59 +02:00
PythicCoder b5dd99c10d Update README.md 2017-03-15 11:10:45 +02:00
PythicCoder a0aae576dc Update README.md 2017-03-15 11:10:21 +02:00
PythicCoder 43acad0776 Update README.md 2017-03-15 11:09:48 +02:00
PythicCoder 896c70daa0 Update README.md 2017-03-15 11:09:22 +02:00
PythicCoder 5622bd855f Update README.md 2017-03-15 11:05:37 +02:00
PythicCoder 2c31b9d096 finished requested changes 2017-03-15 11:00:43 +02:00
aribornstein 0bbccc0800 update load asset 2017-03-15 10:59:01 +02:00
PythicCoder 44e4871ad4 Delete 2_load.jpg 2017-03-15 10:58:18 +02:00
PythicCoder 4f3371486c Update README.md 2017-03-15 10:53:48 +02:00
PythicCoder 9cddc7e813 Update README.md 2017-03-15 10:51:20 +02:00
aribornstein c0e2ee9cbe updated tagging job assets 2017-03-15 10:46:54 +02:00
PythicCoder 2addd9817c Delete 4_Tagging_Job.jpg 2017-03-15 10:42:05 +02:00
PythicCoder 7f8a7a8358 Delete 5_Export.jpg 2017-03-15 10:41:36 +02:00
aribornstein ae53f31cf8 updated tagging job 2017-03-15 10:39:50 +02:00
PythicCoder 3aaf662195 Delete 4_Tagging_Job.jpg 2017-03-15 10:36:24 +02:00
PythicCoder 1f960dbb7b Update README.md 2017-03-15 10:31:21 +02:00
PythicCoder 1424bc5d8a Update README.md 2017-03-15 10:23:06 +02:00
aribornstein e5cb1b7165 force image update 2017-03-15 10:18:11 +02:00
PythicCoder 6a14ae75ce Delete 3_Job_Configuration.jpg 2017-03-15 10:16:20 +02:00
PythicCoder 8e04e9617a Update README.md 2017-03-15 10:15:31 +02:00
PythicCoder 84bf791b30 Update README.md 2017-03-15 10:12:20 +02:00
aribornstein 8cb12e8e8a updated job configuration image 2017-03-15 10:08:37 +02:00
PythicCoder 58b1329c80 Made Suggested Edits 2017-03-15 10:03:28 +02:00
PythicCoder 3859074b84 Update README.md 2017-03-14 15:06:32 +02:00
PythicCoder 8f7e814869 Update README.md 2017-03-14 14:07:21 +02:00
PythicCoder 8980fc6729 Update README.md 2017-03-14 13:43:26 +02:00
PythicCoder 9245d6c274 Update README.md 2017-03-14 13:42:32 +02:00
PythicCoder 15e45f806d Update README.md 2017-03-14 12:07:38 +02:00
aribornstein 09c4804991 fixed job configuration asset 2017-03-14 11:45:56 +02:00
PythicCoder 17521635ba Update README.md 2017-03-14 11:44:16 +02:00
PythicCoder 2794ecb718 Update README.md 2017-03-14 11:28:26 +02:00
PythicCoder 7a57341fa4 Update README.md 2017-03-14 11:25:11 +02:00
aribornstein 5332a160a4 updated assets 2017-03-14 11:19:50 +02:00
PythicCoder f9502b5615 Update README.md 2017-03-14 10:57:55 +02:00
aribornstein d77831d212 updated documention draft 1 2017-03-14 10:31:56 +02:00
PythicCoder 3c93fee22c Merge pull request #89 from CatalystCode/clean_src
Cntk integration patches
2017-03-13 13:33:47 +02:00
aribornstein a2bd29bf41 Cntk integration patches 2017-03-13 13:32:35 +02:00
PythicCoder 91fa61c56d Merge pull request #88 from CatalystCode/clean_src
added cntkpath configuration
2017-03-13 09:59:32 +02:00
aribornstein f13027dfa9 added cntkpath configuration 2017-03-13 09:58:48 +02:00
PythicCoder 60eadb75b1 Merge pull request #86 from CatalystCode/clean_src
Cleaned root src directory and abstracted the export to cntk/ and tracking functionalities
2017-03-12 18:58:27 +02:00
aribornstein 7a71702dc9 fixed cntk review bug 2017-03-12 17:24:24 +02:00
aribornstein b639048bef Keyboard shortcut fix
fixed bug where keyboard shortcuts were getting the way of the configuration screen
2017-03-12 17:21:09 +02:00
aribornstein a9a6170adb cntk review bugfix 2017-03-12 17:07:58 +02:00
aribornstein 8e6344b2c0 Moved icon to images directory 2017-03-12 15:02:21 +02:00
aribornstein 3cc8791e7b Abstracted videotagging tracking code 2017-03-12 14:53:06 +02:00
aribornstein daa5b1d7e9 abstracted export to cntk 2017-03-12 13:34:52 +02:00
PythicCoder 0d794aeeb8 Update README.md 2017-03-11 17:12:28 +02:00
PythicCoder 81d81d380f Update README.md 2017-03-11 17:11:26 +02:00
PythicCoder efff6928d5 Update README.md 2017-03-11 14:51:09 +02:00
PythicCoder 075291c3f3 Merge pull request #85 from CatalystCode/clean_src
Cleaned Root Directory 
Cleaned root directory, moved src to new src folder and removed duplicate sample video
2017-03-11 14:47:37 +02:00
aribornstein 848d1343ad Removed duplicate sample video 2017-03-11 14:44:04 +02:00
aribornstein 27bef9a38f cleaned src directory 2017-03-11 14:38:48 +02:00
aribornstein c80b012e0a clean directory 2017-03-11 14:10:20 +02:00
PythicCoder 9138ee7a31 Update README.md 2017-03-11 14:03:42 +02:00
PythicCoder 89dd574443 Update README.md 2017-03-11 13:44:46 +02:00
PythicCoder 126fa9bace Update README.md 2017-03-11 13:42:31 +02:00
PythicCoder 616a5d50c7 Update README.md 2017-03-11 13:34:44 +02:00
PythicCoder c8a33c4e72 Update README.md 2017-03-11 13:33:44 +02:00
1420 arquivos alterados com 2943 adições e 880 exclusões
+203 -2
Ver Arquivo
@@ -1,2 +1,203 @@
# offline-video-tagger
An offline port of the video-tagging-tool for electron.
# VoTT: Visual Object Tagging Tool
This tool provides end to end support for generating datasets and validating object detection models from video and image assets.
### End to End Object Detection Pipeline:
![Pipeline: tag video, export tags to CNTK, train model, run model on a new video, validate model suggestions and fix errors, return to export tags](media/detectioninabox.jpg)
The tool supports the following **features**:
- The ability to tag and annotate Image Directories or Stand alone videos.
- Computer-assisted tagging and tracking of objects in videos using the [Camshift tracking algorithm](http://opencv.jp/opencv-1.0.0_org/docs/papers/camshift.pdf).
- Exporting tags and assets to CNTK , Tensorflow (PascalVOC) or YOLO format for training an object detection model.
- Running and validating a trained CNTK object detection model on new videos to generate stronger models.
## Table of Contents
- [Installation](#installation)
- [Tagging a Video](#tagging-a-video)
- [Tagging an Image Directory](#tagging-an-image-directory)
- [Reviewing and Improving an Object Detection Model](#reviewing-and-improving-an-object-detection-model)
- [Upcoming Features](#upcoming-features)
- [How to Contribute](#how-to-contribute)
---
## Installation
### Installing the Visual Object Tagging Tool
1. Download and extract the app [release package](https://github.com/CatalystCode/CNTK-Object-Detection-Video-Tagging-Tool/releases)
2. Run the app by launching the "VOTT" executable which will be located inside the unzipped folder.
### Installing CNTK with the FRCNN Prerequisites for Reviewing Model
*Please note that installation of **CNTK and FAST-RCNN dependencies** are **optional for tagging** and are **only required for CNTK model review and training**.*
1. Install [CNTK](https://github.com/Microsoft/CNTK/wiki/Setup-CNTK-on-your-machine) (*Note: currently the tool only supports the full installation method (non pip) of CNTK*).
2. Follow the setup instructions of the [CNTK Fast-RCNN tutorial](https://github.com/Microsoft/CNTK/wiki/Object-Detection-using-Fast-R-CNN#setup) (*Note: Fast-RCNN currently only supports Linux python version 3.4 and not 3.5*).
3. Configure `CNTK-Config.json` (which resides in the '\resources\app' directory of the tagging tool) with the following properties to enable the model review feature:
```json
{
"cntkPath" : "{CNTK Path default is c:/local/cntk}",
}
```
## Tagging a Video
1. Select the option to tag a video
![](media/video-option.jpg)
2. Load an MP4 video file either by dragging it into the app or clicking on and selecting it.
![](media/2_load.jpg)
3. Configure the tagging job and specify the settings in the screenshot below:
![](media/3_Job_Configuration.jpg)
**Frame Extraction Rate**: number of frames to tag per second of video<br>
**Tagging Region Type**: type of bounding box for tagging regions<br>
- *Rectangle*: tag bounding boxes of any dimension
- *Square*: tag bounding boxes of auto-fixed dimensions
**Suggested Region Method**: how to suggest regions for next frame<br>
- *Tracking*: Use camshift to track tagged regions in next frame
- *Copy Last Frame*: Copy all regions to the next frame.
**Enable Scene Change Detection**: Detect scene changes to prevent false positives when tracking. (Note this option is slightly slower)
**Labels**: labels of the tagged regions (e.g. `Cat`, `Dog`, `Horse`, `Person`)<br>
4. Tag the video frame by frame
![](media/4_Tagging_Job.jpg)
**Tagging**: click and drag a bounding box around the desired area, then move or resize the region until it fits the object
- Selected regions appear as red ![red](https://placehold.it/15/f03c15/000000?text=+) and unselected regions will appear as blue ![#1589F0](https://placehold.it/15/1589F0/000000?text=+).
- Assign a tag to a region by clicking on it and selecting the desired tag from the labeling toolbar at the bottom of the tagging control
- Click the ![cleartags](media/cleartags.png) button to clear all tags on a given frame
**Navigation**: users can navigate between video frames by using the ![prev-nxt](media/prev-next.png) buttons, the left/right arrow keys, or the video skip bar
- Tags are auto-saved each time a frame is changed
**Tracking**: new regions are tracked by default until a given scene changes.
- Since the [camshift algorithm](http://opencv.jp/opencv-1.0.0_org/docs/papers/camshift.pdf) has some known limitations, you can disable tracking for certain sets of frames. To toggle tracking *on* and *off* use the file menu setting, or the keyboard shortcut Ctrl/Cmd + T.
5. Export video Tags using the Object Detection Menu or Ctrl/Cmd + E
![]( media/5_Export.jpg)
*Note on exporting: the tool reserves a random 20% sample of the tagged frames as a test set.*
Specify the following export configuration settings:
![]( media/5a_Export.jpg)
- **Export Format**: What framework to export to defaults to *CNTK*<br>
- **Export Frames Until**: how far into the video the export operation will proceed<br>
     - *Last Tagged Region*: exports frames up until the last frame containing tags
      - *Last Visited Frame*: exports frames up until the last frame that the user explicitly visited
      - *Last Frame*: exports all video frames<br>
- **Output directory**: directory path for exporting training data<br>
    
---
## Tagging an Image Directory
1. Select the option to tag an image directory
![](media/image-option.jpg)
2. Load an image directory by selecting it.
![](media/2_load.jpg)
3. Configure the tagging job and specify the settings in the screenshot below:
![](media/3_image_Job_Configuration.jpg)
**Frame Extraction Rate**: number of frames to tag per second of video<br>
**Tagging Region Type**: type of bounding box for tagging regions<br>
- *Rectangle*: tag bounding boxes of any dimension
- *Square*: tag bounding boxes of auto-fixed dimensions
**Labels**: labels of the tagged regions (e.g. `Cat`, `Dog`, `Horse`, `Person`)<br>
4. Tag each Image
![](media/4_image_Tagging_Job.jpg)
**Tagging**: click and drag a bounding box around the desired area, then move or resize the region until it fits the object
- Selected regions appear as red ![red](https://placehold.it/15/f03c15/000000?text=+) and unselected regions will appear as blue ![#1589F0](https://placehold.it/15/1589F0/000000?text=+).
- Assign a tag to a region by clicking on it and selecting the desired tag from the labeling toolbar at the bottom of the tagging control
- Click the ![cleartags](media/cleartags.png) button to clear all tags on a given frame
**Navigation**: users can navigate between video frames by using the ![prev-nxt](media/prev-next.png) buttons, the left/right arrow keys, or the video skip bar
- Tags are auto-saved each time a frame is changed
5. Export Image directory tags Tags using the Object Detection Menu or Ctrl/Cmd + E
![]( media/5_image_Export.jpg)
*Note on exporting: the tool reserves a random 20% sample of the tagged frames as a test set.*
Specify the following export configuration settings:
![]( media/5a_Export.jpg)
- **Export Format**: What framework to export to defaults to *CNTK*<br>
- **Export Frames Until**: how far into the video the export operation will proceed<br>
     - *Last Tagged Region*: exports frames up until the last frame containing tags
      - *Last Visited Frame*: exports frames up until the last frame that the user explicitly visited
      - *Last Frame*: exports all video frames<br>
- **Output directory**: directory path for exporting training data<br>
    
---
## Reviewing and Improving an Object Detection Model
1. Train model with [Object Detection using FastRCNN](https://github.com/Microsoft/CNTK/wiki/Object-Detection-using-Fast-R-CNN#train-on-your-own-data)<br> *Note: the data is already in CNTK format, so you do not have to run `C1_DrawBboxesOnImages.py` or `C2_AssignLabelsToBboxes.py`*
2. Since CNTK does not embed the names of the classes in the model, on default, the module returns non descriptive names for the classes, e.g. "class_1", "class_2".Place a JSON file named "model.json" in the same directory of the Fast-RCNN model file with the the correct tag labels. Format the json file as follows with your own class names:
```json
{
"classes" : {
"background" : 0,
"human" : 1,
"cat" : 2,
"dog" : 3
}
}
```
3. Load a new asset that the model has not been trained on
4. Configure a new or load a previous tagging job
4. Apply model to new asset using Ctrl/Cmd + R
5. Specify a model path and temporary output directory<br>
![](media/6_Review.jpg)
6. When the model finishes processing, validate tags, re-export and retrain it
7. Repeat step 1 on new assets until the model performance is satisfactory
## Supporting additonal object detection Export and Review formats.
In the latest release we provide support for [Export and Review formats](https://github.com/CatalystCode/VOTT/tree/master/src/lib/detection_algorithms). To add a new object detection format, copy the interface folder and use the Yolo and CNTK implementations as reference.
## Upcoming Features
- Tagging project management
-----------
## How to Contribute
You are welcome to send us any bugs you may find, suggestions, or any other comments.
Before sending anything, please go over the repository issues list, just to make sure that it isn't already there.
You are more than welcome to fork this repository and send us a pull request if you feel that what you've done should be included.
-89
Ver Arquivo
@@ -1,89 +0,0 @@
<!--
Demo html page for an example of hosting the
video-tagging control.
-->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>Video Tagging Tool</title>
<!-- Insert this line above script imports for jquery -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="./bower_components/webcomponentsjs/webcomponents.min.js"></script>
<link rel="import" href="./bower_components/video-tagging/video-tagging.html">
<script src="./public/js/bootstrap.min.js"></script>
<script src="./public/js/bootstrap-tagsinput.min.js"></script>
<script src="./public/js/camshift.js"></script>
<script src="./public/js/scene-change-detector.js"></script>
<script src="./index.js"></script>
<link rel="stylesheet" href="./public/css/bootstrap-tagsinput.css" />
<link rel="stylesheet" href="./public/css/styles.css">
</head>
<body>
<div id="container">
<div id ='load-message' onclick="fileSelected();">
<div id = "load-text"><h2>Please <b>Drag in</b> or <b>Click</b> to load a video for tagging.</h2></div>
<img id="vidImage" src ="./public/images/Wikiversity-Mooc-Icon-Video.svg.png" ></img>
</div>
<div id ='load-form-container' style ="display: none">
<h2>Tagging Job Configuration</h2>
<div class="form-group" id="framerateGroup">
<label for="exampleTextarea" title="(How many frames to extract per a second of video!)">Frame Extraction Rate (frames per a video second)</label>
<input id="framerate" type="number" min="1" max="60" value="1" maxlength="3" size="3" class="form-control" />
</div>
<div class="form-group">
<label for="exampleTextarea" title="(Type of region selector to tag frames)">Region Type</label>
<select id="regiontype" class="form-control" id="text" onchange="checkPointRegion();">
<option selected="selected">Rectangle</option>
<option>Point</option>
<option>Square</option>
</select>
</div>
<div class="regionGroup">
<div class="form-group" id="regionPointGroup" style ="display: none">
<label for="exampleTextarea" title="(Region Size for point selector!)">Point Region Size</label>
<input class="form-control" type="text" value="25" id="regionsize"/>
</div>
</div>
<div class="form-group">
<label for="exampleTextarea" title="(Which frame to Export to.)">Export Until: </label>
<select id="exportTo" class="form-control" id="text" >
<option value="tagged" selected="selected">Last Tagged Region</option>
<option value="visited">Last Visited Frame</option>
<option value="last">Last Frame</option>
</select>
</div>
<div class="form-group">
<label for="Out"> Output Path</label>
<input id="output" class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Model"> Model Path</label>
<input id="model" class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Tags"> Labels (Required)</label>
<input id="inputtags" class="form-control" type="text" data-role="tagsinput" required/>
</div>
<div id="loadButton" class="btn btn-primary">Continue</div>
</div>
<div id='video-tagging-container' style="display: none">
<video-tagging id='video-tagging' ></video-tagging>
</div>
</div>
</body>
</html>
-617
Ver Arquivo
@@ -1,617 +0,0 @@
const remote = require('electron').remote;
const basepath = remote.app.getAppPath();
const dialog = remote.require('electron').dialog;
const pathJS = require('path');
const fs = require('fs');
const rimraf = require('rimraf');
const cntkModel= require('cntk-fastrcnn');
const cntkDefaultPath = 'c:/local/cntk';
const ipcRenderer = require('electron').ipcRenderer;
var supertrackingFrameRate = 10;
var trackingEnabled = true;
var visitedFrames, //keep track of the visited frames
videotagging;
//ipc rendering
ipcRenderer.on('openVideo', (event, message) => {
fileSelected();
});
ipcRenderer.on('saveVideo', (event, message) => {
save();
let notification = new Notification('Offline Video Tagger', {
body: 'Successfully saved metadata in ' + `${videotagging.src}.json`
});
});
ipcRenderer.on('exportCNTK', (event, message) => {
exportCNTK();
});
ipcRenderer.on('reviewCNTK', (event, message) => {
if (fs.existsSync(cntkDefaultPath)) {
var modelLocation = $('#model').val();
if (fs.existsSync(modelLocation)) {
reviewCNTK();
} else {
alert(`No model found! Please make sure you put your model in the following directory: ${modelLocation}`)
}
} else {
alert("This feature isn't supported by your system please check your CNTK configuration and try again later.");
}
});
ipcRenderer.on('toggleTracking', (event, message) => {
$('#video-tagging').off("stepFwdClicked-BeforeStep");
if (trackingEnabled) {
$('#video-tagging').off("stepFwdClicked-AfterStep");
//add event to prevent non tracked regions from giving suggestions
$('#video-tagging').on("stepFwdClicked-BeforeStep", () => {
save();
var regionCount = $('.regionCanvas').length;
if (regionCount) {
var curFrame = videotagging.getCurrentFrame();
$.map($('.regionCanvas'), (regionCanvas, i) => {
//get regionId
for (regInd = 0; regInd < videotagging.frames[curFrame].length; regInd++) {
if (videotagging.frames[curFrame][regInd].name = regionCanvas.id) {
videotagging.frames[curFrame][regInd].blockSuggest = true;
}
}
});
}
});
} else {
videotagging.video.addEventListener("canplay", initRegionTracking);
}
trackingEnabled = !trackingEnabled;
});
//drag and drop support
document.addEventListener('drop', (e) => {
e.preventDefault();
e.stopPropagation();
if (e.dataTransfer.files[0].type == "video/mp4") {
fileSelected(e.dataTransfer.files[0]);
}
return false;
});
document.addEventListener('dragover', (e) => {
e.preventDefault();
if (e.dataTransfer.files[0].type == "video/mp4") {
e.dataTransfer.dropEffect = "copy";
}
e.stopPropagation();
});
document.addEventListener('dragstart', (e) => {
e.preventDefault();
let file = e.dataTransfer.files[0];
if (file && file.type == "video/mp4") {
e.dataTransfer.effectAllowed = "copy";
}
e.stopPropagation();
});
// stop zooming
document.addEventListener('mousewheel', (e) => {
if(e.ctrlKey) {
e.preventDefault();
}
});
//adds a loading animation to the tagger
function addLoader() {
if(!$('.loader').length) {
$("<div class=\"loader\"></div>").appendTo($("#videoWrapper"));
}
}
//managed the visited frames
function updateVisitedFrames(){
visitedFrames.add(videotagging.getCurrentFrame());
}
function checkPointRegion() {
if ($('#regiontype').val() != "Point") {
$('#regionPointGroup').hide();
} else {
$('#regionPointGroup').show();
}
}
//load logic
function fileSelected(path) {
$('#load-message').hide();
if (path) { //checking if a video is dropped
let pathName = path.path;
openPath(pathName);
} else { // showing system open dialog
dialog.showOpenDialog({
filters: [{ name: 'Videos', extensions: ['mp4']}],
properties: ['openFile']
},
function (pathName) {
if (pathName) openPath(pathName[0]);
else $('#load-message').show();
});
}
function openPath(pathName) {
var config;
// show configuration
$('#load-message').hide();
$('#video-tagging-container').hide()
$('#load-form-container').show();
$('#framerateGroup').show();
//set title indicator
$('title').text(`Video Tagging Job Configuration: ${pathJS.basename(pathName, pathJS.extname(pathName))}`);
$('#inputtags').tagsinput('removeAll');//remove all previous tag labels
$('#output').val(`${basepath}/cntk`);
$('#model').val(`${basepath}/cntk/Fast-RCNN.model`);
try {
config = require(`${pathName}.json`);
//restore tags
$('#inputtags').val(config.inputTags);
config.inputTags.split(",").forEach( tag => {
$("#inputtags").tagsinput('add',tag);
});
} catch (e) {
console.log(`Error loading save file ${e.message}`);
}
// REPLACE implementation, use jQuery to remove all event handlers on loadbutton
document.getElementById('loadButton').parentNode.replaceChild(document.getElementById('loadButton').cloneNode(true), document.getElementById('loadButton'));
document.getElementById('loadButton').addEventListener('click', loadTagger);
function loadTagger (e) {
if(framerate.validity.valid && inputtags.validity.valid) {
$('.bootstrap-tagsinput').last().removeClass( "invalid" );
$('title').text(`Video Tagging Job: ${pathJS.basename(pathName, pathJS.extname(pathName))}`); //set title indicator
videotagging = document.getElementById('video-tagging'); //find out why jquery doesn't play nice with polymer
videotagging.regiontype = $('#regiontype').val();
videotagging.multiregions = 1;
videotagging.regionsize = $('#regionsize').val();
videotagging.inputtagsarray = $('#inputtags').val().split(',');
videotagging.video.currentTime = 0;
videotagging.framerate = $('#framerate').val();
if (config) {
videotagging.inputframes = config.frames;
visitedFrames = new Set(config.visitedFrames);
} else {
videotagging.inputframes = {};
visitedFrames = new Set();
}
videotagging.src = ''; // ensures reload if user opens same video
videotagging.src = pathName;
//set start time
videotagging.video.oncanplay = function (){
videotagging.videoStartTime = videotagging.video.currentTime;
videotagging.video.oncanplay = undefined;
}
//track visited frames
videotagging.video.removeEventListener("canplay", updateVisitedFrames); //remove old listener
videotagging.video.addEventListener("canplay",updateVisitedFrames);
//init region tracking
videotagging.video.addEventListener("canplay", initRegionTracking);
$('#load-form-container').hide();
$('#video-tagging-container').show();
ipcRenderer.send('setFilePath', pathName);
} else {
$('.bootstrap-tagsinput').last().addClass( "invalid" );
}
}
}
}
//saves current video to config
function save() {
var saveObject = {
"frames" : videotagging.frames,
"inputTags": $('#inputtags').val(),
"exportTo": $('#exportTo').val(),
"visitedFrames": Array.from(visitedFrames),
};
fs.writeFileSync(`${videotagging.src}.json`, JSON.stringify(saveObject));
}
//maps every frame in the video to an imageCanvas
function mapVideo(exportUntil, frameHandler) {
return new Promise((resolve, reject) => {
//init canvas buffer
var frameCanvas = document.createElement("canvas");
frameCanvas.width = videotagging.video.videoWidth;
frameCanvas.height = videotagging.video.videoHeight;
var canvasContext = frameCanvas.getContext("2d");
// start exporting frames using the canplay eventListener
videotagging.video.removeEventListener("canplay", updateVisitedFrames); //stop recording frame movment
videotagging.video.addEventListener("canplay", iterateFrames);
videotagging.video.currentTime = 0;
videotagging.playingCallback();
function iterateFrames() {
var frameId = videotagging.getCurrentFrame();
var isLastFrame;
switch(exportUntil) {
case "tagged":
isLastFrame = (!Object.keys(videotagging.frames).length) || (frameId >= parseInt(Object.keys(videotagging.frames)[Object.keys(videotagging.frames).length-1]));
break;
case "visited":
var lastVisitedFrameId = Math.max.apply(Math, Array.from(visitedFrames));
isLastFrame = (frameId >= lastVisitedFrameId);
break;
case "last":
isLastFrame = (videotagging.video.currentTime >= videotagging.video.duration);
break;
}
if (isLastFrame) {
videotagging.video.removeEventListener("canplay", iterateFrames);
videotagging.video.addEventListener("canplay", updateVisitedFrames);
resolve();
}
frameHandler(frameId, frameCanvas, canvasContext);
if (!isLastFrame) {
videotagging.stepFwdClicked(false);
}
}
});
}
//exports frames to cntk format for model training
function exportCNTK() {
addLoader();
/* create constants for all the paths with meaningful names*/
//make sure paths exist
var exportPath = $('#output').val();
if (!fs.existsSync(`${exportPath}`)) fs.mkdirSync(`${exportPath}`);
var framesPath = `${exportPath}/${pathJS.basename(videotagging.src, pathJS.extname(videotagging.src))}_frames`;
//clear past directory
rimraf(framesPath, () => {
fs.mkdirSync(framesPath);
fs.mkdirSync(`${framesPath}/positive`);
fs.mkdirSync(`${framesPath}/negative`);
mapVideo($('#exportTo').val(), exportFrame).then(() => {
$(".loader").remove();
let notification = new Notification('Offline Video Tagger', {
body: 'Successfully exported CNTK files.'
});
})
});
function exportFrame(frameId, frameCanvas, canvasContext) {
//set default writepath to the negative folder
var writePath = `${framesPath}/negative/${pathJS.basename(videotagging.src, pathJS.extname(videotagging.src))}_frame_${frameId}.jpg`; //defaults to negative
var positiveWritePath = `${framesPath}/positive/${pathJS.basename(videotagging.src, pathJS.extname(videotagging.src))}_frame_${frameId}.jpg`;
//If frame contains tags generate the metadata and save it in the positive directory
var frameIsTagged = videotagging.frames.hasOwnProperty(frameId) && (videotagging.frames[frameId].length);
if (frameIsTagged && (videotagging.getUnlabeledRegionTags(frameId).length != videotagging.frames[frameId].length)) {
//genereate metadata from tags
var frameBBoxes = "",
frameLabels = "";
videotagging.frames[frameId].map( (tag) => {
if (!tag.tags[tag.tags.length-1]) {
return console.log(`frame ${frameId} region ${tag.name} has no label`);
}
var stanW = videotagging.video.videoWidth/tag.width;
var stanH = videotagging.video.videoHeight/tag.height;
frameBBoxes += `${tag.tags[tag.tags.length-1]}\n`;
frameLabels += `${parseInt(tag.x1 * stanW)}\t${parseInt(tag.y1 * stanH)}\t${parseInt(tag.x2 * stanW)}\t${parseInt(tag.y2 * stanH)}\n`;
});
if (frameBBoxes == "" || frameLabels == "") return;
fs.writeFileSync(positiveWritePath.replace('.jpg', '.bboxes.labels.tsv'), frameLabels, (err) => {console.error(err)});
fs.writeFileSync(positiveWritePath.replace('.jpg', '.bboxes.tsv'), frameBBoxes, (err) => {console.error(err)});
writePath = positiveWritePath; // set write path to positve write path
}
//draw the frame to the canvas
canvasContext.drawImage(videotagging.video, 0, 0);
var data = frameCanvas.toDataURL('image/jpeg').replace(/^data:image\/\w+;base64,/, ""); // strip off the data: url prefix to get just the base64-encoded bytes http://stackoverflow.com/questions/5867534/how-to-save-canvas-data-to-file
var buf = new Buffer(data, 'base64');
//write canvas to file and change frame
console.log('saving file', writePath);
if (writePath.includes("negative") && !visitedFrames.has(frameId)) return; //only write visited frames
fs.writeFileSync(writePath, buf);
}
}
//allows user to review cntk suggestions on a video
function reviewCNTK() {
addLoader();
//check if an export directory for the current model exists
var exportPath = $('#output').val();
if (!fs.existsSync(`${exportPath}`)) fs.mkdirSync(`${exportPath}`);
var reviewPath = `${exportPath}/${pathJS.basename(videotagging.src, pathJS.extname(videotagging.src))}_review`;
//if the export directory does not exist create it and export all the frames then review
if (!fs.existsSync(reviewPath)) {
fs.mkdirSync(reviewPath);
mapVideo("last", saveFrame).then(review);
} else {
review();
}
function review() {
//run the model on the reviewPath directory
model = new cntkModel.CNTKFRCNNModel({cntkModelPath : $('#model').val(), verbose : true});
var modelTagsPromise = new Promise((resolve, reject) => {
model.evaluateDirectory(reviewPath, (err, res) => {
if (err) {
console.info(err);
reject();
}
resolve(res);
});
});
modelTagsPromise.then( (modelTags) => {
videotagging.video.removeEventListener("canplay", initRegionTracking); //remove region tracking listener
$('#video-tagging').off("stepFwdClicked-BeforeStep");
$('#video-tagging').off("stepFwdClicked-AfterStep");
videotagging.frames=[];
videotagging.optionalTags.createTagControls(Object.keys(modelTags.classes));
//Create regions based on the provided modelTags
Object.keys(modelTags.frames).map( (pathId) => {
var frameImage = new Image();
frameImage.src = `${reviewPath}\\${pathId}`;
frameImage.onload = loadFrameRegions;
function loadFrameRegions() {
var imageWidth = this.width;
var imageHeight = this.height;
frameId = pathId.replace(".jpg", "");//remove.jpg
videotagging.frames[frameId] = [];
modelTags.frames[pathId].regions.forEach( (region) => {
videotagging.frames[frameId].push({
x1:region.x1,
y1:region.y1,
x2:region.x2,
y2:region.y2,
id:videotagging.uniqueTagId++,
width:imageWidth,
height:imageHeight,
type:videotagging.regiontype,
tags:Object.keys(modelTags.classes).filter( (key) => {return modelTags.classes[key] === region.class }),
name:(videotagging.frames[frameId].length + 1)
});
});
}
});
videotagging.showAllRegions();
//cleanup and notify
$(".loader").remove();
videotagging.video.currentTime = 0;
videotagging.playingCallback();
let notification = new Notification('Offline Video Tagger', { body: 'Model Ready For Review.' });
});
}
function saveFrame(frameId, fCanvas, canvasContext){
canvasContext.drawImage(videotagging.video, 0, 0);
var writePath = reviewPath+ `/${frameId}.jpg`
var data = fCanvas.toDataURL('image/jpeg').replace(/^data:image\/\w+;base64,/, ""); // strip off the data: url prefix to get just the base64-encoded bytes http://stackoverflow.com/questions/5867534/how-to-save-canvas-data-to-file
var buf = new Buffer(data, 'base64');
//write canvas to file and change frame
console.log('saving file', writePath);
if (!fs.existsSync(writePath)) {
fs.writeFileSync(writePath, buf);
}
}
}
//optomize superRegionTracking
function initRegionTracking () {
videotagging.video.removeEventListener("canplay", initRegionTracking); //remove old listener
$('#video-tagging').off("stepFwdClicked-BeforeStep");
$('#video-tagging').off("stepFwdClicked-AfterStep");
var regionsToTrack = [];
$('#video-tagging').on("stepFwdClicked-BeforeStep", () => {
save();
videotagging.canMove = false;
var regionCount = $('.regionCanvas').length;
if (regionCount) {
var curFrame = videotagging.getCurrentFrame();
//init store imagedata for scene detection
var stanW = videotagging.video.videoWidth/videotagging.video.offsetWidth,
stanH = videotagging.video.videoHeight/videotagging.video.offsetHeight;
$.map($('.regionCanvas'), (regionCanvas, i) => {
//scale window to video
var w = Math.round(parseInt(regionCanvas.style.width) * stanW);
var h = Math.round(parseInt(regionCanvas.style.height) * stanH);
var y = Math.round(parseInt(regionCanvas.style.top) * stanH);
var x = Math.round(parseInt(regionCanvas.style.left) * stanW);
//get regionId
var originalRegion = $.grep(videotagging.frames[curFrame], function(e){ return e.name == regionCanvas.id;})[0];
//if region is in blacklist don't track
if (originalRegion.blockSuggest) return;
//add region to be tracked
regionsToTrack.push({x,y,w,h,originalRegion});
});
}
});
$('#video-tagging').on("stepFwdClicked-AfterStep", () => {
videotagging.video.addEventListener("canplay", afterStep);
});
function afterStep() {
videotagging.video.removeEventListener("canplay", afterStep);
if (regionsToTrack.length) {
var curFrame = videotagging.getCurrentFrame(),
stanW = videotagging.video.offsetWidth/videotagging.video.videoWidth,
stanH = videotagging.video.offsetHeight/videotagging.video.videoHeight;
// pass regions to super tracking
superTracking(regionsToTrack).then( (suggestions) => {
suggestions.forEach((suggestion) => {
var x1, y1, x2, y2;
if (suggestion.type == "copy") {
x1 = suggestion.region.x * stanW;
y1 = suggestion.region.y * stanH;
x2 = x1 + suggestion.region.w * stanW;
y2 = y1 + suggestion.region.h * stanH;
} else { //get bounding box of tracked object
x1 = Math.max(Math.round(suggestion.region.x * stanW) - Math.round((suggestion.region.w * stanW)/2), 0),
y1 = Math.max(Math.round(suggestion.region.y * stanH) - Math.round((suggestion.region.h * stanH)/2), 0),
x2 = Math.min(Math.round(suggestion.region.w * stanW) + x1, videotagging.video.offsetWidth),
y2 = Math.min(Math.round(suggestion.region.h * stanH) + y1, videotagging.video.offsetHeight);
}
// create new region
videotagging.createRegion(x1, y1, x2, y2);
videotagging.frames[curFrame][videotagging.frames[curFrame].length-1].tags = suggestion.originalRegion.tags;
videotagging.frames[curFrame][videotagging.frames[curFrame].length-1].suggestedBy = {frameId:curFrame-1, regionId:suggestion.originalRegion.id};
// add suggested by to previous region to blacklist
videotagging.frames[curFrame-1][suggestion.originalRegion.name-1].blockSuggest = true;
});
regionsToTrack = [];
videotagging.canMove = true;
}).catch( (e) => {
console.info(e);
regionsToTrack = [];
videotagging.canMove = true;
});
} else {
videotagging.canMove =true;
}
}
function superTracking(regions) {
return new Promise((resolve, reject) => {
supertrackingFrameRate = Math.max(supertrackingFrameRate,videotagging.framerate + 1);
var video = document.createElement('video');
video.src = videotagging.video.src;
video.currentTime = videotagging.video.currentTime - (1/videotagging.framerate);
video.oncanplay = init;
video.load();
var cstracker = new regiontrackr.camshift.Tracker({whitebalancing : false, calcAngles : false});
var tagging_duration, frameCanvas, canvasContext, scd, rcd;
var suggestions = [];
function init() {
video.oncanplay = undefined;
frameCanvas = document.createElement("canvas");
frameCanvas.width = video.videoWidth;
frameCanvas.height = video.videoHeight;
canvasContext = frameCanvas.getContext("2d")
canvasContext.drawImage(video, 0, 0);
tagging_duration = Math.min(videotagging.video.currentTime , videotagging.video.duration);
//detect if scene change
scd = new SceneChangeDetector({ threshold:49, detectionRegion: { w:frameCanvas.width, h:frameCanvas.height } });
scd.detectSceneChange(video, frameCanvas, canvasContext, videotagging.framerate).then( (sceneChanged) => {
if (!sceneChanged) {
video.oncanplay = trackFrames;
video.currentTime += (1/supertrackingFrameRate);
} else {
reject("scene changed");
}
}).catch((e) => {console.info(e)});
}
function trackFrames() {
if (!regions.length) {
video.oncanplay = undefined;
return resolve(suggestions);
}
var regionDetectionPromises = [];
regions.forEach((region, i) => {
// if first pass check whether the region changed
if (region.regionChanged === undefined) {
rcd = new SceneChangeDetector({ threshold:1, detectionRegion: { w:region.w, h:region.h} });
regionDetectionPromises.push(rcd.detectRegionChange(video, frameCanvas, region, i, videotagging.framerate));
} else {
if (region.regionChanged) {
trackRegion(region, i);
}
}
});
Promise.all(regionDetectionPromises).then((values) => {
values.sort((a,b) => { return b.index - a.index; });//sort so removal works correctly
values.forEach ( (rp) => { //rp is resolved promise
if (rp.regionChanged) {
trackRegion(rp.region, rp.index);
regions[rp.index].regionChanged = rp.regionChanged; //make sure region change only executes once
} else {
suggestions.push({type:"copy", region : rp.region, originalRegion: rp.region.originalRegion});
regions.splice(rp.index,1);
}
});
if (video.currentTime >= tagging_duration) {
video.oncanplay = undefined;
resolve(suggestions);
} else {
video.currentTime += (1 / supertrackingFrameRate);//go to next frame segment
}
},(e)=>{console.info(e);});
}
function trackRegion(region, i) {
//on exit condition push to suggestions
if (video.currentTime >= tagging_duration) {
if (region.trackedObject) {
suggestions.push( {type:"tracked", region:{x : region.trackedObject.x, y : region.trackedObject.y, w : region.w, h: region.h}, originalRegion: region.originalRegion});
}
}
//init tracker for region
if (!region.trackedObject){
cstracker.initTracker(frameCanvas, new regiontrackr.camshift.Rectangle(region.x, region.y, region.w, region.h));
} else {
if (region.trackedObject.width === 0 || region.trackedObject.height === 0 ) { //skip tracking if object disapeared
return;
} else {
cstracker.initTracker(frameCanvas, new regiontrackr.camshift.Rectangle(region.tx, region.ty, region.w, region.h));
}
}
//track region
canvasContext.drawImage(video, 0, 0);
cstracker.track(frameCanvas);
regions[i].trackedObject = cstracker.getTrackObj();
//create new tracker
regions[i].tx = Math.round(region.trackedObject.x - region.w/2);
regions[i].ty = Math.round(region.trackedObject.y - region.h/2);
}
});
}
}
+75 -7
Ver Arquivo
@@ -27,7 +27,7 @@ function createWindow () {
y: mainWindowState.y,
minHeight: 480,
minWidth: 480,
icon: __dirname + '/icon.png',
icon: __dirname + '/src/public/images/icon.png',
show: false
});
@@ -35,7 +35,7 @@ function createWindow () {
// and load the index.html of the app.
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
pathname: path.join(__dirname, 'src/index.html'),
protocol: 'file:',
slashes: true
}));
@@ -47,10 +47,59 @@ function createWindow () {
let p = (process.platform === 'darwin') ? 1 : 0;
menu.items[p].submenu.items[1].enabled = true;
menu.items[p].submenu.items[2].enabled = true;
menu.items[p].submenu.items[3].enabled = true;
menu.items[p+1].submenu.items[0].enabled = true;
menu.items[p+1].submenu.items[1].enabled = true;
});
// do this independently for each object
ipcMain.on('show-popup', function(event, arg) {
let popup = new BrowserWindow({
parent: mainWindow,
modal: true,
show: false,
frame: false,
autoHideMenuBar : true
});
switch (arg.type) {
case "export":
popup.setSize(359, 300);
popup.loadURL(url.format({
pathname: path.join(__dirname, 'src/public/html/export-configuration.html'),
protocol: 'file:',
slashes: true
}));
break;
case "review":
popup.setSize(359, 310);
popup.loadURL(url.format({
pathname: path.join(__dirname, 'src/public/html/review-configuration.html'),
protocol: 'file:',
slashes: true
}));
break;
default: return;
}
popup.once('ready-to-show', () => {
popup.send('configs', arg);
popup.show();
});
});
ipcMain.on('export-tags', (event, arg) => {
mainWindow.send('export-tags', arg);
});
ipcMain.on('review-model', (event, arg) => {
mainWindow.send('review-model', arg);
});
mainWindow.on('ready-to-show', function() {
mainWindow.show();
mainWindow.focus();
@@ -74,6 +123,11 @@ function createWindow () {
accelerator: 'CmdOrCtrl+O',
click () { mainWindow.webContents.send('openVideo'); }
},
{
label: 'Open Image Directory...',
accelerator: 'CmdOrCtrl+I',
click () { mainWindow.webContents.send('openImageDirectory'); }
},
{
label: 'Save',
accelerator: 'CmdOrCtrl+S',
@@ -89,22 +143,34 @@ function createWindow () {
]
},
{
label: 'CNTK',
label: 'Object Detection',
submenu: [
{
label: 'Export Tags to CNTK',
label: 'Export Tags',
accelerator: 'CmdOrCtrl+E',
enabled: false,
click () { mainWindow.webContents.send('exportCNTK'); }
click () { mainWindow.webContents.send('export'); }
},
{
label: 'Review CNTK Model',
label: 'Review Detection Model',
accelerator: 'CmdOrCtrl+R',
enabled: false,
click () { mainWindow.webContents.send('reviewCNTK'); }
click () { mainWindow.webContents.send('review'); }
}
]
},
{
label: "Edit",
submenu: [
{ label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
{ label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
{ type: "separator" },
{ label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
{ label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
{ label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
{ label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
]
},
{
label: 'Debug',
submenu: [
@@ -154,10 +220,12 @@ if (process.platform === 'darwin') {
})
template[1].submenu.push();
template[2].submenu.push();
}
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
}
// This method will be called when Electron has finished
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 16 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 59 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 48 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 40 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 63 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 64 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 66 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 64 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 20 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 20 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 451 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 74 KiB

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 36 KiB

BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 320 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 544 B

BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 305 B

Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 33 KiB

+11 -10
Ver Arquivo
@@ -1,29 +1,30 @@
{
"name": "offline-video-tagger",
"name": "vott",
"version": "1.0.0",
"description": "An offline port of the video-tagging-tool for electron.",
"description": "An electron app for building end to end Object Detection Models with CNTK from Sample Videos.",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"repository": "https://github.com/CatalystCode/offline-video-tagger/",
"repository": "https://github.com/CatalystCode/VOTT",
"keywords": [
"Electron",
"Video-Tagging",
"CNTK",
"tutorial",
"demo"
"Deep-Learning",
"Object-Detection"
],
"author": "GitHub",
"readme": "README.md",
"author": "aribornstein",
"license": "MIT",
"devDependencies": {
"electron": "^1.4.1",
"bower": "^1.7.2"
},
"dependencies": {
"cntk-fastrcnn": "^0.1.5",
"async": "^2.1.5",
"cntk-fastrcnn": "^0.2.6",
"electron": "^1.4.1",
"electron-window-state": "^4.0.2",
"remote": "^0.2.6",
"rimraf": "^2.6.1"
"replace": "^0.3.0"
}
}
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 33 KiB

-7
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Ver Arquivo

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais