diff --git a/README.md b/README.md index bfbce3a4..b9d412cd 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ The following section contains some notes on how to set up your own instance to This should only give you an idea how you *could* configure your system. Of course you are totally free in choosing a different linux distribution, tools and scripts. If you are only interested in how to compile ImageMonkey, then you can jump directly to the *Build Application* section -*Info:* Some commands are distribution (Debian 9.1) specific and may not work on your system. +*Info:* Some commands are distribution (Debian 10) specific and may not work on your system. ### Base System Configuration ### diff --git a/conf/nginx/nginx.conf b/conf/nginx/nginx.conf index b6b86dd7..d15efe5b 100644 --- a/conf/nginx/nginx.conf +++ b/conf/nginx/nginx.conf @@ -13,7 +13,7 @@ events { http{ - limit_req_zone $binary_remote_addr zone=general:20m rate=4r/s; + limit_req_zone $binary_remote_addr zone=general:20m rate=15r/s; include /etc/nginx/mime.types; diff --git a/conf/supervisor/imagemonkey-bot.conf b/conf/supervisor/imagemonkey-bot.conf index 3b48ffce..f4242021 100644 --- a/conf/supervisor/imagemonkey-bot.conf +++ b/conf/supervisor/imagemonkey-bot.conf @@ -1,6 +1,6 @@ [program:imagemonkey-bot] process_name=imagemonkey-bot%(process_num)s -command=/home/imagemonkey/bin/bot -use_sentry=true -labels_repository_name=imagemonkey-labels -labels_repository_owner=bbernhard -singleshot=false -git_checkout_dir=/tmp/labelsbot-checkout -polling_interval=10 +command=/home/imagemonkey/bin/bot -use_sentry=true -labels_repository_name=imagemonkey-labels -labels_repository_owner=ImageMonkey -singleshot=false -git_checkout_dir=/tmp/labelsbot-checkout -polling_interval=10 autostart=true autorestart=true startretries=10 diff --git a/css/common.css b/css/common.css index 299604cb..16012882 100644 --- a/css/common.css +++ b/css/common.css @@ -151,3 +151,7 @@ .pusher > .footer { flex: 1; } + +.default-text { + font-size: 1.33em; +} diff --git a/html/static/blog/README.md b/html/static/blog/README.md index 1ca375a8..ff738197 100644 --- a/html/static/blog/README.md +++ b/html/static/blog/README.md @@ -1,3 +1,11 @@ README ====== +# Install +* Install jekyll as described [here](https://jekyllrb.com/docs/installation/) +* Execute `bundle install` in the `imagemonkey-blog` folder to install dependencies + +# Build + Run +* Execute `bundle exec jekyll build` in the `imagemonkey-blog` folder to generate the sites +* Execute `bundle exec jekyll serve` in the `imagemonkey-blog` folder to run it + diff --git a/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/annotation_rework.gif b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/annotation_rework.gif new file mode 100644 index 00000000..ecfc4c28 Binary files /dev/null and b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/annotation_rework.gif differ diff --git a/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/earn_badges.png b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/earn_badges.png new file mode 100644 index 00000000..7af1e1a7 Binary files /dev/null and b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/earn_badges.png differ diff --git a/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/grow_dataset.png b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/grow_dataset.png new file mode 100644 index 00000000..b13a7bff Binary files /dev/null and b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/grow_dataset.png differ diff --git a/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/imagemonkey_thegame.png b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/imagemonkey_thegame.png new file mode 100644 index 00000000..2632decc Binary files /dev/null and b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/imagemonkey_thegame.png differ diff --git a/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/photograph_object.png b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/photograph_object.png new file mode 100644 index 00000000..24e33956 Binary files /dev/null and b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/photograph_object.png differ diff --git a/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/progress.png b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/progress.png new file mode 100644 index 00000000..36facdeb Binary files /dev/null and b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/progress.png differ diff --git a/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/validation.gif b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/validation.gif new file mode 100644 index 00000000..329ab5dc Binary files /dev/null and b/html/static/blog/assets/article_images/2020-02-09-ImageMonkey-100k/validation.gif differ diff --git a/html/static/blog/feed.xml b/html/static/blog/feed.xml index 5f21ea4a..09cc32ad 100644 --- a/html/static/blog/feed.xml +++ b/html/static/blog/feed.xml @@ -6,10 +6,201 @@ http://myblog.***.***/blog/ - Sun, 03 Dec 2017 20:34:08 +0100 - Sun, 03 Dec 2017 20:34:08 +0100 + Wed, 12 Feb 2020 21:53:01 +0100 + Wed, 12 Feb 2020 21:53:01 +0100 Jekyll v3.5.2 + + ImageMonkey reaches the 100k milestone + <p><a href="https://imagemonkey.io">ImageMonkey</a> is a public open source image dataset with powerful APIs and a tight integration of existing machine learning frameworks.</p> + +<p>As of last week it seems that we’ve finally cracked the 100k milestone - the ImageMonkey dataset now contains over 100k CC0 licensed images, ~140k labeled objects, ~25k validations and over 100k annotated objects.</p> + +<p><img src="/blog/assets/article_images/2020-02-09-ImageMonkey-100k/progress.png" alt="Progress over time&lt;br&gt;(The timestamp for image uploads wasn't there at the beginning,&lt;br&gt;that's why the black line chart is missing some data points)" /></p> + +<p>It’s now almost three years ago since I started working on ImageMonkey - at that time mainly to scratch my own itch. Back then, I was working on another project, which I thought had the potential to blow up (actually it flopped totally, but that’s a different story) and for that project I was looking for labeled gym equipment datasets to train a neural net on it. As it turned out annotated images are really hard to find - and it gets even harder if you are looking for a public domain dataset.</p> + +<p>That’s when I thought to myself: Wouldn’t it be great if there exists such a public dataset? A dataset that’s not owned by a big company where you have to fear that at some point they will shut down the service and everything is lost (yeah, looking at you Yahoo). <strong>A dataset created by people for people.</strong> A dataset where <em>eyerbody</em> can contribute to. Something that’s easy to use.</p> + +<p>There are millions of people in the world running around with their smartphones, snapping pictures of their dogs, cats and what they have for lunch. Wouldn’t that be great image material for a public domain dataset?</p> + +<p>When creating ImageMonkey one of the primary goals was always simplicity and ease of use. ImageMonkey wasn’t primarily designed to be used by the “hardcore data labeler” (that’s not to say that that we do not provide tools for those as well), it was rather designed to be used the ordinary man and and woman. In order to accomplish that, the whole process of collecting data was split up in different tasks (“task based approach”).</p> + +<p><img src="/blog/assets/article_images/2020-02-09-ImageMonkey-100k/annotation_rework.gif" alt="Annotating objects" /></p> + +<center><img src="/blog/assets/article_images/2020-02-09-ImageMonkey-100k/validation.gif" width="50%" alt="Validating objects" /></center> + +<p>The traditional worflow of annotating an object usually looks like this:</p> +<ul> + <li>collect an image</li> + <li>draw a bounding box around the object of interest</li> + <li>label it appropriately.</li> +</ul> + +<p>With ImageMonkey it’s different. Every of those tasks can be done individually. You love taking pictures, but don’t want to tag them with labels? No problem, just upload the pictures without labels - that’s perfectly fine. You enjoy labeling images (I’ve heard that some people find that quite relaxing) but don’t want to draw bounding boxes around the objects? That’s fine, just do the labeling. As you can see, the complex task of annotating objects is broken down in much simpler tasks. The cool thing about that is, that it’s now possible to build APIs around those functionalities and use those APIs to create other applications.</p> + +<p>In the <a href="https://www.youtube.com/watch?v=ji5_MqicxSo">Last Lecture</a> (if you haven’t seen it, I highly encourage you to do so), Randy Pausch talks about <em>head fake</em> - a situation in which someone believes they are learning one thing, but are really learning something different. I am a huge fan of this concept and personally I think it not only works for learning something, but also for <em>doing</em> something.</p> + +<p>While working on ImageMonkey I tried to make use of head fakes and incorporate them into the software I was building. Then, let’s be honest here: Collecting data for a dataset can be tedious and boring - so why not make it more fun?</p> + +<p>With the ImageMonkey Browser Extension and ImageMonkey - The Game I tried exactly that.</p> + +<p>The <a href="https://github.com/bbernhard/imagemonkey-chrome-extension">ImageMonkey Browser Extension</a> shows a random validation each time you open a new browser tab. +<img src="/blog/assets/article_images/2017-10-28-ImageMonkey-v0.2/google-chrome-extension.gif" alt="ImageMonkey Browser Extension" /></p> + +<p><a href="https://play.google.com/store/apps/details?id=io.imagemonkey.thegame">ImageMonkey - The Game</a> uses gamification concepts to make image collecting more fun.</p> + +<p><img src="/blog/assets/article_images/2020-02-09-ImageMonkey-100k/imagemonkey_thegame.png" alt="" /></p> + +<h1 id="powerful-api-and-tight-integrations-of-existing-ml-frameworks">Powerful API and tight integrations of existing ML frameworks</h1> +<p>ImageMonkey’s task based approach made it possible to build a REST API around all its functionality, which not only allows developers to easily export data, but also gives them the possibility to feed back data their own.</p> + +<p>Due to the <a href="https://imagemonkey.io/libraries">tight integration</a> of existing machine learning frameworks like <a href="https://www.tensorflow.org/">Tensorflow</a> and <a href="https://github.com/matterport/Mask_RCNN">Mask RCNN</a> it’s possible to train a neural net for image classification, object detection and object segmentation with just a handful of commands.</p> + +<p>e.g If you want to train a cat/dog image classifier via transfer learning on a pre-trained inception-v3 model, all you need to do is:</p> + +<pre><code class="bash"> + docker pull bbernhard/imagemonkey-train:latest-gpu + docker run --runtime=nvidia -it bbernhard/imagemonkey-train:latest-gpu +</code></pre> + +<pre><code class="bash"> + monkey train --labels="cat|dog" --type="image-classification" +</code></pre> + +<p>The monkey script automatically downloads the necessary data from ImageMonkey, configures the tensorflow pipeline and then starts tensorflow for training. When the training is done, the script spits out a ready-to-go <code>graph.pb</code> file.</p> + +<h1 id="what-exactly-is-a-public-open-source-image-dataset">What exactly is a public open source image dataset?</h1> + +<p>Every line of code that was ever written for the ImageMonkey project is available on <a href="https://github.com/ImageMonkey">Github</a> - i.e if you want to spin up your own (private) ImageMonkey instance for collecting data you can easily do that. But it’s not only that. Every item in the ImageMonkey dataset is licensed under the CC0 license. Which basically means you can do the f*ck you want with it - no strings attached. Furthermore, the whole dataset (i.e the images + an obfuscated database dump) gets uploaded to the internet archive on a regular basis (see <a href="https://imagemonkey.io/public_backup">here</a> for details).</p> + +<h1 id="whats-next">What’s next?</h1> + +<p>Hosting ImageMonkey (and all it’s services) costs money. At the moment everything’s running on two big Hetzner bare metal servers (one of them being a GPU instance). And while the server costs are still affordable for me, I would really like to see ImageMonkey getting <a href="https://imagemonkey.io/supportus">self sustainable</a>.</p> + +<p>Apart from that, I’ll be working on:</p> + +<ul> + <li>a better annotation editor</li> + <li>improve the ML pipeline to provide models for download on a regular basis</li> + <li>some general improvements</li> +</ul> + +<h1 id="thanks">Thanks</h1> +<p>Last but not least I want to thank <a href="https://github.com/dobkeratops">@dobkeratops</a> - ImageMonkey wouldn’t be where it is right now without your help. Thanks a lot for all your contributions!</p> + +<h1 id="want-to-contribute">Want to contribute?</h1> +<p>Any help is really appreciated - whether it is <a href="https://github.com/ImageMonkey">help with the codebase</a>, <a href="https://imagemonkey.io/donate">contributions to the dataset</a> or <a href="https://imagemonkey.io/supportus">financial support</a>. Let’s create our public image dataset together!</p> + +<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha256-/SIrNqv8h6QGKDuNoLGA4iret+kyesCkHGzVUUV0shc=" crossorigin="anonymous"></script> + +<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" /> + +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> + +<!--<script type="text/javascript" src="/assets/js/toast.js"></script>--> + +<div class="divider-30"></div> + +<center><h5>Want to read more about ImageMonkey?</h5></center> +<center><h5>Subscribe now!</h5></center> + +<iframe name="hiddenFrame" width="0" height="0" border="0" style="display: none;"></iframe> +<center><form id="register-newsletter"> + <input id="email" type="text" name="newsletter" required="" placeholder="Enter your email address" /> + <input type="submit" class="btn btn-custom-3 submit-button" value="SIGN UP" /> +</form></center> +<div id="register-successful" class="hide" role="alert"> + <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button> +</div> + +<script> +$('#register-newsletter').submit(function(e) { + subscribe(); + return false; +}); + +function validateEmail(email) { + var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(email); +} + +function postEmail(email){ + var url = encodeURI("https://api.imagemonkey.io/v1/blog/subscribe"); + $.ajax({ + url: url, + dataType: 'json', + type: 'POST', + data: JSON.stringify({email: email}), + complete: function(data){ + }, + success: function(data){ + $('#register-successful').html('<center>Successfully signed up</center>'); + $('#register-successful').removeClass('hide').addClass('alert alert-success').fadeTo(2000, 500).slideUp(500, function(){ + $("#register-successful").slideUp(500); + }); + }, + error: function (xhr, status, errorThrown){ + $('#register-successful').html("<center>Couldn't sign up</center>"); + $('#register-successful').removeClass('hide').addClass('alert alert-danger').fadeTo(2000, 500).slideUp(500, function(){ + $("#register-successful").slideUp(500); + }); + } + }); +} + + +function subscribe() { + var emailAddress = $("#email").val(); + console.log(emailAddress) + $("#register-newsletter").trigger("reset"); + validateEmail(emailAddress); + if (!validateEmail(emailAddress)) { + $('#register-successful').html("<center>Please enter a valid email address</center>"); + $('#register-successful').removeClass('hide').addClass('alert alert-danger').fadeTo(2000, 500).slideUp(500, function(){ + $("#register-successful").slideUp(500); + }); + return; + } + + postEmail(emailAddress); +} + +</script> + +<style type="text/css"> +.submit-button { + color: #fff; + background-color: #57ad68; + border-color: #4cae4c; +} + +.submit-button:hover { + color: #fff; + background-color: #449d44; + border-color: #398439; +} + +.divider-30{ + width:100%; + min-height:1px; + margin-top:30px; + margin-bottom:30px; + display:inline-block; + position:relative; +} +</style> + + + Sun, 09 Feb 2020 13:34:25 +0100 + http://myblog.***.***/blog/general/2020/02/09/ImageMonkey-100k-0.html + http://myblog.***.***/blog/general/2020/02/09/ImageMonkey-100k-0.html + + + general + + + We made some progress <p>It’s now almost 30 days since the <a href="https://imagemonkey.io/blog/general/2017/10/06/ImageMonkey-Introduction.html">last blog post</a> and we made some really good progress. If you haven’t kept up with us, then here’s a quick summary:</p> diff --git a/html/static/blog/general/2017/10/06/ImageMonkey-Introduction.html b/html/static/blog/general/2017/10/06/ImageMonkey-Introduction.html index 881fbb59..7971217b 100644 --- a/html/static/blog/general/2017/10/06/ImageMonkey-Introduction.html +++ b/html/static/blog/general/2017/10/06/ImageMonkey-Introduction.html @@ -295,7 +295,7 @@

Bernhard

- +
diff --git a/html/static/blog/general/2017/10/28/ImageMonkey-v0.2.html b/html/static/blog/general/2017/10/28/ImageMonkey-v0.2.html index ca09f5c9..147562fa 100644 --- a/html/static/blog/general/2017/10/28/ImageMonkey-v0.2.html +++ b/html/static/blog/general/2017/10/28/ImageMonkey-v0.2.html @@ -291,7 +291,7 @@

Bernhard

- +
diff --git a/html/static/blog/general/2020/02/09/ImageMonkey-100k-0.html b/html/static/blog/general/2020/02/09/ImageMonkey-100k-0.html new file mode 100644 index 00000000..16f5a40f --- /dev/null +++ b/html/static/blog/general/2020/02/09/ImageMonkey-100k-0.html @@ -0,0 +1,350 @@ + + + + + + + + + + ImageMonkey reaches the 100k milestone + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ Article Image +
+
+ Article Image +
+ +
+ +
+
+ read +
+ +

ImageMonkey is a public open source image dataset with powerful APIs and a tight integration of existing machine learning frameworks.

+ +

As of last week it seems that we’ve finally cracked the 100k milestone - the ImageMonkey dataset now contains over 100k CC0 licensed images, ~140k labeled objects, ~25k validations and over 100k annotated objects.

+ +

Progress over time<br>(The timestamp for image uploads wasn't there at the beginning,<br>that's why the black line chart is missing some data points)

+ +

It’s now almost three years ago since I started working on ImageMonkey - at that time mainly to scratch my own itch. Back then, I was working on another project, which I thought had the potential to blow up (actually it flopped totally, but that’s a different story) and for that project I was looking for labeled gym equipment datasets to train a neural net on it. As it turned out annotated images are really hard to find - and it gets even harder if you are looking for a public domain dataset.

+ +

That’s when I thought to myself: Wouldn’t it be great if there exists such a public dataset? A dataset that’s not owned by a big company where you have to fear that at some point they will shut down the service and everything is lost (yeah, looking at you Yahoo). A dataset created by people for people. A dataset where eyerbody can contribute to. Something that’s easy to use.

+ +

There are millions of people in the world running around with their smartphones, snapping pictures of their dogs, cats and what they have for lunch. Wouldn’t that be great image material for a public domain dataset?

+ +

When creating ImageMonkey one of the primary goals was always simplicity and ease of use. ImageMonkey wasn’t primarily designed to be used by the “hardcore data labeler” (that’s not to say that that we do not provide tools for those as well), it was rather designed to be used the ordinary man and and woman. In order to accomplish that, the whole process of collecting data was split up in different tasks (“task based approach”).

+ +

Annotating objects

+ +
Validating objects
+ +

The traditional worflow of annotating an object usually looks like this:

+
    +
  • collect an image
  • +
  • draw a bounding box around the object of interest
  • +
  • label it appropriately.
  • +
+ +

With ImageMonkey it’s different. Every of those tasks can be done individually. You love taking pictures, but don’t want to tag them with labels? No problem, just upload the pictures without labels - that’s perfectly fine. You enjoy labeling images (I’ve heard that some people find that quite relaxing) but don’t want to draw bounding boxes around the objects? That’s fine, just do the labeling. As you can see, the complex task of annotating objects is broken down in much simpler tasks. The cool thing about that is, that it’s now possible to build APIs around those functionalities and use those APIs to create other applications.

+ +

In the Last Lecture (if you haven’t seen it, I highly encourage you to do so), Randy Pausch talks about head fake - a situation in which someone believes they are learning one thing, but are really learning something different. I am a huge fan of this concept and personally I think it not only works for learning something, but also for doing something.

+ +

While working on ImageMonkey I tried to make use of head fakes and incorporate them into the software I was building. Then, let’s be honest here: Collecting data for a dataset can be tedious and boring - so why not make it more fun?

+ +

With the ImageMonkey Browser Extension and ImageMonkey - The Game I tried exactly that.

+ +

The ImageMonkey Browser Extension shows a random validation each time you open a new browser tab. +ImageMonkey Browser Extension

+ +

ImageMonkey - The Game uses gamification concepts to make image collecting more fun.

+ +

+ +

Powerful API and tight integrations of existing ML frameworks

+

ImageMonkey’s task based approach made it possible to build a REST API around all its functionality, which not only allows developers to easily export data, but also gives them the possibility to feed back data their own.

+ +

Due to the tight integration of existing machine learning frameworks like Tensorflow and Mask RCNN it’s possible to train a neural net for image classification, object detection and object segmentation with just a handful of commands.

+ +

e.g If you want to train a cat/dog image classifier via transfer learning on a pre-trained inception-v3 model, all you need to do is:

+ +

+      docker pull bbernhard/imagemonkey-train:latest-gpu
+      docker run --runtime=nvidia -it bbernhard/imagemonkey-train:latest-gpu
+
+ +

+      monkey train --labels="cat|dog" --type="image-classification"
+
+ +

The monkey script automatically downloads the necessary data from ImageMonkey, configures the tensorflow pipeline and then starts tensorflow for training. When the training is done, the script spits out a ready-to-go graph.pb file.

+ +

What exactly is a public open source image dataset?

+ +

Every line of code that was ever written for the ImageMonkey project is available on Github - i.e if you want to spin up your own (private) ImageMonkey instance for collecting data you can easily do that. But it’s not only that. Every item in the ImageMonkey dataset is licensed under the CC0 license. Which basically means you can do the f*ck you want with it - no strings attached. Furthermore, the whole dataset (i.e the images + an obfuscated database dump) gets uploaded to the internet archive on a regular basis (see here for details).

+ +

What’s next?

+ +

Hosting ImageMonkey (and all it’s services) costs money. At the moment everything’s running on two big Hetzner bare metal servers (one of them being a GPU instance). And while the server costs are still affordable for me, I would really like to see ImageMonkey getting self sustainable.

+ +

Apart from that, I’ll be working on:

+ +
    +
  • a better annotation editor
  • +
  • improve the ML pipeline to provide models for download on a regular basis
  • +
  • some general improvements
  • +
+ +

Thanks

+

Last but not least I want to thank @dobkeratops - ImageMonkey wouldn’t be where it is right now without your help. Thanks a lot for all your contributions!

+ +

Want to contribute?

+

Any help is really appreciated - whether it is help with the codebase, contributions to the dataset or financial support. Let’s create our public image dataset together!

+ + + + + + + + + +
+ +
Want to read more about ImageMonkey?
+
Subscribe now!
+ + +
+ + +
+ + + + + + + +
+
+ +
+
+
+ +
+
Blog Logo
+

Bernhard

+

+
+

Published

+
+
+ +
+ +
+
+ +
+
+
+
+ +
+
+
+
+ Image +
+
+

ImageMonkey - Blog

+

ImageMonkey - a public, open source image dataset +

+ Back to Overview +
+
+ + + + + + + + + diff --git a/html/static/blog/index.html b/html/static/blog/index.html index 4d10626e..b24ee780 100644 --- a/html/static/blog/index.html +++ b/html/static/blog/index.html @@ -96,6 +96,23 @@

ImageMonkey - a public, open source image dataset
+
+
+
+

+
+
+

ImageMonkey is a public open source image dataset with powerful APIs and a tight integration of existing machine learning frameworks. + +

+
+ +
+
+
@@ -154,7 +171,7 @@

- +
Made with Jekyll
diff --git a/html/templates/contribution_statistics.html b/html/templates/contribution_statistics.html new file mode 100644 index 00000000..b36e2d99 --- /dev/null +++ b/html/templates/contribution_statistics.html @@ -0,0 +1,82 @@ + + + + {{ template "favicon.html" .}} + + + + + + + + {{ .title }} + + + + + + + + + + + + + + + + + + + + + {{ template "menu.html" .}} + + +
+
+ {{ template "pointing_menu.html" .}} +
+

+ Total Contributions +

+
+
+
+
+ + +
+
+
+ + +
+
+
+
+ + + +
+
+
+{{ template "footer.html" .}} + + + + diff --git a/html/templates/explore.html b/html/templates/explore.html index 6baa42ba..3c1e83f1 100644 --- a/html/templates/explore.html +++ b/html/templates/explore.html @@ -23,6 +23,8 @@ + + + @@ -946,7 +985,7 @@

{{ .subtitle }}

+ +
- + {{ template "footer.html" .}} diff --git a/html/templates/libraries.html b/html/templates/libraries.html index 6cb0a877..af9ee5b2 100644 --- a/html/templates/libraries.html +++ b/html/templates/libraries.html @@ -58,9 +58,9 @@

- One of the best things about ImageMonkey is our tight integration with Machine learning frameworks like Tensorflow and Mask RCNN.
You want to train your own image classifier based on the ImageMonkey dataset?

- It's as easy as that:

- CPU version +

One of the best things about ImageMonkey is our tight integration with Machine learning frameworks like Tensorflow and Mask RCNN.
You want to train your own image classifier based on the ImageMonkey dataset?

+ It's as easy as that:



+

CPU version:


     docker pull bbernhard/imagemonkey-train:latest
@@ -68,7 +68,7 @@ 


- GPU version +

GPU version:


     docker pull bbernhard/imagemonkey-train:latest-gpu
@@ -76,10 +76,10 @@ 


- This will download and run a docker image where we've already configured tensorflow and MaskRCNN to work seamlessly with ImageMonkey. +

This will download and run a docker image where we've already configured tensorflow and MaskRCNN to work seamlessly with ImageMonkey. After you've started the docker container, use the monkey script to interact with ImageMonkey dataset.

- Here's a list of all available commands: + Here's a list of all available commands:


@@ -99,8 +99,8 @@ 

Example

- Let's assume you want to train your image classifier on all images that are labeled with dog or cat. - Then simply run +

Let's assume you want to train your image classifier on all images that are labeled with dog or cat. + Then simply run


@@ -108,27 +108,27 @@ 

Example


- lean back and go get yourself a coffee ;-) +

lean back and go get yourself a coffee ;-)



- The script automatically downloads all ImageMonkey images that are labeled with dog or cat and uses transfer learning to retrain an +

The script automatically downloads all ImageMonkey images that are labeled with dog or cat and uses transfer learning to retrain an existing image classifier (inception v3) on these labels.

Umm, wait, I don't want to train an image classifier - I rather want to train a neural net that is able to do object segmentation. - Nothing easier than that. Simply change the type + Nothing easier than that. Simply change the type


       monkey train --labels="cat|dog" --type="object-segmentation"
           
- and MaskRCNN will be used instead. +

and MaskRCNN will be used instead.




-

P.S.

- In case you want to access ImageMonkey via Python, have a look at our Python library. - But keep in mind, the library is still in an alpha stage and the API might change at any point! +

P.S.

+

In case you want to access ImageMonkey via Python, have a look at our Python library. + But keep in mind, the library is still in an alpha stage and the API might change at any point!

diff --git a/html/templates/mobile.html b/html/templates/mobile.html index 467635b1..ca046191 100644 --- a/html/templates/mobile.html +++ b/html/templates/mobile.html @@ -36,23 +36,26 @@

-

Mobile App

-

The ImageMonkey app for your smartphone allows you to validate and donate photos while on the road.

-

- -
- Build from source -
Fork us and build the ImageMonkey App from source.
+

Mobile Apps

+

The ImageMonkey mobile app allows you to validate and donate photos while on the road.

+ +
+
+ +
-

+

- Or + OR

+ +

ImageMonkey - The Game uses gamification concepts to make contributing to the dataset more fun.

+
- - + +
@@ -62,9 +65,9 @@

Firefox Extension

- Help us to improve our public image dataset whenever you open a new browser tab.

+

Help us to improve our public image dataset whenever you open a new browser tab.

- Validating images can be a tedious and time consuming task. Use this Firefox extension to limit the time you are spending on image validations. + Validating images can be a tedious and time consuming task. Use this Firefox extension to limit the time you are spending on image validations.

Get the extension
diff --git a/html/templates/modules/annotation_browse_select_mode.html b/html/templates/modules/annotation_browse_select_mode.html index d249d3b9..14b1dc02 100644 --- a/html/templates/modules/annotation_browse_select_mode.html +++ b/html/templates/modules/annotation_browse_select_mode.html @@ -94,14 +94,14 @@ }); } - function showBrowseAnnotationImageGrid(annotatedEntriesIds = null) { + function showBrowseAnnotationImageGrid(imageGridImageIdentifiers = null) { //if the image grid gets shown again, the image in question was successfully annotated/blacklisted or marked //as non-annotatable. We now grey the image out and change the mouse cursor to default again. - if(annotatedEntriesIds !== null) { - for(var i = 0; i < annotatedEntriesIds.length; i++) { - $("#"+annotatedEntriesIds[i]).addClass("grey-out"); - $("#"+annotatedEntriesIds[i]).css('cursor', 'default'); + if(imageGridImageIdentifiers !== null) { + for(var i = 0; i < imageGridImageIdentifiers.length; i++) { + $("#"+imageGridImageIdentifiers[i]).addClass("grey-out"); + $("#"+imageGridImageIdentifiers[i]).css('cursor', 'default'); } } @@ -121,7 +121,6 @@ } function handleRes(d) { $("#imageGrid").show(); - if(d && d.length > 0) { imageGridData = d; sizes = []; @@ -196,13 +195,23 @@ if($(elem).hasClass("grey-out")) return; - var validationId = $(elem).attr("data-validationid"); - //currentAnnotatedImageGridElement = $(elem).attr("id"); + var validationId = $(elem).attr("data-validationid"); $("#annotationQuerySearchContainer").hide(); infiniteScroll.pause(); infiniteScroll.saveScrollPosition(); $("#imageGrid").hide(); - annotationView.loadUnannotatedImage(validationId); + + if(validationId === "") { + var imageId = $(elem).attr("data-image-id"); + var imageUrl = $(elem).attr("data-orig-image-url"); + var imageWidth = $(elem).attr("data-orig-image-width"); + var imageHeight = $(elem).attr("data-orig-image-height"); + var imageUnlocked = ($(elem).attr("data-image-unlocked") === "true") ? true : false; + annotationView.loadUnannotatedImageWithNoLabelsFromImageUrl(imageId, imageWidth, imageHeight, imageUrl, imageUnlocked); + } + else { + annotationView.loadUnannotatedImage(validationId); + } } function onImageGridCanvasClicked(data) { @@ -214,12 +223,18 @@ annotationView.loadAnnotatedImage(annotationId, -1); } - function newImageItem(id, url, validationId, top, left, width, height, tooltip) { + function newImageItem(id, url, validationId, top, left, width, height, tooltip, imageId, origImageWidth, origImageHeight, origImageUrl, imageUnlocked) { var d = ('
'); + + '" data-validationid="' + validationId + + '" data-orig-image-width="' + origImageWidth + + '" data-orig-image-height="' + origImageHeight + + '" data-image-unlocked="' + imageUnlocked + + '" data-orig-image-url="' + origImageUrl + + '" data-image-id="' + imageId + + '" onclick="onImageGridItemClicked(this);" style="cursor: pointer;">
'); return d; } @@ -302,8 +317,13 @@ } var itemId = imageGridData[i]["uuid"]; + if(itemId === "") + itemId = imageGridData[i]["image"]["uuid"]; + item = newImageItem(itemId, url, imageGridData[i]["uuid"], justifiedLayoutGeometry.boxes[i].top, justifiedLayoutGeometry.boxes[i].left, - justifiedLayoutGeometry.boxes[i].width, justifiedLayoutGeometry.boxes[i].height, tooltipText); + justifiedLayoutGeometry.boxes[i].width, justifiedLayoutGeometry.boxes[i].height, tooltipText, + imageGridData[i]["image"]["uuid"], imageGridData[i]["image"]["width"], imageGridData[i]["image"]["height"], + imageGridData[i]["image"]["url"], imageGridData[i]["image"]["unlocked"]); $("#imageGrid").append(item); } @@ -329,14 +349,9 @@ imageMonkeyApi.setToken(getCookie("imagemonkey")); - var availableLabels = []; var staticQueryAttributes = {{ .queryAttributes }}; - for(var key in staticQueryAttributes) { - if(staticQueryAttributes.hasOwnProperty(key)) { - availableLabels.push(staticQueryAttributes[key].name); - } - } + var availableLabels = staticQueryAttributes; var promises = [imageMonkeyApi.getLabelAccessors(true)]; {{ if ne .sessionInformation.Username "" }} @@ -388,7 +403,7 @@
-

Search for annotation tasks you are interested in

+

Search for annotation tasks you are interested in

diff --git a/html/templates/modules/goto_labels_dlg.html b/html/templates/modules/goto_labels_dlg.html index df89a715..9afb634f 100644 --- a/html/templates/modules/goto_labels_dlg.html +++ b/html/templates/modules/goto_labels_dlg.html @@ -7,6 +7,8 @@ {{ if eq .type "object" }} settings.setAddLabelHotkey($("#recordAddLabelKeyInput").val()); settings.setLabelSeparator($('#labelSeparatorDropdown').dropdown('get value')); + + settings.setVimBindingsEnabled($('#vimBindingsCheckbox').checkbox('is checked')); {{ end }} {{ if eq .type "image" }} @@ -22,6 +24,10 @@ {{ if eq .type "object" }} $("#recordAddLabelKeyInput").val(settings.getAddLabelHotkey()); $('#labelSeparatorDropdown').dropdown('set selected', settings.getLabelSeparator()); + if(settings.vimBindingsEnabled()) + $('#vimBindingsCheckbox').checkbox('set checked'); + else + $('#vimBindingsCheckbox').checkbox('set unchecked'); {{ end }} {{ if eq .type "image" }} @@ -269,6 +275,19 @@

Settings

+ +
+
+
+ Vim Mode +

Enable/Disable Vim Bindings

+
+ + +
+
+
+
{{ end }} {{ if eq .type "image" }} diff --git a/html/templates/modules/label_browse_select_mode.html b/html/templates/modules/label_browse_select_mode.html index 3cdf2e9a..7c7195be 100644 --- a/html/templates/modules/label_browse_select_mode.html +++ b/html/templates/modules/label_browse_select_mode.html @@ -22,7 +22,7 @@ var currentLabeledImageGridElement = null; var infiniteScroll = new InfiniteScroll(loadNextImagesInImageGrid, false); var numberOfQueryResults = 0; - var numberOfCurrentlyShownResults = 0; + var numberOfCurrentlyShownResults = 0; var clearImageGrid = function() { justifiedLayoutGeometry = null; @@ -46,10 +46,16 @@ $("#labelQuerySearchContainer").show(); infiniteScroll.resume(); infiniteScroll.restoreScrollPosition(); + + //hide vim-mode status bar + $("#vimModeStatusBar").hide(); + labelBrowseModeVimBindings.setMode(LabelBrowseModeVimBindingsMode.Browse); } function handleRes(d) { $("#imageGrid").show(); + labelBrowseModeVimBindings.reset(); + labelBrowseModeVimBindings.enableListeners(); if(d !== null) { imageGridData = d; @@ -114,6 +120,7 @@ if($(elem).hasClass("grey-out")) return; + labelBrowseModeVimBindings.setMode(LabelBrowseModeVimBindingsMode.Label); var imageId = $(elem).attr("data-imageid"); currentLabeledImageGridElement = $(elem).attr("id"); $("#labelQuerySearchContainer").hide(); @@ -184,7 +191,7 @@ var imageUrl; var annotationsScaleFactor; var item; - for(var i = from; i < (from + n); i++){ + for(var i = from; i < (from + n); i++){ var url = getUrlFromImageUrl(imageGridData[i]["image"]["url"], imageGridData[i]["image"]["unlocked"]) + ((imageGridData[i]["image"]["unlocked"] === true) ? '?' : '&') + "width=" + Math.round(justifiedLayoutGeometry.boxes[i].width, 0) @@ -220,11 +227,11 @@ if(tooltipText.length > 2) tooltipText = tooltipText.substring(0, tooltipText.length - 2); //remove last comma + space - var imageId = ("galleryitem" + imageGridData[i]["image"]["uuid"]); + var imageId = ("galleryitem" + imageGridData[i]["image"]["uuid"]); item = newImageItem(imageId, url, imageGridData[i]["image"]["uuid"], justifiedLayoutGeometry.boxes[i].top, justifiedLayoutGeometry.boxes[i].left, justifiedLayoutGeometry.boxes[i].width, justifiedLayoutGeometry.boxes[i].height, tooltipText); $("#imageGrid").append(item); - + labelBrowseModeVimBindings.addImageId(imageId); document.getElementById("imageGrid").style.height = (justifiedLayoutGeometry.boxes[(from + n - 1)].top + justifiedLayoutGeometry.boxes[(from + n - 1)].height) + "px"; } @@ -233,6 +240,7 @@ numberOfCurrentlyShownResults = numOfLastFetchedImg; $("#numberOfQueryResults").text(numberOfCurrentlyShownResults + "/" + numberOfQueryResults + " results shown"); + } function getRandomInt(min, max) { @@ -276,11 +284,25 @@ new AutoCompletion("#labelQuery", availableLabels); + $("#labelQueryForm").form("settings", {keyboardShortcuts: false}); $("#randomLabelQueryButton").click(function(e) { var randomElem = availableLabels[getRandomInt(0, availableLabels.length - 1)]; $("#labelQuery").val(randomElem); }); + + $("#labelQuery").keyup(function(event) { + if(event.keyCode === 13) { //when enter inside input field is pressed + event.preventDefault(); + populateImageGrid(); + $("#labelQuery").blur(); + } + }); + + {{if ne .query "" }} + $("#labelQuery").val({{ .query }}); + $("#browseLabelsGoButton").click(); + {{ end }} }); @@ -290,9 +312,9 @@
- +
-

Search for images you are interested in

+

Search for images you are interested in

@@ -301,7 +323,7 @@
-
Go
+
Go

diff --git a/html/templates/modules/validate_browse_select_mode.html b/html/templates/modules/validate_browse_select_mode.html index 3bf049c6..15ffbfc9 100644 --- a/html/templates/modules/validate_browse_select_mode.html +++ b/html/templates/modules/validate_browse_select_mode.html @@ -372,7 +372,7 @@
-

Search for images you are interested in

+

Search for images you are interested in

diff --git a/html/templates/supportus.html b/html/templates/supportus.html index 63b887a0..43b72a63 100644 --- a/html/templates/supportus.html +++ b/html/templates/supportus.html @@ -44,7 +44,8 @@

-
+
+