Code Monkey home page Code Monkey logo

alvarocavalcante / auto_annotate Goto Github PK

View Code? Open in Web Editor NEW
148.0 5.0 32.0 55.47 MB

Labeling is boring. Use this tool to speed up your next object detection project!

Home Page: https://medium.com/p/acf410a600b8#9e0e-aaa30a9f4b7a

License: Apache License 2.0

Python 49.07% Jupyter Notebook 50.93%
tensorflow labeling-tool object-detection annotation-tool computer-vision dataset-generation pattern-recognition python python3 semi-supervised-learning

auto_annotate's Introduction

auto-annotate-logo

Colab

Auto Annotation Tool for TensorFlow Object Detection

Are you tired to label your images by hand when working with object detection? Have hundreds or thousands of images to label? Then this project will make your life easier, just create some annotations and let the machine do the rest for you!

Contents

๐Ÿค” How it works

This auto annotation tool is based on the idea of a semi-supervised architecture, where a model trained with a small amount of labeled data is used to produce the new labels for the rest of the dataset.

As simple as that, the library uses an initial and simplified object detection model to generate the XML files with the image annotations (considering the PASCAL VOC format). Besides that, it's possible to define a confidence threshold for the detector, acting as a trade-off for the generated predictions.

If you want to know more technical details about the project, please, refer to my Medium article.

๐Ÿ“ Prerequisites

To use this library you will need a pre-trained object detection model with a subsample of your dataset. As a semi-supervised solution, it's impossible to avoid manual annotation, but you'll need to label just a small amount of your data.

It's hard to determine the number of images to label manually, once it depends on the complexity of your problem. If you want to detect dogs and cats and have 2000 images in your dataset, for example, probably 200 images are enough (100 per class). On the other hand, if you have dozens of classes or objects that are hard to detect, you should need more manual annotations to see the benefits of the semi-supervised approach.

After training this initial model, export your best checkpoint to the SavedModel format and you'll be ready to use the auto annotation tool!

๐Ÿ’พ Installation

It's recommended to use a Python virtual environment to avoid any compatibility issue with your TensorFlow version.

In your environment, you can install the project using pip:

pip install auto-annotate

๐Ÿ‘จโ€๐Ÿ”ฌ Usage

You can use this tool either from the command line or directly in your Python code. For both, you'll have the same set of parameters:

  • saved_model_path: The path of the saved_model folder with the initial model.
  • label_map_path: The path of the label_map.pbtxt file.
  • imgs_path: The path of the folder with your dataset images to label.
  • xml_path (optional): Path to save the resulting XML files. The default behavior is to save in the same folder of the dataset images.
  • threshold: Confidence threshold to accept the detections made by the model. the defaults is 0.5.

Command line

To use this tool from the command line, you just need to run:

python -m auto_annotate --label_map_path /example/label_map.pbtxt \
--saved_model_path /example/saved_model \
--imgs_path /example/dataset_images \
--xml_path /example/dataset_labels \
--threshold 0.65

Code

To use this tool from your Python code, check the following code snippet:

from auto_annotate import AutoAnnotate

ann_tool = AutoAnnotate(
              saved_model_path = '/example/saved_model',
              label_map_path = '/example/label_map.pbtxt',
              images_path = '/example/dataset_images',
              xml_path = '/example/dataset_labels',
              detection_threshold = 0.65)

ann_tool.generate_annotations()

Google Colab

For a complete working example, you can refer to this Google Colab Notebook, where I share the details about installlation and setup.

๐Ÿค Contribute

Contributions are welcome! Feel free to open a new issue if you have any problem to use the library of find a bug!

You can also use the discussions section to suggest improvements and ask questions! If you find this library useful, don't forget to give it a โญ or support the project:

Buy Me a Coffee at ko-fi.com

auto_annotate's People

Contributors

alvarocavalcante avatar dependabot[bot] avatar lucs1590 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

auto_annotate's Issues

Annotations are not generated

Hi,

I am trying to auto annotate a set of custom images. The initial mode is trained using 'Ultralytics Yolov5s' and saved_model is generated. When I try executing the following code

from auto_annotate import AutoAnnotate

ann_tool = AutoAnnotate(
              saved_model_path = './saved_model',
              label_map_path = './label_map.pbtxt',
              images_path = './dataset_images',
              xml_path = './dataset_labels',
              detection_threshold = 0.65)

ann_tool.generate_annotations()

Following messages are displayed in the terminal

_Python inputs incompatible with input_signature:
inputs: (
tf.Tensor(
[[[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]

...

[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]]], shape=(1, 640, 640, 3), dtype=uint8))
input_signature: (
TensorSpec(shape=(1, 640, 640, 3), dtype=tf.float32, name=None))._

There are no annotations generated in the 'dataset_labels' folder. Can you please help with the same ?

Regards
Karthik

Could not find matching concrete function to call loaded from the SavedModel

Could not find matching concrete function to call loaded from the SavedModel. Got:
Positional arguments (3 total):
* <tf.Tensor 'inputs:0' shape=(1, 492, 423, 3) dtype=uint8>
* False
* None
Keyword arguments: {}

Expected these arguments to match one of the following 4 option(s):

Option 1:
Positional arguments (3 total):
* TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name='input_1')
* False
* None
Keyword arguments: {}

can you please tell me what can be the issue as I have taken the model from saved model link provided in guide line.

How to save the output labels with the original image names

Dear Alvaro,

Thank you for your hard work on this. I tested this, its very useful in overcoming the time-consuming task of labeling. Could you please give me some suggestion on how can I retain the original names for the output images and labels. Currently, I am getting images_1 ... images_N in in results folder and images_1 ... images_N in xml folder. Another thing is that, output labels contains the original image size not the reduced size. For example, If original image size is m x n, the output labels also show m x n and not the reduced size. Could you please take a look? Thank you.

visualize_boxes_and_labels_on_image_array() got an unexpected keyword argument 'file_name'

`import os
import numpy as np
import argparse
from PIL import Image, ImageOps
import cv2
from matplotlib import pyplot as plt

import tensorflow as tf

from object_detection.utils import visualization_utils as viz_utils
from object_detection.utils import label_map_util

def infer_images(detect_fn, image, category_index, file_name, draw_image=True):
print('file name =', file_name)
image_np = np.array(image)
input_tensor = tf.convert_to_tensor(image_np)
input_tensor = input_tensor[tf.newaxis, ...]

name = file_name

detections = detect_fn(input_tensor)

num_detections = int(detections.pop('num_detections'))
detections = {key: value[0, :num_detections].numpy()
            for key, value in detections.items()}
detections['num_detections'] = num_detections

detections['detection_classes'] = detections['detection_classes'].astype(np.int64)

image_np_with_detections = image_np.copy()

if draw_image:
  viz_utils.visualize_boxes_and_labels_on_image_array(
      image_np_with_detections,
      detections['detection_boxes'],
      detections['detection_classes'],
      detections['detection_scores'],
      category_index,
      file_name=file_name,
      use_normalized_coordinates=True,
      max_boxes_to_draw=200,
      min_score_thresh=.20,
      agnostic_mode=False)



return image_np_with_detections

parser = argparse.ArgumentParser(description='Auto annotation arguments.')
parser.add_argument('--labelmap', help='The path of the label_map file.')
parser.add_argument('--saved_model', help='The path of the saved model folder.')
parser.add_argument('--imgs', help='The path of the images that will be annotated.')

args = parser.parse_args()

category_index = label_map_util.create_category_index_from_labelmap(args.labelmap,
use_display_name=True)

detect_fn = tf.saved_model.load(args.saved_model)

for img in os.listdir(args.imgs):
try:
file_name = img.split('.')[0]
img = np.array(ImageOps.exif_transpose(Image.open(args.imgs+'/'+img)))
result_img = infer_images(detect_fn, img, category_index, file_name)

    result_img = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)
    cv2.imwrite('./results/'+ file_name + '.jpg', result_img)
except Exception as e:
    print('Error to process image {}'.format(file_name))
    print(e)`

When trying to run this on a series of jpg images, I get the following error:
visualize_boxes_and_labels_on_image_array() got an unexpected keyword argument 'file_name'

If I comment out the file_name argument, it works and detects objects and draws bounding boxes, however, I don't receive any XML files.

Thanks for any help!

Question about TSODA

@AlvaroCavalcante

I saw your TSODA.ipynb. Wonderful work. I was wondering if you could please help with some issues I am facing. I am getting this error

Failed to get matching files on /content/tf-models/research/fine_tuned_model/model.ckpt: Not found: /content/tf-models/research/fine_tuned_model; No such file or directory
MODEL TRAINED

I did not find some details about fine_tuned_model folder. Could you please explain why we need this folder and should I manually create it? Does this folder is supposed to be empty from the start?

Also, I could not simulate your original TSODA.ipynb on google colab. I am getting the following error:

ValueError: ssd_inception_v2 is not supported. See `model_builder.py` for features extractors compatible with different versions of Tensorflow
MODEL TRAINED 

Could you please help with it? Thanks.

Version issue within the setup.py

Hello, I am trying to install the auto_annotate with pip as you have recommended. But as per your setup.py file, Pillow=7.0.0 version is recommended but while installation of auto_annotate through pip, it shows the following error

image

I tried to separately install Pillow 7.0.0 version but still not able to downgrade from 9.2 to 7.0. I also saw 1 pull request for the same. Is it possible for you to pull the requests for the versions as few older versions are not being able to downgrade.

google.protobuf.message.DecodeError: Error parsing message

(tensorflow) zhu@zhu-Nitro-AN515-51:~/auto_annotate$ python3 scripts/detection_images.py
2021-04-06 18:16:53.498679: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /opt/ros/melodic/lib
2021-04-06 18:16:53.498699: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.

WARNING:tensorflow:From /home/zhu/anaconda3/envs/tensorflow/lib/python3.8/site-packages/tensorflow/python/compat/v2_compat.py:96: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term
Traceback (most recent call last):
File "scripts/detection_images.py", line 45, in
od_graph_def.ParseFromString(serialized_graph)
google.protobuf.message.DecodeError: Error parsing message

I'm new to this. I try to find answer from stackoverflow but nothing can help.
I'm using Tensorflow 2.4

How to get pretrained model and what is it trained on?

Hi @AlvaroCavalcante ,
I am trying to understand the logic behind the automatic annotation.
Is the concept as follows:
-you label a few instances of data for your use case.
-Use this data to train a pre-trained object detection model.
-Then use the fine-tuned model to make bounding box inference on new data?

How to set the dimensions for the bounding box?

Is there any way I can set the predefined dimensions of bounding box for my images?

On running the script of "detection_img_tf2.py" it actually creates the dimensions on images by its own but for my case, I actually want to predefine its dimensions for a particular image.

I would like to present the same with an example of what currently is happening with me.

Image 1:
Image_212

Image 2:
Image_195

On running the script it creates the bounding box for this 2 almost identical images but boxes are having different dimensions and also it is detecting the label in image 1 with wrong dimensions but actually it should detect the label in image 2 and also it should draw the dimensions as in image 2 for all images inside the folder but it is not making it. So I want to know if I can define the dimensions for the box beforehand.

Also what model can I actually use for such custom images as from 1k images from the folder it only detects around 12-15 with label and create xml files for the same? Currently I am using the ssd_mobilenet_320x320_coco2017 model file for this.

Question: I am trying to auto_annotate images using google collab but getting this error.

THE ERROR:

2023-04-13 13:39:21.365592: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. 2023-04-13 13:39:22.331926: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/lib64-nvidia 2023-04-13 13:39:22.332041: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/lib64-nvidia 2023-04-13 13:39:22.332060: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly. Loading model into memory... 2023-04-13 13:39:25.709694: W tensorflow/core/common_runtime/gpu/gpu_bfc_allocator.cc:42] Overriding orig_value setting because the TF_FORCE_GPU_ALLOW_GROWTH environment variable is set. Original config value was 0. Loading label map... Found 1036 images to annotate. 0% 0/1036 [00:00<?, ?it/s]'_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable '_UserObject' object is not callable 2% 20/1036 [00:00<00:05, 199.26it/s]'_UserObject' object is not callable

Is this the problem with collab env or some other problem?

XML result path dynamically

When using the auto annotate tool, mainly in version 2.x of the TF, we could pass all the arguments dynamically on the command line! The problem is that the generate_xml.py file still has a hardcoded path that needs to be replaced with a dynamic option, as saw in the line below:

arquivo.write('your-local-path-here/xml/' + self.file_name + '.xml')

The idea of this issue is to create a new argument on the file detection_img_tf2.py that contains the XML path that the user wants to get the results.

The argument must be passed to the generate_xml.py and the XML results must appear in the folder specified in the arguments when calling the execution command!

tensorflow.python.framework.errors_impl.NotFoundError: /path-label-map.pbtxt; No such file or directory

Traceback (most recent call last):
File "/Users/advaitgupta/auto_annotate/scripts/detection_img_tf2.py", line 51, in
category_index = label_map_util.create_category_index_from_labelmap(args.labelmap,
File "/Users/advaitgupta/Tensorflow/tf2_api_env/lib/python3.9/site-packages/object_detection/utils/label_map_util.py", line 360, in create_category_index_from_labelmap
categories = create_categories_from_labelmap(label_map_path, use_display_name)
File "/Users/advaitgupta/Tensorflow/tf2_api_env/lib/python3.9/site-packages/object_detection/utils/label_map_util.py", line 340, in create_categories_from_labelmap
label_map = load_labelmap(label_map_path)
File "/Users/advaitgupta/Tensorflow/tf2_api_env/lib/python3.9/site-packages/object_detection/utils/label_map_util.py", line 168, in load_labelmap
label_map_string = fid.read()
File "/Users/advaitgupta/Tensorflow/tf2_api_env/lib/python3.9/site-packages/tensorflow/python/lib/io/file_io.py", line 114, in read
self._preread_check()
File "/Users/advaitgupta/Tensorflow/tf2_api_env/lib/python3.9/site-packages/tensorflow/python/lib/io/file_io.py", line 76, in _preread_check
self._read_buf = _pywrap_file_io.BufferedInputStream(
tensorflow.python.framework.errors_impl.NotFoundError: /path-label-map.pbtxt; No such file or directory

Running detection_img_tf2.py [...] resulting in AttributeError: ... 'cv2' has no attribute

I currently have installed TF2 via the instructions on this git repo using the docker options and have run the Object Detection test code mentioned in this issue. After placing the desired files from the Auto_Annotate script folder and running the referenced TF2 python command,

python3 scripts/detection_img_tf2.py --saved_model /path-saved-model --labelmap /path-label-map.pbtxt --imgs /path-of-the-imgs

I receive the following set of errors.

C:\Users\name\Downloads\auto_annotate-master\auto_annotate-master>python3 scripts/detection_img_tf2.py --saved_model /path-saved-model --labelmap /path-label-map.pbtxt --imgs /path-of-the-imgs
Traceback (most recent call last):
  File "C:\Users\name\Downloads\auto_annotate-master\auto_annotate-master\scripts\detection_img_tf2.py", line 5, in <module>
    import cv2
  File "C:\Users\name\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\cv2\__init__.py", line 181, in <module>
    bootstrap()
  File "C:\Users\name\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\cv2\__init__.py", line 175, in bootstrap
    if __load_extra_py_code_for_module("cv2", submodule, DEBUG):
  File "C:\Users\name\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\cv2\__init__.py", line 28, in __load_extra_py_code_for_module
    py_module = importlib.import_module(module_name)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "C:\Users\name\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\cv2\gapi\__init__.py", line 290, in <module>
    cv.gapi.wip.GStreamerPipeline = cv.gapi_wip_gst_GStreamerPipeline
AttributeError: partially initialized module 'cv2' has no attribute 'gapi_wip_gst_GStreamerPipeline' (most likely due to a circular import)

Is the command above supposed to be modified with custom paths entered in these sections? /path-saved-model /path-label /path-of-the-imgs?

A way to set the min confidence level of the auto labels?

Hi Alvaro, awesome code thanks!

Is there a way to only save the labels with a confidence over a certain percent?

For example, in the following image can we only auto label with confidence over 40% to exclude the miss labelled grass?
Screenshot from 2021-10-10 17-27-19

I have been searching the code but cannot see anywhere to set anywhere.

Thanks,
Tully

xml files are not getting created

on running the script , xml images are not created but there is properly annotated jpg files in results folder. Any idea why this is happening?

Need Help

Thanks

How to get pretrain model?

Hello Alvaro, thanks for the nice tool.
I am trying to use your idea.

Would you kindly let me know the way to get pretrained model?
Thanks.

One more thing, so tf model folder and auto_annotate stays separately of do i have to put tf model inside of auto_annotate?

Error running the code.

I have successfully completed all the steps till running detection_images.py, but I encounter an error while running the script.
The below is the error I encountered. Do you know what's wrong? Thanks in advance

2021-06-16 10:11:51.834111: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
WARNING:tensorflow:From /usr/local/lib/python3.7/dist-packages/tensorflow/python/compat/v2_compat.py:96: disable_resource_variables (from tensorflow.python.ops.variable_scope) is deprecated and will be removed in a future version.
Instructions for updating:
non-resource variables are not supported in the long term
Error parsing message

using yolov5 model

Can I use this method for labeling data set for yolov5 model ?
I have very large data set for yolov5 model for object detection

xml for multiple class names

Hello @AlvaroCavalcante , this script is running well.
I have multiple class names and it appears in the detected image, but I only get one class name for all bounding box in the xml file.
Could you help me please?
Thank you

Error parsing message

Error:
od_graph_def.ParseFromString(serialized_graph)
google.protobuf.message.DecodeError: Error parsing message

Tensorflow version ==2.0.0

The issue remains consistent with all versions of tensorflow 2.he

I have tested it models trained and frozen by google as well.

detection_graph = tf.Graph()
with detection_graph.as_default():
    od_graph_def = tf.GraphDef()
    with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
        serialized_graph = fid.read()
        od_graph_def.ParseFromString(serialized_graph) --------------------------------- error
        tf.import_graph_def(od_graph_def, name='')

I have tried all the possible solutions I found online. It seems to be a common issue.

XML generated are distorted when opened in LabelImg annotation tool

Hello @AlvaroCavalcante , Thanks for your previous responses. I have encountered new problem i.e, after generating the XML files when I try to open the folder which has image and its xml file in LabelImg tool ,I can see the bounding boxes with right co-ordinates but it is not annotated on the right part it is distorted in the image.

Example : if there are classes A,B,C I can see three bounding boxes when I open in LabelImg tool but all those 3 boxes are not annotated on the particular part . It is like bounding boxes are drawn but not on that particular part.

So this makes life tough again re-arranging the boxes by checking which class does the box belongs to .

I will be glad if you can help me resolve this issue , so I can post all the new changes that I did to get the better results which will help others who are facing same issues.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.