Giter VIP home page Giter VIP logo

openalpr's Introduction

openalpr

OpenALPR is an open source Automatic License Plate Recognition library written in C++ with bindings in C#, Java, Node.js, Go, and Python. The library analyzes images and video streams to identify license plates. The output is the text representation of any license plate characters.

Check out a live online demo here: http://www.openalpr.com/demo-image.html

User Guide

OpenALPR includes a command line utility. Simply typing "alpr [image file path]" is enough to get started recognizing license plate images.

For example, the following output is created by analyzing this image: Plate Image

user@linux:~/openalpr$ alpr ./samplecar.png

plate0: top 10 results -- Processing Time = 58.1879ms.
    - PE3R2X     confidence: 88.9371
    - PE32X      confidence: 78.1385
    - PE3R2      confidence: 77.5444
    - PE3R2Y     confidence: 76.1448
    - P63R2X     confidence: 72.9016
    - FE3R2X     confidence: 72.1147
    - PE32       confidence: 66.7458
    - PE32Y      confidence: 65.3462
    - P632X      confidence: 62.1031
    - P63R2      confidence: 61.5089

Detailed command line usage:

user@linux:~/openalpr$ alpr --help

USAGE: 

   alpr  [-c <country_code>] [--config <config_file>] [-n <topN>] [--seek
         <integer_ms>] [-p <pattern code>] [--clock] [-d] [-j] [--]
         [--version] [-h] <image_file_path>


Where: 

   -c <country_code>,  --country <country_code>
     Country code to identify (either us for USA or eu for Europe). 
     Default=us

   --config <config_file>
     Path to the openalpr.conf file

   -n <topN>,  --topn <topN>
     Max number of possible plate numbers to return.  Default=10

   --seek <integer_ms>
     Seek to the specified millisecond in a video file. Default=0

   -p <pattern code>,  --pattern <pattern code>
     Attempt to match the plate number against a plate pattern (e.g., md
     for Maryland, ca for California)

   --clock
     Measure/print the total time to process image and all plates. 
     Default=off

   -d,  --detect_region
     Attempt to detect the region of the plate image.  [Experimental] 
     Default=off

   -j,  --json
     Output recognition results in JSON format.  Default=off

   --,  --ignore_rest
     Ignores the rest of the labeled arguments following this flag.

   --version
     Displays version information and exits.

   -h,  --help
     Displays usage information and exits.

   <image_file_path>
     Image containing license plates


   OpenAlpr Command Line Utility

Binaries

Pre-compiled Windows binaries can be downloaded on the releases page

Install OpenALPR on Ubuntu 16.04 with the following commands:

sudo apt-get update && sudo apt-get install -y openalpr openalpr-daemon openalpr-utils libopenalpr-dev

Documentation

Detailed documentation is available at doc.openalpr.com

Integrating the Library

OpenALPR is written in C++ and has bindings in C#, Python, Node.js, Go, and Java. Please see this guide for examples showing how to run OpenALPR in your application: http://doc.openalpr.com/bindings.html

Compiling

Build Status

OpenALPR compiles and runs on Linux, Mac OSX and Windows.

OpenALPR requires the following additional libraries:

- Tesseract OCR v3.0.4 (https://github.com/tesseract-ocr/tesseract)
- OpenCV v2.4.8+ (http://opencv.org/)

After cloning this GitHub repository, you should download and extract Tesseract and OpenCV source code into their own directories. Compile both libraries.

Please follow these detailed compilation guides for your respective operating system:

If all went well, there should be an executable named alpr along with libopenalpr-static.a and libopenalpr.so that can be linked into your project.

Docker

# Build docker image
docker build -t openalpr https://github.com/openalpr/openalpr.git
# Download test image
wget http://plates.openalpr.com/h786poj.jpg
# Run alpr on image
docker run -it --rm -v $(pwd):/data:ro openalpr -c eu h786poj.jpg

Questions

Please post questions or comments to the Google group list: https://groups.google.com/forum/#!forum/openalpr

Contributions

Improvements to the OpenALPR library are always welcome. Please review the OpenALPR design description and get started.

Code contributions are not the only way to help out. Do you have a large library of license plate images? If so, please upload your data to the anonymous FTP located at upload.openalpr.com. Do you have time to "tag" plate images in an input image or help in other ways? Please let everyone know by posting a note in the forum.

License

Affero GPLv3 http://www.gnu.org/licenses/agpl-3.0.html

Commercial-friendly licensing available. Contact: [email protected]

openalpr's People

Contributors

abankowski avatar alandtse avatar aybassiouny avatar ddobrev avatar engycz avatar fabaff avatar fredericoperimlopes avatar josephfrazier avatar jovargas avatar kees-v avatar manupap1 avatar masroore avatar matthill avatar mattndu avatar nayrnet avatar peters avatar psaintjust avatar robertocarvajal avatar sam-dieck avatar samislavath avatar sanathreddy04 avatar sarafalamaki avatar shaneqful avatar silex avatar splewis1 avatar steffkes avatar sunariescn avatar tweej avatar vebers avatar vzaliva 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  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

openalpr's Issues

Crowdsource ALPR training via Mechanical Turk

Amazon's Mechanical Turk (https://www.mturk.com/mturk/welcome) can be used as a cost-effective way to get human operators to tag license plate images for training data.

For this to work we would need a simplified, web-based training workflow. It would need:

  • An introductory training where users could be trained on the type of data needed
  • A validation set so that users who do not enter correct data would be disqualified
  • Training workflow for both plate regions (detection) and plate characters (OCR)

Invalid region code produced in json

This command:
./alpr /home/mhill/webservice/temp_uploads/5fa0beb7-002f-4b68-a59d-042c5ab18757.jpg -dj

on this image:
5fa0beb7-002f-4b68-a59d-042c5ab18757

Produces this output:
{"epoch_time":1409713153536,"processing_time_ms":303.881430,"results":[{"plate":"DRUPAL","confidence":95.113091,"matches_template":0,"region":"��#���","region_confidence":1,"processing_time_ms":238.184692,"coordinates":[{"x":187,"y":134},{"x":292,"y":134},{"x":292,"y":182},{"x":187,"y":182}],"candidates":[{"plate":"DRUPAL","confidence":95.113091,"matches_template":0},{"plate":"0RUPAL","confidence":85.834694,"matches_template":0},{"plate":"ORUPAL","confidence":85.360779,"matches_template":0},{"plate":"BRUPAL","confidence":84.456360,"matches_template":0},{"plate":"DR0PAL","confidence":83.963173,"matches_template":0},{"plate":"QRUPAL","confidence":83.164261,"matches_template":0},{"plate":"0R0PAL","confidence":74.684776,"matches_template":0},{"plate":"OR0PAL","confidence":74.210861,"matches_template":0},{"plate":"BR0PAL","confidence":73.306442,"matches_template":0},{"plate":"QR0PAL","confidence":72.014343,"matches_template":0}]}]}

OCR font recognition

Hello,

I used train-ocr to make it learn the switzerland fonts and added it to the eu dataset. When doing some tests with ocr debug set to 1 I was surprised to see that the font used was still the "germany" one, despite analyzing a swiss plate. The result for the plate is correct, tho.

The code showing the font is:

const char* fontName = ri->WordFontAttributes(&dontcare, &dontcare, &dontcare, &dontcare, &dontcare, &dontcare, &pointsize, &fontindex);

Do you have a short explanation of how tesseract is used and how it choses which trained font to use? does it try all of them and pick the best match?

Add character height as a function that affects confidence

Smaller characters (lower resolution plates) should have lower confidence. When the plate gets closer and the characters are large, the confidence should reflect the higher probability of an accurate read. Since plate image sizes are normalized, the cropped size has to be mapped back to the original image to get an accurate size.

Recrop plate region before identifying edges

The example below had to fall back to a best-guess for plate edge. The area identified by plate detection was too small. Given that the characters were properly identified, the plate area should be recropped (only in cases where it is too small based on the character height) before sending to platelines. The plate edges are strong and would likely be properly identified.

From benchmark db: us/car9-1.jpg

image

Save clipped images

If we could have an option to save the clipped images too that would be good, and helpful to automatically gather appropriate images for training OCR.

Steve

min/max plate size: poor naming/confusing

Hello,

The doc says:

template_max_width_px = [maximum width of the plate before processing. Should be proportional to the plate dimensions]
template_max_height_px = [maximum height of the plate before processing. Should be proportional to the plate dimensions]
min_plate_size_width_px = [Minimum size of a plate region to consider it valid.]
min_plate_size_height_px = [Minimum size of a plate region to consider it valid.]

And then when I read the code I see that:

  Size minSize(config->minPlateSizeWidthPx * this->scale_factor, config->minPlateSizeHeightPx * this->scale_factor);
  Size maxSize(w * config->maxPlateWidthPercent * this->scale_factor, h * config->maxPlateHeightPercent * this->scale_factor);

Which actually correspond to:

max_plate_width_percent = 100
max_plate_height_percent = 100

This is rather confusing and unclear. I propose a renaming of the variable and some cleanup, maybe remove max_plate_width_percent entirely and use template_max_width_px which would be renamed to max_plate_size_width?

I started a pull request and realised I wasn't sure of what I was doing, can you help me go in the correct direction? Right now it looks like you specify min plate size in terms of pixels, max plate size in terms of %, and max plate size in terms of pixel but just for ocr?

error LNK2019

Anyone has ideas about his? I did build tesseract 3.02 in VS2012 by myself. When I build alpr, quite a few link errors like below happen. Thanks for your help.

Error 732 error LNK2019: unresolved external symbol "public: float thiscall tesseract::ChoiceIterator::Confidence(void)const " (?Confidence@ChoiceIterator@tesseract@@QBEMXZ) referenced in function "public: void thiscall OCR::performOCR(class std::vector<class cv::Mat,class std::allocator >,class std::vector<class cv::Rect,class std::allocator<class cv::Rect > >)" (?performOCR@OCR@@QAEXV?$vector@VMat@cv@@v?$allocator@VMat@cv@@@std@@@std@@v?$vector@V?$Rect@h@cv@@v?$allocator@V?$Rect@h@cv@@@std@@@3@@z) I:\WorkingProjects\References\openalpr-build\openalpr\ocr.obj openalpr

Support multi-line plates

Europe, Japan, Pakistan all use 2-line license plates. Supporting these plates will require training data and modifications to the Character Analysis code.

image

image

image

`-j` option doens't care about `-n` (only prints best match)

Hello,

When using -j, it only prints the "best match" and not all the matches like -n does on the command line.

Is this intentional? it's kinda annoying because right now my plate is often in the top 5 results but not always the top 1, and parsing the output without -j kinda defeats the point :)

Add video support via plate tracking across frames

Using sparse mode optical flow tracking, the library should be able to track plate regions from frame to frame in a video. This would improve accuracy by:

  • Reducing false positives. A plate must be seen multiple times to be considered valid
  • Providing more reads per plate (higher accuracy reads would be used)
  • Remove double-counting of reads

This will likely be very processor intensive, and should be implemented as a GPU-only feature.

tesseract.lib problems

I am using Visual Studio 2013 to try to build OpenALPR. After fixing numerous errors I have reached a point where I can go no further. I don't know if I am using a newer version of tesseract, or if something else is going on, but here is my problem:
When I build Tesseract I cannot find a tesseract.lib file (Which is needed for classifychars and benchmark projects). I tried replacing tesseract.lib with libtesseract302.lib in the classifychars property pages under linker->input->additional dependencies, but then I get compiler error "LNK2019: Unresolved external symbol public:float __thiscall tesseract::choiceIterator::confidence " when I try to build classifychars. (Note that there are total of 6 errors when I build, 5 are similar and they all have to do with the choiceIterator: constructor, destructor, Next, GetUTF8Text, and of course confidence. The last is error LNK1120, which is a count of the other errors.) I am using Tesseract 3.02.02. I am new to Tesseract, OpenCV, and OpenALPR so any help would be greatly appreciated.

Installation issue

Hi, I'm trying to install using the easiest method on README.md
after I run the command sudo apt-get update I get this error:

W: Failed to fetch gzip:/var/lib/apt/lists/partial/deb.openalpr.com_master_dists_openalpr_main_binary-amd64_Packages Encountered a section with no Package: header

E: Some index files failed to download. They have been ignored, or old ones used instead.

what can I do to fix it?

update: when I use the easy method with contains downloading dependencies and compiling openalpr I get this error:
-- Found Tesseract
CMake Error at CMakeLists.txt:47 (MESSAGE):
OpenCV version is not compatible : 2.4.1

-- Configuring incomplete, errors occurred!

What is the Tesseract_DIR?

Could you tell me how to configuration the Tesseract_DIR ?

In the README.we can see blow:

  • SET(Tesseract_DIR "/home/mhill/projects/alpr/libraries/tesseract-ocr").

I was down tesseract-3.00,install to my ubuntu and test was ok.But when i make openalpr.It tell me [ocr.h:37:21: baseapi.h:There is no this file].

I think i configuration the Tesseract_DIR error. now was [SET(Tesseract_DIR "/git/tesseract-3.00/api/.libs")] , And Tesseract is in /git/tesseract-3.00/。

tesseract path
_9z8 cay k6freq epem

Error message
aplr

Add rotation attribute to alprd

Alprd can rotate input image by x degrees to get better accuracy. If the camera is fixed and rotated x degree, alprd can compensate for this by rotating the image before analyzing

Add a namespace to the library

Hi,

Good work!

I am testing the library as a plugin for the ZoneMinder CCTV software.

The alpr object is loaded dynamically, plates are detected but every time I delete the alpr object I get a segmentation fault.

I found the cause: Conflict of class name

Class "Detector" and "Config" are defined in OpenALPR but also in ZoneMinder

Although these classes are used only internally in the OpenALPR library, the duplication of class name leads to unattended errors.

I temporary fixed the issue by enclosing the conflicting OpenALPR classes in the namespace "alpr".

To avoid this kind of problems (especially with very common class names), the OpenALPR library should provide his own namespace.

Emmanuel Papin

OpenCV >=v2.4.8 required

The README.md claims "OpenCV v2.4.x " is required for compiling. Build scripts indicate OpenCV >= 2.4.8 is required.

From ../src/CMakeLists.txt about line 55:

IF (${OpenCV_VERSION} VERSION_LESS 2.4.8)
MESSAGE(FATAL_ERROR "OpenCV version is not compatible : ${OpenCV_VERSION}")
ENDIF()

How to modify license plates formats

Hello,

I'd like to use openalpr to scan various types of license plates.

  1. Is there an easy way to create a new plate format?
  2. Is there an easy way to have a "catch all" format which yields good results?

In general, how do you handle license plate recognition when you expect several formats?

[EDIT] I just found about the -d option, is that the way to go?

Configurable character height filter

Some countries use characters that have characters which are not fully connected (e.g., Serbian zero characters). The height filter (in character segmentation) should be configurable per-country and should be turned off for EU.

zeros_orig
zeros

Support unicode characters

Copied from Roya Gh forum post:

I want to add support for plates of a new country to OpenAlpr so that it can recognize the license plates of Iran.
I've tained tesseract for persian and it works for Iimages of Persian text,
but when I try to use OpenAlpr the output is sth like this:

plate0: 9 results
- лллллилл confidence: 83.9618 template_match: 0
- лллллил confidence: 81.1455 template_match: 0
- ллйлллил confidence: 81.0826 template_match: 0

I've tarined for unicode but I've realized that OpenAlpr doesn't use UTF8, I suppose that the problem is due to this,

const char* choice = ci.GetUTF8Text();
postProcessor->addLetter(*choice, j, ci.Confidence());

here https://github.com/openalpr/openalpr/blob/master/src/openalpr/ocr.cpp#L104

Is there any implementation of OpenAlpr supporting UTF8?

Add mask region to alpr daemon

There are certain areas in the input stream that we don't wish to attempt detection (e.g., sky, a fence area, a timestamp). Add a black/white mask image as input (resolution must match input stream) that will not attempt detection.

This should be implemented in such a way that it both decreases false positives and improves performance (since less of the image must be analyzed).

Add output when no plate is found

The alpr binary should report that no plate is found when recognition is unsuccessful. Json output should remain as-is (i.e., returns an empty set: [])

Letter I not detected in European plates

Hi,

I've noticed the letter 'I' (capital i) doesn't get detected in my plates, please check the given example.

imag0555 - kopie
Any thoughts on this?

Thanks!

Kind regards,
Ben

Alternate license

Is it possible to offer an alternative license to AGPL? Any license which doesn't require open sourcing proprietary code or offering an optional commercial license would fit our requirements (free users use AGPL, commercial users pay $ and keep their code closed source).

Thanks, Daniel.

Problem with training for different country

Hello!
I am trying to train openalpr for Bulgarian plates.

I have a cropped images with license plates and I am running classifychars. It gives me this error:

OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /opencv/opencv-2.4.8/modules/core/src/array.cpp, line 2482
terminate called after throwing an instance of 'cv::Exception'
what(): /opencv/opencv-2.4.8/modules/core/src/array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat

Please advice.

ocr.h lacks "#include "resultiterator.h" and alpr segfault

Hello,

To compile on ubuntu 12.04, I had to add #include "resultiterator.h" in ocr.h:

/home/philippe/work/openalpr/src/openalpr/ocr.cpp: In member function ‘void OCR::performOCR(std::vector<cv::Mat>, std::vector<cv::Rect_<int> >)’:
/home/philippe/work/openalpr/src/openalpr/ocr.cpp:84:32: error: invalid use of incomplete type ‘struct tesseract::ResultIterator’
/usr/include/tesseract/baseapi.h:83:7: error: forward declaration of ‘struct tesseract::ResultIterator’

And then the binary segfaulted in ocr.cpp around line 100;

const char* choice = ci.GetUTF8Text();
postProcessor->addLetter(*choice, j, ci.Confidence());

It segfault because choice is value 0x0. If I comment the whole "post-process" block then it still work and gives decent results.

I did install opencv manually and for tesseract I did "apt-get install libtesseract-dev", which is version 3.02.01-2.

Any idea about why I get the segfault?

How to get the region of a plate?

Hi,

I am a newbie and would love to use openalpr to read some license plates into a database. Unfortunately, I am having trouble with the region detection so I am wondering if I am doing something wrong or whether it is just not good.

I am running the command "alpr -d license.jpg -r <runtime_dir>" to try to get the region into the output. The license plate is reading fine but I get (no region)

plate0: 6 results -- Processing Time = 245.592ms.
- 478HM2 confidence: 89.4472 template_match: 0
- 478HN2 confidence: 81.5051 template_match: 0
- 478H2 confidence: 80.1997 template_match: 0

if I add the json flag, I see:

[{"plate":"478HM2","confidence":89.447197,"matches_template":0,"region":"","region_confidence":0,"processing_time_ms":100.312790,"coordinates":[{"x":405,"y":311},{"x":545,"y":308},{"x":545,"y":385},{"x":405,"y":385}],"candidates":............

So it looks for this plate, it just can't get the region. (It's Massachusetts but the plate is on the car and somewhat obscured.)

I also tried on a VT and NH plate and it guessed "GA" and "OK".

I attached the last 2 here in case someone is kind enough to advise and interested in seeing them. Thanks in advance!

image-1
image

Use better angle value for edge detection

The angle of the edge of the plate can be better determined by examining the angle of the characters. In the picture attached, notice that the first pass (charanalysis) identified a few valid characters. Looking at the edges of the U character, we know the angle of the edge that we're looking for. It should be slanted backwards. Without this knowledge, the edge detector picked a vertical line instead.

image

Invalid json output

When printing as json the resulting output is invalid:

{"epoch_time":1408627909,"processing_time_ms":67.107000,"results":[]}
No license plates found.

The message "No licence plate found" should only be printed in the console, not to json.

wrong paths in the provided windows release

After loading and extracting openalpr.windows.zip, I run

alpr.exe sample.jpg

I get the following error

--(!)Runtime directory 'C:/projects/openalpr/src/../runtime_data/' does not exist!
--(!)Error loading classifier
Tesseract couldn't load any languages!
OpenCV Error: Assertion failed (scaleFactor > 1 && image.depth() == CV_8U) in cv::CascadeClassifier::detectMultiScale, file src\cascadedetect.cpp, line 1081

Sure, this workaround helps

xcopy /e runtime_data\ c:\projects\openalpr\runtime_data

but a relative path would be nicer I think. Especially for users without writing permission to c:.

Multi-threading does not improve performance

Running OpenALPR in multiple forked processes does increase the performance significantly. However, the multi-threading within a single process never increases performance.

Currently, OpenALPR has a multi-threading function implemented (controllable by setting the number of cores in openalpr.conf). But it does not work. Threads are instantiated correctly, but they are just as slow if not slower than if the processing was run serially.

Bountysource

Auto mask

Some method of taking note of the positions of plates that are recognised and forming a mask to only analyse those areas would be a great feature.

Cheers

Steve

Use Yelp's MOE to estimate ideal ALPR parameters

Setup a system that automatically modifies parameters, then runs a benchmark. The result should be piped into MOE to get the statistically optimal values.

For example, plate corner detection uses a number of tuneable weights. A benchmark could vary these values and re-run the benchmark and have MOE evaluate the best settings.

Many other ALPR machine-learning parameters could be analyzed in a similar way.

https://github.com/Yelp/MOE

Shadow detection/removal

The shadow bisecting the plate image causes errors in the OCR output. In this case, the "J" is believed to be a "3"

plate113

image

Compiling problem

Hi!

I'm trying to build this on Raspbian, but 'make' fails. I'm sort of new to github and how to properly format a bugreport/problem, so bare with me :)

Here is the output from "make" after following the instructions for installation:
http://pastebin.com/dK90kie5

Any suggestions?

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.