Giter Club home page Giter Club logo

topsup's Introduction

答题辅助

这两天冲顶大会之类的直播答题 APP 突然火了起来,萌生了使用截图,文字识别,搜索来玩答题的想法。

因为截图时间、搜索结果等限制,使用文字识别搜索,能提供的辅助作用有限。

非常感谢关注,欢迎大家 PR 更多有趣的想法和优化。

目录

更新日志

  • 2018.01.14
    • 文字识别方法集成 baidu ocr ,相对来说识别快 ,可在运行代码中选择想要用的 ocr 方式
    • 题目和选项一次截取识别
    • 将需要配置的参数统一调整到 config/configure.conf
  • 2018.01.12
    • 修复 windows 命令行颜色乱码,处理一些识别错误
  • 2018.01.11
    • 修复搜索可能的乱码等一些问题,多线程加快执行
  • 2018.01.10
    • 增加循环,无需重复加载,优化逻辑和显示 来自 issue #7。增加部分手机截图设置
    • 增加了截图传输效率,修改了识别参数,对图像进行灰度转化,去干扰,增加了识别准确率。结果判断使用了三种方式,对不同问题可以参考不同结果。

具体做法

  1. ADB 获取手机截屏
adb shell screencap -p /sdcard/screenshot.png
adb pull /sdcard/screenshot.png .
  1. OCR 识别题目与选项文字

​ 两个方法:

  • 谷歌 Tesseract ,安装软件即可,不同电脑配置运行效率不同
  • 百度 OCR ,需要注册百度 API,每天调用次数有限
  1. 搜索判断

结果判断方式

  1. 直接打开浏览器搜索问题
  2. 题目+每个选项都通过搜索引擎搜索,从网页代码中提取搜索结果计数
  3. 只用题目进行搜索,统计结果页面代码中包含选项的词频

以下为两个示例结果

参考了 I Hacked HQ Trivia But Here’s How They Can Stop Me

使用步骤 (谷歌 Tesseract)

Android

1. 安装 ADB

windows

下载地址:https://adb.clockworkmod.com/ ,并配置环境变量

Mac

使用 brew 进行安装 brew cask install android-platform-tools

安装完后插入安卓设备且安卓已打开 USB 调试模式,终端输入 adb devices ,显示设备号则表示成功。我手上的机子是坚果 pro1,第一次不成功,查看设备管理器有叹号,使用 handshaker 加载驱动后成功,也可以使用豌豆荚之类的试试。

List of devices attached
6934dc33    device

若不成功,可以参考Android 和 iOS 操作步骤进行修改

2. 安装 python 3

3. 安装所需 python 包

命令行: pip install -r requirements.txt

或者

pip install pytesseract
pip install pillow  
pip install requests
pip install colorama
pip install baidu-aip

4. 安装 谷歌 Tesseract

Windows下链接: 推荐使用安装版,在安装时选择增加中文简体语言包

其他系统: https://github.com/tesseract-ocr/tesseract/wiki

5. 修改 config/configure.conf 中相应参数信息

[region]
# 题目与选项区域
question_region = 50, 350, 1000, 560
choices_region = 75, 535, 1000, 1200

# 题目和选项一起的区域
combine_region = 50, 350, 1000, 1200

[tesseract]
# windows
# tesseract 安装路径
tesseract_cmd = C:\\Program Files (x86)\\Tesseract-OCR\\tesseract

# 语言包目录和参数
tessdata_dir_config = --tessdata-dir "C:\\Program Files (x86)\\Tesseract-OCR\\tessdata" --psm 6

# mac 环境, 文件夹分割请使用 / 代替 \\ 如 '/usr/local/Cellar/tesseract/3.05.01/bin/tesseract'

注: 可以用 GetImgTool.py 调整题目截取位置 可以到这里查看部分手机截图设置

6. 运行脚本

python GetQuestionAndroid.py 会自动识别文字并打开浏览器

IOS

部分朋友成功

使用步骤 (百度 OCR)

  1. 百度平台上创建应用申请 API Key 和 Secret Key

  2. 安装所需 python 包

    命令行:

    pip install -r requirements.txt

    或者

    pip install pytesseract
    pip install pillow  
    pip install requests
    pip install colorama
    pip install baidu-aip
    

  3. config/configure.conf 中加入相应 key, 并设置截取区域

    [region]
    # 题目和选项一起的区域
    combine_region = 50, 350, 1000, 1200
    [baidu_api]
    APP_ID = 
    API_KEY = 
    SECRET_KEY = 
    
  4. GetQuestionAndroid.py中切换识别方法

#ocr_img: 需要分别截取题目和选项区域,使用 Tesseract
#ocr_img_tess: 题目和选项一起截,使用 Tesseract
#ocr_img_baidu: 题目和选项一起截,使用 baidu ocr,需配置 key
    
# question, choices = ocr.ocr_img(img, config)
# question, choices = ocr.ocr_img_tess(img, config)
question, choices = ocr.ocr_img_baidu(img, config)
  1. 其它环境配置与 Tesseract 步骤相同

  2. 运行脚本

    安卓: python GetQuestionAndroid.py

其它

总结

有了 ADB 截图,能玩出更多花样。python 写小脚本真的很方便。

Next

  • 文字识别后 nlp 处理一下关系,然后搜索不同选择结果

topsup's People

Contributors

alfredcc avatar assey2018 avatar hh23485 avatar skyexu 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

topsup's Issues

求助,这个错误是怎么回事?要怎样处理?

C:\Users\Administrator\Desktop\TopSup-master\TopSup-master>python GetQuestionTes
sAndroid.py
采用方式 2 获取截图
Traceback (most recent call last):
File "GetQuestionTessAndroid.py", line 20, in
question, choices = ocr.ocr_img(img)
File "C:\Users\Administrator\Desktop\TopSup-master\TopSup-master\common\ocr.py
", line 64, in ocr_img
question = pytesseract.image_to_string(question_im, lang='chi_sim', config=t
essdata_dir_config)
File "C:\python3.6\lib\site-packages\pytesseract\pytesseract.py", line 122, in
image_to_string
config=config)
File "C:\python3.6\lib\site-packages\pytesseract\pytesseract.py", line 46, in
run_tesseract
proc = subprocess.Popen(command, stderr=subprocess.PIPE)
File "C:\python3.6\lib\subprocess.py", line 709, in init
restore_signals, start_new_session)
File "C:\python3.6\lib\subprocess.py", line 997, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] 系统找不到指定的文件。

IOS 运行错误

Traceback (most recent call last):
File "GetTitleTessIos.py", line 16, in
c.screenshot('screenshot.png')
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/wda/init.py", line 295, in screenshot
value = self.http.get('screenshot').value
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/wda/init.py", line 101, in fetch
return self._fetch_no_alert(method, url, data)
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/wda/init.py", line 107, in _fetch_no_alert
return httpdo(target_url, method, data)
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/wda/init.py", line 77, in httpdo
retjson = response.json()
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/models.py", line 892, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/init.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

运行GetQuestionTessAndroid.py后异常

nk_ 4ur zxdf cfp _b70g
运行GetQuestionTessAndroid.py后显示不支持当前设备,换了几个Android手机都是一样的结果;对Android手机调试开发没深入接触,还有疑问是屏幕截屏的时机如何把控,app启动后手动截屏吗?Thanks

[Errno 13] Permission denied:'screenshot.png'

外挂启动后报错如下,请问是什么原因?

答题外挂已启动
采用方式 2 获取截图
Traceback (most recent call last):
File "/Users/wangpeng52/Downloads/TopSup-master/GetQuestionTessAndroid.py", line 21, in
question, choices = ocr.ocr_img(img)
File "/Users/wangpeng52/Downloads/TopSup-master/common/ocr.py", line 64, in ocr_img
question = pytesseract.image_to_string(question_im, lang='chi_sim', config=tessdata_dir_config)
File "/anaconda3/lib/python3.6/site-packages/pytesseract/pytesseract.py", line 122, in image_to_string
config=config)
File "/anaconda3/lib/python3.6/site-packages/pytesseract/pytesseract.py", line 46, in run_tesseract
proc = subprocess.Popen(command, stderr=subprocess.PIPE)
File "/anaconda3/lib/python3.6/subprocess.py", line 709, in init
restore_signals, start_new_session)
File "/anaconda3/lib/python3.6/subprocess.py", line 1344, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'C:\Program Files (x86)\Tesseract-OCR\tesseract': 'C:\Program Files (x86)\Tesseract-OCR\tesseract'

感谢分享,还有很多可以改进的,一起加油。

我也是刚刚接触这个答题的,因为前几天也试了跳一跳,正有这样的想法。结果各位已经都做好了,哈哈哈。
我觉得之后还可以做的,比如对搜索结果内容进行解析,和答案进行比较,自动进行筛选;再比如收集问题的种类,通过NLP来让搜索的方式更好的匹配问题之类的。

mac下脚本报错

采用方式 2 获取截图
-- 方法2: 题目+选项搜索结果计数法 --
Question: 歌曲 (康定情歌) 中的“康定”位
Traceback (most recent call last):
File "GetQuestionTessAndroid.py", line 28, in
methods.run_algorithm(1, question, choices)
File "/XXX/Maple/XXX/TopSup-master/common/methods.py", line 51, in run_algorithm
open_webbrowser_count(question, choices)
File "/XXX/XXX/XXX/TopSup-master/common/methods.py", line 16, in open_webbrowser_count
if '不是' in question:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

感谢

那个截图的那个流 能不能 不保存, 直接 就 给转成图片的格式

学到了很多, 非常感谢分享

一个报错不知道如何解决...

C:\Users\LHTV\Desktop\TopSup-master>python GetQuestionTessAndroid.py
Traceback (most recent call last):
File "GetQuestionTessAndroid.py", line 9, in
from common import screenshot, ocr, methods
File "C:\Users\LHTV\Desktop\TopSup-master\common\ocr.py", line 8, in
import pytesseract
File "C:\Python27\lib\site-packages\pytesseract_init_.py", line 2, in
from pytesseract import image_to_string
File "C:\Python27\lib\site-packages\pytesseract\pytesseract.py", line 9, in
import Image
File "C:\Python27\lib\site-packages\PIL\Image.py", line 27, in
from . import VERSION, PILLOW_VERSION, _plugins
ValueError: Attempted relative import in non-package

xiaomi mi5 config

question_im = image.crop((120, 360, 1000, 540)) # mi5
choices_im = image.crop((140, 660, 900, 1200))

Mac 系统 配置环境

Mac 系统 以下 如何配置环境

tesseract 路径

pytesseract.pytesseract.tesseract_cmd = 'C:\Program Files (x86)\Tesseract-OCR\tesseract'

语言包目录和参数

tessdata_dir_config = '--tessdata-dir "C:\Program Files (x86)\Tesseract-OCR\tessdata" --psm 6'

运行报错

运行GetQuestionTessAndroid.py的时候21行报错了:question, choices = ocr.ocr_img(img),大神知道是为啥吗?

建议:输出格式化

加了一个output

def open_webbrowser_count(question,choices):
print('\n -- 题目+选项搜索结果计数法 -- Question:' + question + '\n')
#print('Question: ' + question + '\n')
if '不是' in question:
print('请注意此题为否定题,选计数最少的')

counts = []
for i in range(len(choices)):
    # 请求
    req = requests.get(url='http://www.baidu.com/s', params={'wd': question + choices[i]})
    content = req.text
    index = content.find('百度为您找到相关结果约') + 11
    content = content[index:]
    index = content.find('个')
    count = content[:index].replace(',', '')
    counts.append(count)
    #print(choices[i] + " : " + count)
    #print("\033[0;31m{0:^10}:{1:^10}\033[0m".format(choices[i],count))
    #print(counts)
output(choices, counts)

def count_base(question,choices):
print('\n -- 题目搜索结果包含选项词频计数法 -- Question:' + question + '\n')
# 请求
req = requests.get(url='http://www.baidu.com/s', params={'wd':question})
content = req.text
#print(content)
counts = []
#print('Question: ' + question + '\n')
if '不是' in question:
print('请注意此题为否定题,选计数最少的')
for i in range(len(choices)):
counts.append(content.count(choices[i]))
#print((choices[i], + " : " + str(counts[i]))
#print("\033[0;31m{0:^10}:{1:^10}\033[0m".format(choices[i], str(counts[i])))
output(choices, counts)

def output(choices, counts):
counts = list(map(int, counts))
#print(choices, counts)

# 最可能的答案
index_max = counts.index(max(counts))

# 最不可能的答案
index_min = counts.index(min(counts))

if index_max == index_min:
    print("\033[1;31m此方法失效!\033[0m")
    return

for i in range(len(choices)):
    if i == index_max:
        # 绿色为最可能的答案
        print("\033[1;32m{0:^10} {1:^10}\033[0m".format(choices[i], counts[i]))
    elif i == index_min:
        # 红色为最不可能的答案
        print("\033[0;31m{0:^10}{1:^10}\033[0m".format(choices[i], counts[i]))
    else:
        print("{0:^10} {1:^10}".format(choices[i], counts[i]))

能出一个Mac+iOS的详细步骤嘛 我的老有问题

➜ TopSup-master python3 GetQuestionTessIos.py
Traceback (most recent call last):
File "GetQuestionTessIos.py", line 23, in
question, choices = ocr.ocr_img(img)
File "/Users/Mac/Downloads/TopSup-master/common/ocr.py", line 64, in ocr_img
question = pytesseract.image_to_string(question_im, lang='chi_sim', config=tessdata_dir_config)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pytesseract/pytesseract.py", line 122, in image_to_string
config=config)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pytesseract/pytesseract.py", line 46, in run_tesseract
proc = subprocess.Popen(command, stderr=subprocess.PIPE)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 707, in init
restore_signals, start_new_session)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/subprocess.py", line 1326, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'C:\Program Files (x86)\Tesseract-OCR\tesseract'

求助,貌似是一个很简单的报错

File "C:\Users\Admin\Desktop\GetQuestionTessAndroid.py", line 9, in
from common import screenshot, ocr, methods
ImportError: cannot import name 'ocr'

找不到ocr?我需要这么做?

FileNotFoundError: [WinError 2] 系统找不到指定的文件

Windows环境下运行报错:

python GetQuestionTessAndroid.py
采用方式 2 获取截图
Traceback (most recent call last):
  File "GetQuestionTessAndroid.py", line 20, in <module>
    question, choices = ocr.ocr_img(img)
  File "D:\Download\ZSDT\code\TopSup\common\ocr.py", line 64, in ocr_img
    question = pytesseract.image_to_string(question_im, lang='chi_sim', config=tessdata_dir_config)
  File "D:\Project\Python3\lib\site-packages\pytesseract\pytesseract.py", line 123, in image_to_string
    config=config)
  File "D:\Project\Python3\lib\site-packages\pytesseract\pytesseract.py", line 47, in run_tesseract
    proc = subprocess.Popen(command, stderr=subprocess.PIPE)
  File "D:\Project\Python3\lib\subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "D:\Project\Python3\lib\subprocess.py", line 997, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] 系统找不到指定的文件。

这个是tesseract路径问题吗?已经填加了PATH,当前可执行tesseract
tesseract路径配置

# tesseract 路径
pytesseract.pytesseract.tesseract_cmd = 'D:\\Project\\Tesseract-OCR\\tesseract'
# 语言包目录
tessdata_dir_config = '--tessdata-dir "D:\\Project\\Tesseract-OCR\\tessdata" --psm 6'

README中提到的依赖已安装

这样识别图片兼容性能好点?

   allRight = pytesseract.image_to_string(all, lang='chi_sim', config=tessdata_dir_config)  
    pattern =  re.compile(u'\d*\.([\s\S]*?)\?');
    question =  pattern.findall(allRight)  
    
    pattern2 =  re.compile(u'[A-Za-z]\.([\s\S]*?)\n');
    answer =  pattern2.findall(allRight)  
    answer = [ x for x in answer if x != '' ]
    return question[0], answer

UnicodeEncodeError: 'ascii' codec can't encode characters

Traceback (most recent call last):
File "GetQuestionTessAndroid.py", line 32, in
m1 = Thread(methods.run_algorithm(0, question, choices))
File "/Users/ext.charles.ma/Desktop/mm/TopSup/common/methods.py", line 74, in run_algorithm
open_webbrowser(question)
File "/Users/ext.charles.ma/Desktop/mm/TopSup/common/methods.py", line 11, in open_webbrowser
webbrowser.open('https://baidu.com/s?wd=' + question)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/webbrowser.py", line 61, in open
if browser.open(url, new, autoraise):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/webbrowser.py", line 636, in open
osapipe.write(script)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 38-39: ordinal not in range(128)

运行错误

$ python3 GetQuestionApi.py
/usr/local/Cellar/python3/3.6.4_1/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python: can't open file 'GetQuestionApi.py': [Errno 2] No such file or directory
help!

运行报错

(python36) E:\AssisiTool\TopSup-master>GetQuestionTessAndroid.py
閲囩敤鏂瑰紡 2 鑾峰彇鎴浘
Traceback (most recent call last):
File "E:\AssisiTool\TopSup-master\GetQuestionTessAndroid.py", line 20, in
question, choices = ocr.ocr_img(img)
File "E:\AssisiTool\TopSup-master\common\ocr.py", line 64, in ocr_img
question = pytesseract.image_to_string(question_im, lang='chi_sim', config=t
essdata_dir_config)
File "C:\Python27\lib\site-packages\pytesseract\pytesseract.py", line 122, in
image_to_string
config=config)
File "C:\Python27\lib\site-packages\pytesseract\pytesseract.py", line 46, in r
un_tesseract
proc = subprocess.Popen(command, stderr=subprocess.PIPE)
File "C:\Python27\lib\subprocess.py", line 711, in init
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 959, in _execute_child
startupinfo)
WindowsError: [Error 2]

速度太慢

我是写c++的 ,如果图像识别用api来做应该更快

Read.md提供的安装版安装版tesseract也存在中文语言包的问题

Windows下链接: 推荐使用安装版,在安装时选择增加中文简体语言包

安装版: https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-3.05.01.exe
按照Read.md中的方式安装了tesseract,运行程序时也存在中文语言包找不到的错误
pytesseract.pytesseract.TesseractError: (1, 'Error opening data file C:\Program Files (x86)\Tesseract-OCR\tessdata/chi_sim.traineddata Please make sure the TESSDATA_PREFIX environment variable is set to the parent directory of your "tessdata" directory. Failed loading language 'chi_sim' Tesseract couldn't load any languages! Could not initialize tesseract.')

Five undefined names

flake8 testing of https://github.com/Skyexu/TopSup

$ time flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics

./GetQuestionTessIos.py:21:21: F821 undefined name 'ocr'
question, choices = ocr.ocr_img(img)
                    ^
./GetQuestionTessIos.py:26:1: F821 undefined name 'methods'
methods.run_algorithm(0, question, choices)
^
./GetQuestionTessIos.py:28:1: F821 undefined name 'methods'
methods.run_algorithm(1, question, choices)
^
./GetQuestionTessIos.py:30:1: F821 undefined name 'methods'
methods.run_algorithm(2, question, choices)
^
./baiduApiVersion/GetTitleBaiduIos.py:39:10: F821 undefined name 'img'
region = img.crop((50, 350, 1000, 560)) # 坚果 pro1
         ^

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.