Repository: Tsuku43/zoomg (language: python)

Issue:
release 1.0
Version 1.0 is released.
Creating a github template.


Discussion / hints:

Fix patch:
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index f9cb6a8..a1defcb 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -1,19 +1,19 @@
 # Contributing
 
 When contributing to this repository, please first discuss the change you wish to make via issue,
-email, or any other method with the owners of this repository before making a change. 
+email, or any other method with the owners of this repository before making a change.
 
 Please note we have a code of conduct, please follow it in all your interactions with the project.
 
 ## Pull Request Process
 
-1. Ensure any install or build dependencies are removed before the end of the layer when doing a 
+1. Ensure any install or build dependencies are removed before the end of the layer when doing a
    build.
-2. Update the README.md with details of changes to the interface, this includes new environment 
+2. Update the README.md with details of changes to the interface, this includes new environment
    variables, exposed ports, useful file locations and container parameters.
 3. Increase the version numbers in any examples files and the README.md to the new version that this
    Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
-4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 
+4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
    do not have permission to do that, you may request the second reviewer to merge it for you.
 
 ## Code of Conduct
@@ -32,21 +32,21 @@ orientation.
 Examples of behavior that contributes to creating a positive environment
 include:
 
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+- Using welcoming and inclusive language
+- Being respectful of differing viewpoints and experiences
+- Gracefully accepting constructive criticism
+- Focusing on what is best for the community
+- Showing empathy towards other community members
 
 Examples of unacceptable behavior by participants include:
 
-* The use of sexualized language or imagery and unwelcome sexual attention or
-advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
+- The use of sexualized language or imagery and unwelcome sexual attention or
+  advances
+- Trolling, insulting/derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or electronic
   address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
+- Other conduct which could reasonably be considered inappropriate in a
   professional setting
 
 ### Our Responsibilities
@@ -89,4 +89,4 @@ This Code of Conduct is adapted from the [Contributor Covenant][homepage], versi
 available at [http://contributor-covenant.org/version/1/4][version]
 
 [homepage]: http://contributor-covenant.org
-[version]: http://contributor-covenant.org/version/1/4/
\ No newline at end of file
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/.github/ISSUE_TEMPLATE/Bug report.md b/.github/ISSUE_TEMPLATE/Bug report.md
index d2ba6c2..55f2971 100644
--- a/.github/ISSUE_TEMPLATE/Bug report.md
+++ b/.github/ISSUE_TEMPLATE/Bug report.md
@@ -1,20 +1,14 @@
 ---
 name: バグレポート - Bug Report
 about: バグの詳細を記載する - Provide bug details
-
 ---
 
 # 概要 - Overview
 
-
 # 再現手順 - Reproduction steps
 
-
 # 修正しないとどう困るか - Troubled point
 
-
 # 原因 - Cause
 
-
 # 修正案 - amendment
-
diff --git a/.github/ISSUE_TEMPLATE/Request.md b/.github/ISSUE_TEMPLATE/Request.md
index 3c6307f..78453bf 100644
--- a/.github/ISSUE_TEMPLATE/Request.md
+++ b/.github/ISSUE_TEMPLATE/Request.md
@@ -1,17 +1,12 @@
 ---
 name: 要望 - Request
 about: 機能追加などの要望を記載する - Describe requests for additional functions
-
 ---
 
 # 概要 - Overview
 
-
 # 目的 - Purpose
 
-
 # 提案内容 - Proposal contents
 
-
 # タスク - Tasks
-
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 09ead75..3bc11a9 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,13 +1,9 @@
 # 概要 - Overview
 
-
 # 変更内容 - Changes
 
-
 # 影響範囲 - Impact range
 
-
 # 動作要件 - Operating requirements
 
-
 # 補足 - Supplement
diff --git a/.gitignore b/.gitignore
index 4a40218..1ba6b0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,4 +23,9 @@ setting.json
 .dist
 *.swp
 
-# Custom files
\ No newline at end of file
+# Custom files
+
+.python-version
+var
+test
+zoomg.egg-info
\ No newline at end of file
diff --git a/.python-version b/.python-version
new file mode 100644
index 0000000..0f44168
--- /dev/null
+++ b/.python-version
@@ -0,0 +1,1 @@
+3.6.4
diff --git a/ALGORITHM.md b/ALGORITHM.md
new file mode 100644
index 0000000..522b63f
--- /dev/null
+++ b/ALGORITHM.md
@@ -0,0 +1,70 @@
+# Algorithm
+
+はじめに理想的な動画を用いての説明を行い,その後に実際の動画に適用する.理想的な動画とはバーチャル背景が赤色,オブジェクトが黄色,部屋が水色である動画とする.ここではオブジェクトが右から左へ横切ることを想定している.  
+![sample_01.gif](https://github.com/Tsuku43/zoomg/blob/master/images/sample_01.gif?raw=true)  
+※フレーム数確保のため速度を落としている.
+
+## 手法
+
+基本的な考え方としては,バーチャル背景が部屋を即座に隠すことを利用し,各ピクセルごとに出現時間が短い色を選ぶことで部屋を復元する.以下の画像は理想的な動画の同一部分を拡大し並べたものである.  
+![sample_01_1-10.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_01_1-10.png?raw=true)  
+バーチャル背景とオブジェクトの色には部屋の色よりも幅があり長時間表示されているため,出現頻度が高くなりやすい.よって,最も出現頻度が低い水色が,部屋の色だと決定できる.実際にはピクセルごとに処理を行うため,ある程度のフレーム数が必要である.以下の画像は理想的な動画の座標 500,500 の色を時間軸を横にとり,並べたものである.  
+![sample_01_500_500_check.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_01_500_500_check.png?raw=true)  
+水色が最も少ないことがわかる.フレーム数と動画長が増加するほど復元の精度が向上する.問題はバーチャル背景と部屋の色が境界で混ざり合う場合である.これはバーチャル背景と部屋の色差を利用して,排除している.バーチャル背景は先に説明した部屋の復元の逆,最も出現頻度が高い色を選択することで取得できる.今後,色差計算が精度向上に大きく影響する可能性がある.
+
+### 理想的な動画
+
+理想的な動画および,部屋部分を写真に変更した理想的な動画に zoomg を適用する.復元された画像は以下になる.  
+**理想的な動画**  
+部屋部分  
+![sample_01_room.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_01_room.png?raw=true)  
+500,500 の時間変化  
+![sample_01_500_500_check.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_01_500_500_check.png?raw=true)  
+**部屋部分を写真に変更した理想的な動画**  
+部屋部分  
+![sample_02_room.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_02_room.png?raw=true)  
+500,500 の時間変化  
+![sample_02_500_500_check.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_02_500_500_check.png?raw=true)  
+共にパラメータを 20 とした.フレーム数の関係でバーチャル背景のみとなったピクセルは縦の線として現れている.オブジェクトと同色のクラスタはパラメータ調整により削減できる.パラメータを 5 とした sample_02 の部屋部分を以下に示す.  
+![sample_02_room_5.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_02_room_5.png?raw=true)
+
+### 実際の動画
+
+実際の zoom から得られた動画に zoomg を適用する.復元された画像は以下になる.  
+**復元された画像**  
+部屋部分(顔黒塗り)  
+![zoom_0_room.png](https://github.com/Tsuku43/zoomg/blob/master/images/zoom_0_room.png?raw=true)  
+500,500 の時間変化  
+![zoom_0_500_500_check.png](https://github.com/Tsuku43/zoomg/blob/master/images/zoom_0_500_500_check.png?raw=true)  
+パラメータを 90 とした.フレーム数の関係で腕などの表示時間が短いため,背景と判定されている.大幅にバーチャル背景が乱れる現象も復元には大きく影響している.実際の部屋と比べると,赤く囲った部分が復元できていることがわかる.  
+**実際の部屋**  
+![room.png](https://github.com/Tsuku43/zoomg/blob/master/images/room.png?raw=true)
+
+## 対抗手法
+
+グリーンバックを使えば部屋の情報が漏れる心配はない.技術的な対策としては,バーチャル背景を不規則に動かすことが挙げられる.規則的に動く場合,バーチャル背景のピクセルが累積してしまうので動画時間によっては復元される恐れがある.バーチャル背景の画像を十分長さのある動画とし,色と場所をランダムにしたノイズピクセルをばらまくことで機械的な復元を妨げることができる.
+
+### フレーム単位のノイズ
+
+理想的な動画をフレーム単位で分割し,1 つのフレームのバーチャル背景部分をノイズに変更したものを再度動画にしたものに zoomg を適用する.  
+![image_123.png](https://github.com/Tsuku43/zoomg/blob/master/images/image_123.png?raw=true)  
+フレーム単位で挿入するため,オブジェクトが動いた後の動画後半に挿入した.これは得られた部屋の情報がノイズによってかき消されることを意味している.復元された画像は以下になる.
+**復元された画像**  
+部屋部分  
+![sample_03_room.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_03_room.png?raw=true)  
+500,500 の時間変化  
+![sample_03_500_500_check.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_03_500_500_check.png?raw=true)  
+1000,1000 の時間変化  
+![sample_03_1000_1000_check.png](https://github.com/Tsuku43/zoomg/blob/master/images/sample_03_1000_1000_check.png?raw=true)  
+パラメータを 20 とした.ノイズによって復元が妨げられていることがわかる.
+
+### ピクセル単位のノイズ
+
+フレーム単位のノイズでは,フレームを削除することにより容易に復元が可能となる.これを防ぐため,バーチャル背景のランダムな箇所へピクセル単位でのノイズを挿入する.ノイズのピクセルサイズをもランダムにすることで予測を困難にすることができるが,動画の質が低下してしまう.本対策ではバーチャル背景の認識に影響を与えない程度のノイズを目指し,ノイズの座標と量をランダムに散りばめることとした.ノイズを含ませたバーチャル背景用動画を zoom のバーチャル背景として使用した動画に zoomg を適用する.動画は[zoom_vbg.png](https://github.com/Tsuku43/zoomg/blob/master/images/zoom_vbg.png?raw=true)より生成したもので,読み込みの関係で mov への変換を行った.  
+**復元された画像**  
+部屋部分(顔黒塗り)  
+![zoom_1_room_60.png](https://github.com/Tsuku43/zoomg/blob/master/images/zoom_1_room_60.png?raw=true)  
+![zoom_1_room_90.png](https://github.com/Tsuku43/zoomg/blob/master/images/zoom_1_room_90.png?raw=true)  
+500,500 の時間変化  
+![zoom_1_500_500_check.png](https://github.com/Tsuku43/zoomg/blob/master/images/zoom_1_500_500_check.png?raw=true)  
+上の画像をパラメータ 60,下の画像をパラメータを 90 とした.ノイズにより部屋の復元がさらに困難になっていることがわかる.
diff --git a/ColorSpace/LICENSE b/ColorSpace/LICENSE
new file mode 100644
index 0000000..9cc0f51
--- /dev/null
+++ b/ColorSpace/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Berendea Nicolae
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/ColorSpace/README.md b/ColorSpace/README.md
new file mode 100644
index 0000000..c56cf90
--- /dev/null
+++ b/ColorSpace/README.md
@@ -0,0 +1,43 @@
+# ColorSpace
+[![Build status](https://ci.appveyor.com/api/projects/status/9imauslkfcma7yps/branch/master?svg=true)](https://ci.appveyor.com/project/berendeanicolae/colorspace/branch/master)
+
+C++ library for converting between color spaces and comparing colors.
+
+## Color Conversion
+You can convert between any supported color spaces using the ```To``` template method:
+```c++
+ColorSpace::Lab lab(100, 0, 0);
+ColorSpace::Cmy cmy;
+lab.To<ColorSpace::Cmy>(&cmy);
+```
+## Color Comparison
+You can compare colors by using the ```Compare``` method of each comparison class:
+```c++
+ColorSpace::Lab a(100, 0, 0);
+ColorSpace::Rgb b(255, 255, 255);
+ColorSpace::Cie2000Comparison::Compare(&a, &b);
+```
+
+## Currently Supported Color Spaces
+* CMY
+* CMYK
+* HSL
+* HSB
+* HSV
+* CIE L*AB
+* Hunter LAB
+* LCH
+* LUV
+* RGB
+* XYZ
+* YXY
+
+## Currently Supported Comparisons
+* Euclidean
+* CIE1976
+* CIE94
+* CIE2000
+* CMC
+
+## License
+ColorSpace is licenced under the MIT License, see LICENSE for more information.
diff --git a/ColorSpace/src/ColorSpace.cpp b/ColorSpace/src/ColorSpace.cpp
new file mode 100644
index 0000000..a86672e
--- /dev/null
+++ b/ColorSpace/src/ColorSpace.cpp
@@ -0,0 +1,187 @@
+#include "ColorSpace.h"
+#include "Conversion.h"
+
+namespace ColorSpace {
+	Rgb::Rgb() {}
+	Rgb::Rgb(double r, double g, double b) : r(r), g(g), b(b) {}
+	void Rgb::Initialize(Rgb *color) {
+		RgbConverter::ToColorSpace(color, this);
+	}
+	void Rgb::ToRgb(Rgb *color) {
+		RgbConverter::ToColor(color, this);
+	}
+	void Rgb::Copy(IColorSpace *color) {
+		Rgb *rgb = static_cast<Rgb*>(color);
+		rgb->r = r;
+		rgb->g = g;
+		rgb->b = b;
+	}
+
+
+	Xyz::Xyz() {}
+	Xyz::Xyz(double x, double y, double z) : x(x), y(y), z(z) {}
+	void Xyz::Initialize(Rgb *color) {
+		XyzConverter::ToColorSpace(color, this);
+	}
+	void Xyz::ToRgb(Rgb *color) {
+		XyzConverter::ToColor(color, this);
+	}
+	void Xyz::Copy(IColorSpace *color) {
+		Xyz *xyz = static_cast<Xyz*>(color);
+		xyz->x = x;
+		xyz->y = y;
+		xyz->z = z;
+	}
+
+	Hsl::Hsl() {}
+	Hsl::Hsl(double h, double s, double l) : h(h), s(s), l(l) {}
+	void Hsl::Initialize(Rgb *color) {
+		HslConverter::ToColorSpace(color, this);
+	}
+	void Hsl::ToRgb(Rgb *color) {
+		HslConverter::ToColor(color, this);
+	}
+	void Hsl::Copy(IColorSpace *color) {
+		Hsl *hsl = static_cast<Hsl*>(color);
+		hsl->h = h;
+		hsl->s = s;
+		hsl->l = l;
+	}
+
+	Lab::Lab() {}
+	Lab::Lab(double l, double a, double b) : l(l), a(a), b(b) {}
+	void Lab::Initialize(Rgb *color) {
+		LabConverter::ToColorSpace(color, this);
+	}
+	void Lab::ToRgb(Rgb *color) {
+		LabConverter::ToColor(color, this);
+	}
+	void Lab::Copy(IColorSpace *color) {
+		Lab *lab = static_cast<Lab*>(color);
+		lab->l = l;
+		lab->a = a;
+		lab->b = b;
+	}
+
+	Lch::Lch() {}
+	Lch::Lch(double l, double c, double h) : l(l), c(c), h(h) {}
+	void Lch::Initialize(Rgb *color) {
+		LchConverter::ToColorSpace(color, this);
+	}
+	void Lch::ToRgb(Rgb *color) {
+		LchConverter::ToColor(color, this);
+	}
+	void Lch::Copy(IColorSpace *color) {
+		Lch *lch = static_cast<Lch*>(color);
+		lch->l = l;
+		lch->c = c;
+		lch->h = h;
+	}
+
+	Luv::Luv() {}
+	Luv::Luv(double l, double u, double v) : l(l), u(u), v(v) {}
+	void Luv::Initialize(Rgb *color) {
+		LuvConverter::ToColorSpace(color, this);
+	}
+	void Luv::ToRgb(Rgb *color) {
+		LuvConverter::ToColor(color, this);
+	}
+	void Luv::Copy(IColorSpace *color) {
+		Luv *luv = static_cast<Luv*>(color);
+		luv->l = l;
+		luv->u = u;
+		luv->v = v;
+	}
+
+	Yxy::Yxy() {}
+	Yxy::Yxy(double y1, double x, double y2) : y1(y1), x(x), y2(y2) {}
+	void Yxy::Initialize(Rgb *color) {
+		YxyConverter::ToColorSpace(color, this);
+	}
+	void Yxy::ToRgb(Rgb *color) {
+		YxyConverter::ToColor(color, this);
+	}
+	void Yxy::Copy(IColorSpace *color) {
+		Yxy *yxy = static_cast<Yxy*>(color);
+		yxy->y1 = y1;
+		yxy->x = x;
+		yxy->y2 = y2;
+	}
+
+	Cmy::Cmy() {}
+	Cmy::Cmy(double c, double m, double y) : c(c), m(m), y(y) {}
+	void Cmy::Initialize(Rgb *color) {
+		CmyConverter::ToColorSpace(color, this);
+	}
+	void Cmy::ToRgb(Rgb *color) {
+		CmyConverter::ToColor(color, this);
+	}
+	void Cmy::Copy(IColorSpace *color) {
+		Cmy *cmy = static_cast<Cmy*>(color);
+		cmy->c = c;
+		cmy->m = m;
+		cmy->y = y;
+	}
+
+	Cmyk::Cmyk() {}
+	Cmyk::Cmyk(double c, double m, double y, double k) : c(c), m(m), y(y), k(k) {}
+	void Cmyk::Initialize(Rgb *color) {
+		CmykConverter::ToColorSpace(color, this);
+	}
+	void Cmyk::ToRgb(Rgb *color) {
+		CmykConverter::ToColor(color, this);
+	}
+	void Cmyk::Copy(IColorSpace *color) {
+		Cmyk *cmyk = static_cast<Cmyk*>(color);
+		cmyk->c = c;
+		cmyk->m = m;
+		cmyk->y = y;
+		cmyk->k = k;
+	}
+
+	Hsv::Hsv() {}
+	Hsv::Hsv(double h, double s, double v) : h(h), s(s), v(v) {}
+	void Hsv::Initialize(Rgb *color) {
+		HsvConverter::ToColorSpace(color, this);
+	}
+	void Hsv::ToRgb(Rgb *color) {
+		HsvConverter::ToColor(color, this);
+	}
+	void Hsv::Copy(IColorSpace *color) {
+		Hsv *hsv = static_cast<Hsv*>(color);
+		hsv->h = h;
+		hsv->s = s;
+		hsv->v = v;
+	}
+
+	Hsb::Hsb() {}
+	Hsb::Hsb(double h, double s, double b) : h(h), s(s), b(b) {}
+	void Hsb::Initialize(Rgb *color) {
+		HsbConverter::ToColorSpace(color, this);
+	}
+	void Hsb::ToRgb(Rgb *color) {
+		HsbConverter::ToColor(color, this);
+	}
+	void Hsb::Copy(IColorSpace *color) {
+		Hsb *hsb = static_cast<Hsb*>(color);
+		hsb->h = h;
+		hsb->s = s;
+		hsb->b = b;
+	}
+
+	HunterLab::HunterLab() {}
+	HunterLab::HunterLab(double l, double a, double b) : l(l), a(a), b(b) {}
+	void HunterLab::Initialize(Rgb *color) {
+		HunterLabConverter::ToColorSpace(color, this);
+	}
+	void HunterLab::ToRgb(Rgb *color) {
+		HunterLabConverter::ToColor(color, this);
+	}
+	void HunterLab::Copy(IColorSpace *color) {
+		HunterLab *lab = static_cast<HunterLab*>(color);
+		lab->l = l;
+		lab->a = a;
+		lab->b = b;
+	}
+}
+
diff --git a/ColorSpace/src/ColorSpace.h b/ColorSpace/src/ColorSpace.h
new file mode 100644
index 0000000..1e5e34e
--- /dev/null
+++ b/ColorSpace/src/ColorSpace.h
@@ -0,0 +1,169 @@
+#ifndef COLOR_SPACE_H
+#define COLOR_SPACE_H
+
+#include <typeinfo>
+#include "Conversion.h"
+
+namespace ColorSpace {
+	struct IColorSpace {
+		IColorSpace() {}
+		virtual ~IColorSpace() {}
+
+		virtual void Initialize(Rgb *color) = 0;
+		virtual void ToRgb(Rgb *color) = 0;
+		virtual void Copy(IColorSpace *color) = 0;
+
+		template <typename TColorSpace>
+		void To(TColorSpace *color);
+	};
+
+
+	struct Rgb : public IColorSpace {
+		double r, g, b;
+
+		Rgb();
+		Rgb(double r, double g, double b);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Xyz : public IColorSpace {
+		double x, y, z;
+
+		Xyz();
+		Xyz(double x, double y, double z);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Hsl : public IColorSpace {
+		double h, s, l;
+
+		Hsl();
+		Hsl(double h, double s, double l);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Lab : public IColorSpace {
+		double l, a, b;
+
+		Lab();
+		Lab(double l, double a, double b);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Lch : public IColorSpace {
+		double l, c, h;
+
+		Lch();
+		Lch(double l, double c, double h);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Luv : public IColorSpace {
+		double l, u, v;
+
+		Luv();
+		Luv(double l, double u, double v);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Yxy : public IColorSpace {
+		double y1, x, y2;
+
+		Yxy();
+		Yxy(double y1, double x, double y2);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Cmy : public IColorSpace {
+		double c, m, y;
+
+		Cmy();
+		Cmy(double c, double m, double y);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Cmyk : public IColorSpace {
+		double c, m, y, k;
+
+		Cmyk();
+		Cmyk(double c, double m, double y, double k);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Hsv : public IColorSpace {
+		double h, s, v;
+
+		Hsv();
+		Hsv(double h, double s, double v);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct Hsb : public IColorSpace {
+		double h, s, b;
+
+		Hsb();
+		Hsb(double h, double s, double b);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	struct HunterLab : public IColorSpace {
+		double l, a, b;
+
+		HunterLab();
+		HunterLab(double l, double a, double b);
+
+		virtual void Initialize(Rgb *color);
+		virtual void ToRgb(Rgb *color);
+		virtual void Copy(IColorSpace *color);
+	};
+
+	template <typename TColorSpace>
+	void IColorSpace::To(TColorSpace *color) {
+		Rgb rgb;
+
+		if (typeid(*this) == typeid(*color)) {
+			this->Copy(color);
+		}
+		else {
+			this->ToRgb(&rgb);
+			IConverter<TColorSpace>::ToColorSpace(&rgb, color);
+		}
+	}
+
+}
+
+#endif // COLOR_SPACE_H
+
diff --git a/ColorSpace/src/Comparison.cpp b/ColorSpace/src/Comparison.cpp
new file mode 100644
index 0000000..d5aebc0
--- /dev/null
+++ b/ColorSpace/src/Comparison.cpp
@@ -0,0 +1,169 @@
+#include "Comparison.h"
+#include "Utils.h"
+#include <cmath>
+
+namespace ColorSpace {
+	double EuclideanComparison::Compare(IColorSpace *a, IColorSpace *b) {
+		Rgb rgb_a;
+		Rgb rgb_b;
+
+		a->ToRgb(&rgb_a);
+		b->ToRgb(&rgb_b);
+
+		return sqrt(SQR(rgb_a.r - rgb_b.r) + SQR(rgb_a.g - rgb_b.g) + SQR(rgb_a.b - rgb_b.b));
+	}
+
+	double Cie1976Comparison::Compare(IColorSpace *a, IColorSpace *b) {
+		Lab lab_a;
+		Lab lab_b;
+
+		a->To<Lab>(&lab_a);
+		b->To<Lab>(&lab_b);
+
+		return sqrt(SQR(lab_a.l - lab_b.l) + SQR(lab_a.a - lab_b.a) + SQR(lab_a.b - lab_b.b));
+	}
+
+	Cie94Comparison::Application::Application(Cie94Comparison::APPLICATION appType) {
+		switch (appType) {
+		case GRAPHIC_ARTS:
+			kl = 1.0;
+			k1 = 0.045;
+			k2 = 0.015;
+			break;
+		case TEXTILES:
+			kl = 2.0;
+			k1 = 0.048;
+			k2 = 0.014;
+			break;
+		}
+	}
+
+	double Cie94Comparison::Compare(IColorSpace *a, IColorSpace *b, APPLICATION appType) {
+		Application app(appType);
+		Lab lab_a;
+		Lab lab_b;
+
+		a->To<Lab>(&lab_a);
+		b->To<Lab>(&lab_b);
+
+		double deltaL = lab_a.l - lab_b.l;
+		double deltaA = lab_a.a - lab_b.a;
+		double deltaB = lab_a.b - lab_b.b;
+
+		double c1 = sqrt(SQR(lab_a.a) + SQR(lab_a.b));
+		double c2 = sqrt(SQR(lab_b.a) + SQR(lab_b.b));
+		double deltaC = c1 - c2;
+
+		double deltaH = SQR(deltaA) + SQR(deltaB) - SQR(deltaC);
+
+		double sl = 1.0;
+		double sc = 1.0 + app.k1*c1;
+		double sh = 1.0 + app.k2*c1;
+
+		deltaL /= app.kl*sl;
+		deltaC /= sc;
+
+		return sqrt(SQR(deltaL) + SQR(deltaC) + deltaH/SQR(sh));
+	}
+
+	double Cie2000Comparison::Compare(IColorSpace *a, IColorSpace *b) {
+		const double eps = 1e-5;
+		Lab lab_a;
+		Lab lab_b;
+
+		a->To<Lab>(&lab_a);
+		b->To<Lab>(&lab_b);
+
+		// calculate ci, hi, i=1,2
+		double c1 = sqrt(SQR(lab_a.a) + SQR(lab_a.b));
+		double c2 = sqrt(SQR(lab_b.a) + SQR(lab_b.b));
+		double meanC = (c1 + c2) / 2.0;
+		double meanC7 = POW7(meanC);
+
+		double g = 0.5*(1 - sqrt(meanC7 / (meanC7 + 6103515625.))); // 0.5*(1-sqrt(meanC^7/(meanC^7+25^7)))
+		double a1p = lab_a.a * (1 + g);
+		double a2p = lab_b.a * (1 + g);
+
+		c1 = sqrt(SQR(a1p) + SQR(lab_a.b));
+		c2 = sqrt(SQR(a2p) + SQR(lab_b.b));
+		double h1 = fmod(atan2(lab_a.b, a1p) + 2*M_PI, 2*M_PI);
+		double h2 = fmod(atan2(lab_b.b, a2p) + 2*M_PI, 2*M_PI);
+
+		// compute deltaL, deltaC, deltaH
+		double deltaL = lab_b.l - lab_a.l;
+		double deltaC = c2 - c1;
+		double deltah;
+
+		if (c1*c2 < eps) {
+			deltah = 0;
+		}
+		if (std::abs(h2 - h1) <= M_PI) {
+			deltah = h2 - h1;
+		}
+		else if (h2 > h1) {
+			deltah = h2 - h1 - 2* M_PI;
+		}
+		else {
+			deltah = h2 - h1 + 2 * M_PI;
+		}
+
+		double deltaH = 2 * sqrt(c1*c2)*sin(deltah / 2);
+
+		// calculate CIEDE2000
+		double meanL = (lab_a.l + lab_b.l) / 2;
+		meanC = (c1 + c2) / 2.0;
+		meanC7 = POW7(meanC);
+		double meanH;
+
+		if (c1*c2 < eps) {
+			meanH = h1 + h2;
+		}
+		if (std::abs(h1 - h2) <= M_PI + eps) {
+			meanH = (h1 + h2) / 2;
+		}
+		else if (h1 + h2 < 2*M_PI) {
+			meanH = (h1 + h2 + 2*M_PI) / 2;
+		}
+		else {
+			meanH = (h1 + h2 - 2*M_PI) / 2;
+		}
+
+		double T = 1
+			- 0.17*cos(meanH - DegToRad(30))
+			+ 0.24*cos(2 * meanH)
+			+ 0.32*cos(3 * meanH + DegToRad(6))
+			- 0.2*cos(4 * meanH - DegToRad(63));
+		double sl = 1 + (0.015*SQR(meanL - 50)) / sqrt(20 + SQR(meanL - 50));
+		double sc = 1 + 0.045*meanC;
+		double sh = 1 + 0.015*meanC*T;
+		double rc = 2 * sqrt(meanC7 / (meanC7 + 6103515625.));
+		double rt = -sin(DegToRad(60 * exp(-SQR((RadToDeg(meanH) - 275) / 25)))) * rc;
+
+		return sqrt(SQR(deltaL / sl) + SQR(deltaC / sc) + SQR(deltaH / sh) + rt * deltaC / sc * deltaH / sh);
+	}
+
+
+	const double CmcComparison::defaultLightness = 2.;
+	const double CmcComparison::defaultChroma = 1.;
+	double CmcComparison::Compare(IColorSpace *a, IColorSpace *b) {
+		Lch lch_a;
+		Lch lch_b;
+
+		a->To<Lch>(&lch_a);
+		b->To<Lch>(&lch_b);
+
+		double deltaL = lch_a.l - lch_b.l;
+		double deltaC = lch_a.c - lch_b.c;
+		double deltaH = 0;
+
+		double f = sqrt(POW4(lch_a.c) / (POW4(lch_a.c) + 1900));
+		double t = (164 <= lch_a.h && lch_a.h <= 345) ? (0.56 + std::abs(0.2*cos(lch_a.h + 168))) : (0.36 + std::abs(0.4*cos(lch_a.h + 35)));
+
+		double sl = (lch_a.l < 16) ? 0.511 : (0.040975*lch_a.l / (1 + 0.01765*lch_a.l));
+		double sc = 0.0638*lch_a.c / (1 + 0.0131*lch_a.c) + 0.638;
+		double sh = sc*(f*t + 1 - f);
+
+		return sqrt(SQR(deltaL / (defaultLightness*sl)) + SQR(deltaC / (defaultChroma*sc)) + SQR(deltaH / sh));
+	}
+}
+
diff --git a/ColorSpace/src/Comparison.h b/ColorSpace/src/Comparison.h
new file mode 100644
index 0000000..45973ff
--- /dev/null
+++ b/ColorSpace/src/Comparison.h
@@ -0,0 +1,44 @@
+#ifndef COMPARISON_H
+#define COMPARISON_H
+
+#include "ColorSpace.h"
+
+namespace ColorSpace {
+	struct EuclideanComparison {
+		static double Compare(IColorSpace *a, IColorSpace *b);
+	};
+
+	struct Cie1976Comparison {
+		static double Compare(IColorSpace *a, IColorSpace *b);
+	};
+
+
+	struct Cie94Comparison {
+		enum APPLICATION {
+			GRAPHIC_ARTS = 0,
+			TEXTILES
+		};
+
+		struct Application {
+			double kl, k1, k2;
+			Application(APPLICATION appType);
+		};
+
+		static double Compare(IColorSpace *a, IColorSpace *b, APPLICATION appType=GRAPHIC_ARTS);
+	};
+
+
+	struct Cie2000Comparison {
+		static double Compare(IColorSpace *a, IColorSpace *b);
+	};
+
+
+	struct CmcComparison {
+		static const double defaultLightness;
+		static const double defaultChroma;
+		static double Compare(IColorSpace *a, IColorSpace *b);
+	};
+}
+
+#endif // COMPARISON_H
+
diff --git a/ColorSpace/src/Conversion.cpp b/ColorSpace/src/Conversion.cpp
new file mode 100644
index 0000000..42b8112
--- /dev/null
+++ b/ColorSpace/src/Conversion.cpp
@@ -0,0 +1,383 @@
+#include "Conversion.h"
+#include "ColorSpace.h"
+#include "Utils.h"
+#define _USE_MATH_DEFINES
+#include <cmath>
+#include <algorithm>
+
+namespace ColorSpace {
+	double Hue_2_RGB(double v1, double v2, double vh) {
+		if (vh < 0) vh += 1;
+		if (vh > 1) vh -= 1;
+		if (6 * vh < 1) return v1 + (v2 - v1) * 6 * vh;
+		if (2 * vh < 1) return v2;
+		if (3 * vh < 2) return v1 + (v2 - v1)*(2.0 / 3.0 - vh) * 6;
+		return v1;
+	}
+
+
+
+	void RgbConverter::ToColorSpace(Rgb *color, Rgb *item) {
+		item->r = color->r;
+		item->g = color->g;
+		item->b = color->b;
+	}
+	void RgbConverter::ToColor(Rgb *color, Rgb *item) {
+		color->r = item->r;
+		color->g = item->g;
+		color->b = item->b;
+	}
+
+	void XyzConverter::ToColorSpace(Rgb *color, Xyz *item) {
+		double r = color->r / 255.0;
+		double g = color->g / 255.0;
+		double b = color->b / 255.0;
+
+		r = ((r > 0.04045) ? pow((r + 0.055) / 1.055, 2.4) : (r / 12.92)) * 100.0;
+		g = ((g > 0.04045) ? pow((g + 0.055) / 1.055, 2.4) : (g / 12.92)) * 100.0;
+		b = ((b > 0.04045) ? pow((b + 0.055) / 1.055, 2.4) : (b / 12.92)) * 100.0;
+
+		item->x = r*0.4124564 + g*0.3575761 + b*0.1804375;
+		item->y = r*0.2126729 + g*0.7151522 + b*0.0721750;
+		item->z = r*0.0193339 + g*0.1191920 + b*0.9503041;
+	}
+	void XyzConverter::ToColor(Rgb *color, Xyz *item) {
+		double x = item->x / 100.0;
+		double y = item->y / 100.0;
+		double z = item->z / 100.0;
+
+		double r = x * 3.2404542 + y * -1.5371385 + z * -0.4985314;
+		double g = x * -0.9692660 + y * 1.8760108 + z * 0.0415560;
+		double b = x * 0.0556434 + y * -0.2040259 + z * 1.0572252;
+
+		r = ((r > 0.0031308) ? (1.055*pow(r, 1 / 2.4) - 0.055) : (12.92*r)) * 255.0;
+		g = ((g > 0.0031308) ? (1.055*pow(g, 1 / 2.4) - 0.055) : (12.92*g)) * 255.0;
+		b = ((b > 0.0031308) ? (1.055*pow(b, 1 / 2.4) - 0.055) : (12.92*b)) * 255.0;
+		
+		color->r = r;
+		color->g = g;
+		color->b = b;
+	}
+	const double XyzConverter::eps = 216.0 / 24389.0;
+	const double XyzConverter::kappa = 24389.0 / 27.0;
+	const Xyz XyzConverter::whiteReference(95.047, 100.000, 108.883);
+
+	void HslConverter::ToColorSpace(Rgb *color, Hsl *item) {
+		double r = color->r / 255.0;
+		double g = color->g / 255.0;
+		double b = color->b / 255.0;
+
+		double min = std::min(r, std::min(g, b));
+		double max = std::max(r, std::max(g, b));
+		double delta = max - min;
+		
+		item->l = (max + min) / 2;
+		if (delta == 0)
+		{
+			item->h = item->s = 0;
+		}
+		else {
+			if (item->l < 0.5) {
+				item->s = delta / (max + min) * 100;
+			}
+			else {
+				item->s = delta / (1 - std::abs(2 * item->l - 1)) * 100;
+			}
+
+			if (r == max) {
+				item->h =  (g - b) / delta;
+			}
+			else if (g == max) {
+				item->h = (b - r) / delta + 2;
+			}
+			else if (b == max) {
+				item->h = (r - g) / delta + 4;
+			}
+			item->h = fmod(60 * item->h + 360, 360);
+		}
+		item->l *= 100;
+	}
+	void HslConverter::ToColor(Rgb *color, Hsl *item) {
+		double h = item->h / 360;
+		double s = item->s / 100;
+		double l = item->l / 100;
+
+		if (item->s == 0) {
+			color->r = color->g = color->b = item->l * 255;
+		}
+		else {
+			double temp1, temp2;
+
+			temp2 = (l < 0.5) ? (l*(1 + s)) : (l + s - (s*l));
+			temp1 = 2 * l - temp2;
+
+			color->r = 255 * Hue_2_RGB(temp1, temp2, h + 1.0 / 3.0);
+			color->g = 255 * Hue_2_RGB(temp1, temp2, h);
+			color->b = 255 * Hue_2_RGB(temp1, temp2, h - 1.0 / 3.0);
+		}
+	}
+
+	void LabConverter::ToColorSpace(Rgb *color, Lab *item) {
+		Xyz xyz;
+
+		XyzConverter::ToColorSpace(color, &xyz);
+
+		double x = xyz.x / 95.047;
+		double y = xyz.y / 100.00;
+		double z = xyz.z / 108.883;
+
+		x = (x > 0.008856) ? cbrt(x) : (7.787 * x + 16.0 / 116.0);
+		y = (y > 0.008856) ? cbrt(y) : (7.787 * y + 16.0 / 116.0);
+		z = (z > 0.008856) ? cbrt(z) : (7.787 * z + 16.0 / 116.0);
+
+		item->l = (116.0 * y) - 16;
+		item->a = 500 * (x - y);
+		item->b = 200 * (y - z);
+	}
+	void LabConverter::ToColor(Rgb *color, Lab *item) {
+		double y = (item->l + 16.0) / 116.0;
+		double x = item->a / 500.0 + y;
+		double z = y - item->b / 200.0;
+
+		double x3 = POW3(x);
+		double y3 = POW3(y);
+		double z3 = POW3(z);
+
+		x = ((x3 > 0.008856) ? x3 : ((x - 16.0 / 116.0) / 7.787)) * 95.047;
+		y = ((y3 > 0.008856) ? y3 : ((y - 16.0 / 116.0) / 7.787)) * 100.0;
+		z = ((z3 > 0.008856) ? z3 : ((z - 16.0 / 116.0) / 7.787)) * 108.883;
+
+		Xyz xyz(x, y, z);
+		XyzConverter::ToColor(color, &xyz);
+	}
+
+	void LchConverter::ToColorSpace(Rgb *color, Lch *item) {
+		Lab lab;
+
+		LabConverter::ToColorSpace(color, &lab);
+		double l = lab.l;
+		double c = sqrt(lab.a*lab.a + lab.b*lab.b);
+		double h = atan2(lab.b, lab.a);
+
+		h = h / M_PI * 180;
+		if (h < 0) {
+			h += 360;
+		}
+		else if (h >= 360) {
+			h -= 360;
+		}
+
+		item->l = l;
+		item->c = c;
+		item->h = h;
+	}
+	void LchConverter::ToColor(Rgb *color, Lch *item) {
+		Lab lab;
+
+		item->h = item->h * M_PI / 180;
+
+		lab.l = item->l;
+		lab.a = cos(item->h)*item->c;
+		lab.b = sin(item->h)*item->c;
+
+		LabConverter::ToColor(color, &lab);
+	}
+
+	void LuvConverter::ToColorSpace(Rgb *color, Luv *item) {
+		const Xyz &white = XyzConverter::whiteReference;
+		Xyz xyz;
+
+		XyzConverter::ToColorSpace(color, &xyz);
+		double y = xyz.y / white.y;
+		double temp = (xyz.x + 15 * xyz.y + 3 * xyz.z);
+		double tempr = (white.x + 15 * white.y + 3 * white.z);
+
+		item->l = (y > XyzConverter::eps) ? (116 * cbrt(y) - 16) : (XyzConverter::kappa*y);
+		item->u = 52 * item->l * (((temp > 1e-3) ? (xyz.x / temp) : 0) - white.x / tempr);
+		item->v = 117 * item->l * (((temp > 1e-3) ? (xyz.y / temp) : 0) - white.y / tempr);
+	}
+	void LuvConverter::ToColor(Rgb *color, Luv *item) {
+		const Xyz &white = XyzConverter::whiteReference;
+		Xyz xyz;
+
+		double y = (item->l > XyzConverter::eps*XyzConverter::kappa) ? POW3((item->l + 16) / 116) : (item->l / XyzConverter::kappa);
+		double tempr = white.x + 15 * white.y + 3 * white.z;
+		double up = 4 * white.x / tempr;
+		double vp = 9 * white.y / tempr;
+
+		double a = 1. / 3. * (52 * item->l / (item->u + 13 * item->l*up) - 1);
+		double b = -5 * y;
+		double x = (y*(39 * item->l / (item->v + 13 * item->l*vp) - 5) - b) / (a + 1. / 3.);
+		double z = x*a + b;
+
+		xyz.x = x * 100;
+		xyz.y = y * 100;
+		xyz.z = z * 100;
+
+		XyzConverter::ToColor(color, &xyz);
+	}
+
+	void YxyConverter::ToColorSpace(Rgb *color, Yxy *item) {
+		Xyz xyz;
+
+		XyzConverter::ToColorSpace(color, &xyz);
+		double temp = xyz.x + xyz.y + xyz.z;
+		item->y1 = xyz.y;
+		item->x = (temp==0) ? 0 : (xyz.x / temp);
+		item->y2 = (temp==0) ? 0 : (xyz.y / temp);
+	}
+	void YxyConverter::ToColor(Rgb *color, Yxy *item) {
+		Xyz xyz;
+
+		xyz.x = item->x*(item->y1 / item->y2);
+		xyz.y = item->y1;
+		xyz.z = (1 - item->x - item->y2)*(item->y1 / item->y2);
+		XyzConverter::ToColor(color, &xyz);
+	}
+
+	void CmyConverter::ToColorSpace(Rgb *color, Cmy *item) {
+		item->c = 1 - color->r / 255;
+		item->m = 1 - color->g / 255;
+		item->y = 1 - color->b / 255;
+	}
+	void CmyConverter::ToColor(Rgb *color, Cmy *item) {
+		color->r = (1 - item->c) * 255;
+		color->g = (1 - item->m) * 255;
+		color->b = (1 - item->y) * 255;
+	}
+
+	void CmykConverter::ToColorSpace(Rgb *color, Cmyk *item) {
+		Cmy cmy;
+
+		CmyConverter::ToColorSpace(color, &cmy);
+		double k = 1.0;
+		k = std::min(k, cmy.c);
+		k = std::min(k, cmy.m);
+		k = std::min(k, cmy.y);
+
+		item->k = k;
+		if (std::abs(item->k - 1) < 1e-3) {
+			item->c = 0;
+			item->m = 0;
+			item->y = 0;
+		}
+		else {
+			item->c = (cmy.c - k) / (1 - k);
+			item->m = (cmy.m - k) / (1 - k);
+			item->y = (cmy.y - k) / (1 - k);
+		}
+	}
+	void CmykConverter::ToColor(Rgb *color, Cmyk *item) {
+		Cmy cmy;
+
+		cmy.c = item->c * (1 - item->k) + item->k;
+		cmy.m = item->m * (1 - item->k) + item->k;
+		cmy.y = item->y * (1 - item->k) + item->k;
+		CmyConverter::ToColor(color, &cmy);
+	}
+
+	void HsvConverter::ToColorSpace(Rgb *color, Hsv *item) {
+		double r = color->r / 255.0;
+		double g = color->g / 255.0;
+		double b = color->b / 255.0;
+
+		double min = std::min(r, std::min(g, b));
+		double max = std::max(r, std::max(g, b));
+		double delta = max - min;
+
+		item->v = max;
+		item->s = (max > 1e-3) ? (delta / max) : 0;
+
+		if (delta == 0) {
+			item->h = 0;
+		}
+		else {
+			if (r == max) {
+				item->h = (g - b) / delta;
+			}
+			else if (g == max) {
+				item->h = 2 + (b - r) / delta;
+			}
+			else if (b == max) {
+				item->h = 4 + (r - g) / delta;
+			}
+
+			item->h *= 60;
+			item->h = fmod(item->h + 360, 360);
+		}
+	}
+	void HsvConverter::ToColor(Rgb *color, Hsv *item) {
+		int range = (int)floor(item->h / 60);
+		double c = item->v*item->s;
+		double x = c*(1 - std::abs(fmod(item->h / 60, 2) - 1));
+		double m = item->v - c;
+
+		switch (range) {
+			case 0:
+				color->r = (c + m) * 255;
+				color->g = (x + m) * 255;
+				color->b = m * 255;
+				break;
+			case 1:
+				color->r = (x + m) * 255;
+				color->g = (c + m) * 255;
+				color->b = m * 255;
+				break;
+			case 2:
+				color->r = m * 255;
+				color->g = (c + m) * 255;
+				color->b = (x + m) * 255;
+				break;
+			case 3:
+				color->r = m * 255;
+				color->g = (x + m) * 255;
+				color->b = (c + m) * 255;
+				break;
+			case 4:
+				color->r = (x + m) * 255;
+				color->g = m * 255;
+				color->b = (c + m) * 255;
+				break;
+			default:		// case 5:
+				color->r = (c + m) * 255;
+				color->g = m * 255;
+				color->b = (x + m) * 255;
+				break;
+		}
+	}
+
+	void HsbConverter::ToColorSpace(Rgb *color, Hsb *item) {
+		Hsv hsv;
+
+		HsvConverter::ToColorSpace(color, &hsv);
+		item->h = hsv.h;
+		item->s = hsv.s;
+		item->b = hsv.v;
+	}
+	void HsbConverter::ToColor(Rgb *color, Hsb *item) {
+		Hsv hsv;
+
+		hsv.h = item->h;
+		hsv.s = item->s;
+		hsv.v = item->b;
+		HsvConverter::ToColor(color, &hsv);
+	}
+
+	void HunterLabConverter::ToColorSpace(Rgb *color, HunterLab *item) {
+		Xyz xyz;
+
+		XyzConverter::ToColorSpace(color, &xyz);
+		item->l = 10.0*sqrt(xyz.y);
+		item->a = (xyz.y != 0) ? (17.5*(1.02*xyz.x - xyz.y) / sqrt(xyz.y)) : 0;
+		item->b = (xyz.y != 0) ? (7.0*(xyz.y - 0.847*xyz.z) / sqrt(xyz.y)) : 0;
+	}
+	void HunterLabConverter::ToColor(Rgb *color, HunterLab *item) {
+		double x = (item->a / 17.5) *(item->l / 10.0);
+		double y = item->l*item->l / 100;
+		double z = item->b / 7.0 * item->l / 10.0;
+
+		Xyz xyz((x+y)/1.02, y, -(z-y)/0.847);
+		XyzConverter::ToColor(color, &xyz);
+	}
+}
+
diff --git a/ColorSpace/src/Conversion.h b/ColorSpace/src/Conversion.h
new file mode 100644
index 0000000..22ec388
--- /dev/null
+++ b/ColorSpace/src/Conversion.h
@@ -0,0 +1,113 @@
+#ifndef RGB_CONVERTER_H
+#define RGB_CONVERTER_H
+
+namespace ColorSpace {
+	struct Rgb;
+	struct Xyz;
+	struct Hsl;
+	struct Lab;
+	struct Lch;
+	struct Luv;
+	struct Yxy;
+	struct Cmy;
+	struct Cmyk;
+	struct Hsv;
+	struct Hsb;
+	struct HunterLab;
+
+	template <typename TColorSpace>
+	struct IConverter {
+		static void ToColorSpace(Rgb *color, TColorSpace *item);
+		static void ToColor(Rgb *color, TColorSpace *item);
+	};
+
+	template <>
+	struct IConverter<Rgb> {
+		static void ToColorSpace(Rgb *color, Rgb *item);
+		static void ToColor(Rgb *color, Rgb *item);
+	};
+	typedef IConverter<Rgb> RgbConverter;
+
+	template <>
+	struct IConverter<Xyz> {
+		static void ToColorSpace(Rgb *color, Xyz *item);
+		static void ToColor(Rgb *color, Xyz *item);
+		static const double eps;
+		static const double kappa;
+		static const Xyz whiteReference;
+	};
+	typedef IConverter<Xyz> XyzConverter;
+
+	template <>
+	struct IConverter<Hsl> {
+		static void ToColorSpace(Rgb *color, Hsl *item);
+		static void ToColor(Rgb *color, Hsl *item);
+	};
+	typedef IConverter<Hsl> HslConverter;
+
+	template <>
+	struct IConverter<Lab> {
+		static void ToColorSpace(Rgb *color, Lab *item);
+		static void ToColor(Rgb *color, Lab *item);
+	};
+	typedef IConverter<Lab> LabConverter;
+
+	template <>
+	struct IConverter<Lch> {
+		static void ToColorSpace(Rgb *color, Lch *item);
+		static void ToColor(Rgb *color, Lch *item);
+	};
+	typedef IConverter<Lch> LchConverter;
+
+	template <>
+	struct IConverter<Luv> {
+		static void ToColorSpace(Rgb *color, Luv *item);
+		static void ToColor(Rgb *color, Luv *item);
+	};
+	typedef IConverter<Luv> LuvConverter;
+
+	template <>
+	struct IConverter<Yxy> {
+		static void ToColorSpace(Rgb *color, Yxy *item);
+		static void ToColor(Rgb *color, Yxy *item);
+	};
+	typedef IConverter<Yxy> YxyConverter;
+
+	template <>
+	struct IConverter<Cmy> {
+		static void ToColorSpace(Rgb *color, Cmy *item);
+		static void ToColor(Rgb *color, Cmy *item);
+	};
+	typedef IConverter<Cmy> CmyConverter;
+
+	template <>
+	struct IConverter<Cmyk> {
+		static void ToColorSpace(Rgb *color, Cmyk *item);
+		static void ToColor(Rgb *color, Cmyk *item);
+	};
+	typedef IConverter<Cmyk> CmykConverter;
+
+	template <>
+	struct IConverter<Hsv> {
+		static void ToColorSpace(Rgb *color, Hsv *item);
+		static void ToColor(Rgb *color, Hsv *item);
+	};
+	typedef IConverter<Hsv> HsvConverter;
+
+	template <>
+	struct IConverter<Hsb> {
+		static void ToColorSpace(Rgb *color, Hsb *item);
+		static void ToColor(Rgb *color, Hsb *item);
+	};
+	typedef IConverter<Hsb> HsbConverter;
+
+	template <>
+	struct IConverter<HunterLab> {
+		static void ToColorSpace(Rgb *color, HunterLab *item);
+		static void ToColor(Rgb *color, HunterLab *item);
+	};
+	typedef IConverter<HunterLab> HunterLabConverter;
+}
+
+#endif // RGB_CONVERTER_H
+
diff --git a/ColorSpace/src/Utils.h b/ColorSpace/src/Utils.h
new file mode 100644
index 0000000..2db252e
--- /dev/null
+++ b/ColorSpace/src/Utils.h
@@ -0,0 +1,14 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+#define M_PI 3.141592653589793238462643383279502884L
+#define SQR(x) ((x)*(x))
+#define POW2(x) SQR(x)
+#define POW3(x) ((x)*(x)*(x))
+#define POW4(x) (POW2(x)*POW2(x))
+#define POW7(x) (POW3(x)*POW3(x)*(x))
+#define DegToRad(x) ((x)*M_PI/180)
+#define RadToDeg(x) ((x)/M_PI*180)
+
+#endif // UTILS_H
+
diff --git a/LICENSE b/LICENSE
index 25647a7..8203dd3 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,21 @@
-Copyright (c) <year> <copyright holders>
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+MIT License
 
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+Copyright (c) 2020 Tsuku43
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/zoomg/MANIFEST.in b/MANIFEST.in
similarity index 100%
rename from zoomg/MANIFEST.in
rename to MANIFEST.in
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1f09dc6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,42 @@
+[![PyPI version](https://badge.fury.io/py/zoomg.svg)](https://badge.fury.io/py/zoomg) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Downloads](https://pepy.tech/badge/zoomg)](https://pepy.tech/project/zoomg)
+
+# **zoomg**
+
+バーチャル背景適用済み動画から部屋の画像を復元するライブラリ
+
+<div align="center">
+  <img width="60%" src="https://github.com/Tsuku43/zoomg/blob/master/images/icon.png?raw=true" alt="logo" />
+</div>
+
+本ライブラリは以下の研究の一部として開発され，[情報通信システムセキュリティ研究会（ICSS）](https://www.ieice.org/iss/icss/)にて[論文発表](https://www.ieice.org/ken/paper/20210301ZCDg/)を行いました．結果として ICSS 2020 年度研究賞を受賞しました．
+
+```txt
+「仮想背景を使用したリモート会議映像における秘匿された背景の再構築手法」
+○辻知希，石川琉聖（立命館大）・衛藤将史（NICT）・服部祐一（セキュアサイクル）・井上博之（広島市大）
+```
+
+## [zoomg](https://github.com/Tsuku43/zoomg/tree/master/zoomg)
+
+zoomg PyPI パッケージ  
+**パッケージの仕様は[こちら](./zoomg_docs.md)**
+
+## [ALGORITHM.md](https://github.com/Tsuku43/zoomg/blob/master/ALGORITHM.md)
+
+zoomg のアルゴリズムを説明した資料
+
+## [AVTOKYO2020](https://github.com/Tsuku43/zoomg/tree/master/avtokyo)
+
+[AVTOKYO2020](https://www.avtokyo.org/2020/event) で使用する参考資料
+
+## [Sample](https://github.com/Tsuku43/zoomg/tree/master/sample)
+
+zoomg を利用するサンプルコード
+
+## [Resources](https://github.com/Tsuku43/zoomg/tree/master/resources)
+
+zoomg を利用する際に有用なリソース
+
+## Authors
+
+- **[satoki](https://github.com/satoki)**
+- **[xryuseix](https://github.com/xryuseix)**
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..014b6e4
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,461 @@
+|PyPI version| |License: MIT| |Downloads|
+
+zoomg Docs
+==========
+
+バーチャル背景適用済み動画からバーチャル背景を復元するライブラリ
+
+.. figure:: https://github.com/Tsuku43/zoomg/blob/master/images/icon.png?raw=true
+   :alt: icon
+
+   icon
+
+System Requirements / 動作保証環境
+----------------------------------
+
+-  python 3.6.4
+-  pip 20.2.4
+-  OS
+
+   -  macOS Catalina 10.15.7 (x86_64)
+   -  macOS Bug Sur 11.4 (aarch64)
+   -  Ubuntu 20.04.1 LTS / 18.04.4 LTS
+
+Installing / インストール
+-------------------------
+
+-  aarch64環境の場合
+
+.. code:: shell
+
+   pip install zoomg
+
+-  x86_64環境の場合
+
+.. code:: shell
+
+   pip install git+https://github.com/Tsuku43/zoomg
+
+**Windows では動作保証をしていません**
+
+How to use / 使用方法
+---------------------
+
+簡単な使用方法
+~~~~~~~~~~~~~~
+
+.. code:: sh
+
+   python3 sample.py sample_video.mp4
+
+.. code:: python
+
+   import zoomg
+   import cv2
+   import sys
+   import numpy
+
+
+   # ビデオ読み込みの初期設定
+   filename = sys.argv[1]
+   video = cv2.VideoCapture(filename)
+   height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
+   width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
+
+   # zoomgの初期化
+   zoom = zoomg.Zoomg(height, width)
+
+   while True:
+       # フレーム読み込み
+       ret, frame = video.read()
+       if not ret:
+           break
+       # zoomgに画像を追加
+       zoom.add_image(frame)
+
+   # 背景画像を生成
+   zoom.generate_image()
+   # 背景画像を取得
+   image = zoom.get_image()
+   # 背景画像を保存
+   cv2.imwrite("room.png", numpy.array(image))
+
+Zoomg クラス
+~~~~~~~~~~~~
+
+背景画像の生成を行います.
+
+**コンストラクタ**
+^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+   zoom = zoomg.Zoomg(height, width)
+
+-  引数
+
+========== === ============== ==== ==============
+パラメータ 型  キーワード引数 省略 説明
+========== === ============== ==== ==============
+height     int 可(h)          -    入力画像の高さ
+width      int 可(w)          -    入力画像の幅
+========== === ============== ==== ==============
+
+-  返り値
+
+========== ===== ==================
+パラメータ 型    説明
+========== ===== ==================
+zoom       Zoomg Zoomg オブジェクト
+========== ===== ==================
+
+--------------
+
+**Zoomg.add_image**
+^^^^^^^^^^^^^^^^^^^
+
+zoomg
+オブジェクトに画像を追加します.動画を入力したい場合はフレーム単位で分割する必要があります.
+
+.. code:: python
+
+   zoom.add_image(frame)
+
+-  引数
+
++------------+---------------+---------------+------+---------------+
+| パラメータ | 型            | キ            | 省略 | 説明          |
+|            |               | ーワード引数  |      |               |
++============+===============+===============+======+===============+
+| frame      | 3 次元        | -             | -    | zoomg         |
+|            | numpy.ndarray |               |      | オ            |
+|            |               |               |      | ブジェクトに  |
+|            |               |               |      | 追加する画像  |
++------------+---------------+---------------+------+---------------+
+
+-  返り値
+
+   -  なし
+
+--------------
+
+**Zoomg.generate_image**
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+``Zoomg.add_image``\ で追加した画像から背景画像を復元する.
+
+.. code:: python
+
+   zoom.generate_image(comp, param, noise_frame)
+
+-  引数
+
++---+---+-----+--------------+-----------------------------------------+
+| パ | 型 | キ | 省略        | 説明                                    |
+| ラ |  | ー  |              |                                         |
+| メ |  | ワ  |              |                                         |
+| ー |  | ー  |              |                                         |
+| タ |  | ド  |              |                                         |
+|   |   | 引  |              |                                         |
+|   |   | 数  |              |                                         |
++===+===+=====+==============+=========================================+
+| c | s | 可  | 可(default=  | 色差を決定する．詳                      |
+| o | t | (co | “ciede2000”) | 細は表「\ `色差 <#色差>`__\ 」を参照．  |
+| m | r | mp) |              |                                         |
+| p | i |     |              |                                         |
+|   | n |     |              |                                         |
+|   | g |     |              |                                         |
++---+---+-----+--------------+-----------------------------------------+
+| p | f | 可( | 可(defau     | 各ピクセルが部屋の背景かバーチ          |
+| a | l | par | lt=表「\ `色 | ャル背景か判定するためのパラメータ．詳  |
+| r | o | am) | 差 <#色差>`_ | 細は表「\ `色差 <#色差>`__\ 」を参照．  |
+| a | a |     | _\ 」を参照) |                                         |
+| m | t |     |              |                                         |
++---+---+-----+--------------+-----------------------------------------+
+| n | i | 可( | 可           | 画像にノイズが多く含まれてい            |
+| o | n | noi | (default=1)  | る場合,ノイズを軽減するためのパラメータ |
+| i | t | se_ |              |                                         |
+| s |   | fra |              |                                         |
+| e |   | me) |              |                                         |
+| _ |   |     |              |                                         |
+| f |   |     |              |                                         |
+| r |   |     |              |                                         |
+| a |   |     |              |                                         |
+| m |   |     |              |                                         |
+| e |   |     |              |                                         |
++---+---+-----+--------------+-----------------------------------------+
+
+色差
+''''
+
++---------+----+--------+-------+------------------------------------+
+| 色      | co | param  | 省略  | 説明                               |
+| 差計算  | mp | 指定可 |       |                                    |
+| アルゴ  |    | 能範囲 |       |                                    |
+| リズム  |    |        |       |                                    |
++=========+====+========+=======+====================================+
+| コ      | `  | [0.0,  | 可    | 高くす                             |
+| サイン  | `c | 1.0]   | (def  | ると復元できるピクセル数が\ **減り |
+| 類似度  | os |        | ault= | **,低くすると誤判定が\ **増える**. |
+|         | _s |        | 0.75) |                                    |
+|         | im |        |       |                                    |
+|         | `` |        |       |                                    |
++---------+----+--------+-------+------------------------------------+
+| CI      | `  | [0.0,  | 可    | 高くす                             |
+| EDE2000 | `c | 100]   | (def  | ると誤判定が\ **増え**,低くすると  |
+|         | ie |        | ault= | 復元できるピクセル数が\ **減る**.  |
+|         | de |        | 5.06) |                                    |
+|         | 20 |        |       |                                    |
+|         | 00 |        |       |                                    |
+|         | `` |        |       |                                    |
++---------+----+--------+-------+------------------------------------+
+
+-  返り値
+
+   -  なし
+
+--------------
+
+**Zoomg.get_image**
+^^^^^^^^^^^^^^^^^^^
+
+``Zoomg.generate_image``\ で生成した画像を取得します.
+
+.. code:: python
+
+   image = zoom.get_image()
+
+-  引数
+
+   -  なし
+
+-  返り値
+
+========== ================== ====================
+パラメータ 型                 説明
+========== ================== ====================
+image      int 型 3 次元 list 復元した画像ファイル
+========== ================== ====================
+
+--------------
+
+**Zoomg.get_omgc**
+^^^^^^^^^^^^^^^^^^
+
+``Zoomg.generate_image``\ を使用した際,正しく復元できたか拘らず,復元したピクセル数を返します.この数は\ ``Zoomg.generate_image``\ の引数\ ``param``\ に影響されます.
+
+.. code:: python
+
+   omgc = zoom.get_omgc()
+
+-  引数
+
+   -  なし
+
+-  返り値
+
+========== === ==================
+パラメータ 型  説明
+========== === ==================
+omgc       int 復元したピクセル数
+========== === ==================
+
+--------------
+
+**Zoomg.verify**
+^^^^^^^^^^^^^^^^
+
+``Zoomg.generate_image``\ の\ ``param``\ 引数の値がどれだけいいものか検証します.部屋の画像と復元した部屋の画像からどれだけ二つの画像が似ているか計測し,復元精度を返します.
+
+.. code:: python
+
+   ok, ng, acc = zoomg.verify(room_image, comp, param)
+
+-  引数
+
++---+-------+----+-------------+--------------------------------------+
+| パ | 型   | キ | 省略        | 説明                                 |
+| ラ |      | ー |             |                                      |
+| メ |      | ワ |             |                                      |
+| ー |      | ー |             |                                      |
+| タ |      | ド |             |                                      |
+|   |       | 引 |             |                                      |
+|   |       | 数 |             |                                      |
++===+=======+====+=============+======================================+
+| r | 3     | -  | -           | 部屋の画像                           |
+| o | 次元  |    |             |                                      |
+| o | num   |    |             |                                      |
+| m | py.nd |    |             |                                      |
+| _ | array |    |             |                                      |
+| i |       |    |             |                                      |
+| m |       |    |             |                                      |
+| a |       |    |             |                                      |
+| g |       |    |             |                                      |
+| e |       |    |             |                                      |
++---+-------+----+-------------+--------------------------------------+
+| c | s     | 可 | 可          | 色差を決定する．詳細                 |
+| o | tring | (c | (default=“  | は表「\ `色差 <#色差>`__\ 」を参照． |
+| m |       | om | ciede2000”) |                                      |
+| p |       | p) |             |                                      |
++---+-------+----+-------------+--------------------------------------+
+| p | float | 可 | 可(default= | 各ピクセルが部屋の背景かバーチャル   |
+| a |       | (  | 表「\ `色差 | 背景か判定するためのパラメータ．詳細 |
+| r |       | pa |  <#色差>`__ | は表「\ `色差 <#色差>`__\ 」を参照． |
+| a |       | ra | \ 」を参照) |                                      |
+| m |       | m) |             |                                      |
++---+-------+----+-------------+--------------------------------------+
+
+-  返り値
+
+========== ===== ======================================
+パラメータ 型    説明
+========== ===== ======================================
+ok         int   部屋の画像と復元画像のピクセル一致数
+ng         int   部屋の画像と復元画像のピクセル不一致数
+acc        float 精度(``ok / (ok + ng)``)
+========== ===== ======================================
+
+--------------
+
+**Zoomg.get_height**
+^^^^^^^^^^^^^^^^^^^^
+
+生成画像の高さを取得します.\ ``zoomg.Zoomg(height, width)``\ の\ ``height``\ と同一の値になります.
+
+.. code:: python
+
+   height = zoomg.get_height()
+
+-  引数
+
+   -  なし
+
+-  返り値
+
+========== === ==============
+パラメータ 型  説明
+========== === ==============
+height     int 生成画像の高さ
+========== === ==============
+
+--------------
+
+**Zoomg.get_width**
+^^^^^^^^^^^^^^^^^^^
+
+生成画像の幅を取得します.\ ``zoomg.Zoomg(height, width)``\ の\ ``width``\ と同一の値になります.
+
+.. code:: python
+
+   width = zoomg.get_width()
+
+-  引数
+
+   -  なし
+
+-  返り値
+
+========== === ============
+パラメータ 型  説明
+========== === ============
+width      int 生成画像の幅
+========== === ============
+
+--------------
+
+**Zoomg.get_shape**
+^^^^^^^^^^^^^^^^^^^
+
+生成画像の高さと幅を取得します.\ ``zoomg.Zoomg(height, width)``\ の\ ``height``\ と同一の値になります.
+
+.. code:: python
+
+   height, width = zoomg.get_shape()
+
+-  引数
+
+   -  なし
+
+-  返り値
+
+========== === ==============
+パラメータ 型  説明
+========== === ==============
+height     int 生成画像の高さ
+width      int 生成画像の幅
+========== === ==============
+
+--------------
+
+Function
+~~~~~~~~
+
+その他,利用できる関数をこちらに記載します.
+
+**add_noise()**
+^^^^^^^^^^^^^^^
+
+背景画像の生成を妨害します.画像に対してノイズを入ります.
+
+.. code:: python
+
+   zoomg.get_shape(image&, height, width, rate)
+
+-  引数
+
++------------+-------------+-------------+-------------+-------------+
+| パラメータ | 型          | キー        | 省略        | 説明        |
+|            |             | ワード引数  |             |             |
++============+=============+=============+=============+=============+
+| image      | 3 次元      | -           | -           | ノイズを入  |
+|            | nu          |             |             | れたい画像  |
+|            | mpy.ndarray |             |             |             |
+|            | の参照      |             |             |             |
++------------+-------------+-------------+-------------+-------------+
+| height     | int         | 可(h)       | -           | ``imag      |
+|            |             |             |             | e``\ の高さ |
++------------+-------------+-------------+-------------+-------------+
+| width      | int         | 可(w)       | -           | ``im        |
+|            |             |             |             | age``\ の幅 |
++------------+-------------+-------------+-------------+-------------+
+| rate       | float       | 可(rate)    | 可(defa     | ノイズの    |
+|            |             |             | ult=0.0003) | 入れる割合  |
++------------+-------------+-------------+-------------+-------------+
+
+-  返り値
+
+========== === ==============
+パラメータ 型  説明
+========== === ==============
+height     int 生成画像の高さ
+width      int 生成画像の幅
+========== === ==============
+
+--------------
+
+Build / ビルド
+--------------
+
+-  本ソースコードのコンパイル
+
+.. code:: sh
+
+   > pwd
+   ほにゃらら/zoomg/zoomg
+
+   > clang++ -O3 -Wall -shared -std=c++17 -fPIC `python -m pybind11 --includes` -undefined dynamic_lookup zoomg.cpp ColorSpace/src/Comparison.cpp ColorSpace/src/ColorSpace.cpp ColorSpace/src/Conversion.cpp -o zoomg`python3-config --extension-suffix`
+
+-  実行
+
+.. code:: sh
+
+   > cd test
+   > pip uninstall zoomg # いらないかも
+   > python test.py sample_02.mp4
+
+.. |PyPI version| image:: https://badge.fury.io/py/zoomg.svg
+   :target: https://badge.fury.io/py/zoomg
+.. |License: MIT| image:: https://img.shields.io/badge/License-MIT-yellow.svg
+   :target: https://opensource.org/licenses/MIT
+.. |Downloads| image:: https://pepy.tech/badge/zoomg
+   :target: https://pepy.tech/project/zoomg
diff --git a/zoomg/__init__.py b/__init__.py
similarity index 100%
rename from zoomg/__init__.py
rename to __init__.py
diff --git a/avtokyo/README.md b/avtokyo/README.md
new file mode 100644
index 0000000..df68906
--- /dev/null
+++ b/avtokyo/README.md
@@ -0,0 +1,15 @@
+# AVTOKYO2020
+
+[AVTOKYO2020](https://www.avtokyo.org/2020)へのご参加ありがとうございます.
+
+## 登壇資料
+
+- [ja] slide-AVTOKYO2020.pdf (日本語版)
+- [en] slide-AVTOKYO2020.pdf (english ver.)
+
+## CTF ファイル
+
+- [ctf.mp4](https://github.com/Tsuku43/zoomg/avtokyo/ctf.mp4)
+  - zoomg を用いて flag を得ることができます.
+
+![ctf.gif](https://github.com/Tsuku43/zoomg/blob/master/images/ctf.gif?raw=true)
diff --git a/avtokyo/[en] slide-AVTOKYO2020.pdf b/avtokyo/[en] slide-AVTOKYO2020.pdf
new file mode 100644
index 0000000..e058205
Binary files /dev/null and b/avtokyo/[en] slide-AVTOKYO2020.pdf differ
diff --git a/avtokyo/[ja] slide-AVTOKYO2020.pdf b/avtokyo/[ja] slide-AVTOKYO2020.pdf
new file mode 100644
index 0000000..edb2df9
Binary files /dev/null and b/avtokyo/[ja] slide-AVTOKYO2020.pdf differ
diff --git a/zoomg/build/lib.macosx-10.15-x86_64-3.6/zoomg.cpython-36m-darwin.so b/build/lib.macosx-10.15-x86_64-3.6/zoomg.cpython-36m-darwin.so
similarity index 100%
rename from zoomg/build/lib.macosx-10.15-x86_64-3.6/zoomg.cpython-36m-darwin.so
rename to build/lib.macosx-10.15-x86_64-3.6/zoomg.cpython-36m-darwin.so
diff --git a/build/lib.macosx-11-arm64-3.9/zoomg.cpython-39-darwin.so b/build/lib.macosx-11-arm64-3.9/zoomg.cpython-39-darwin.so
new file mode 100755
index 0000000..584d376
Binary files /dev/null and b/build/lib.macosx-11-arm64-3.9/zoomg.cpython-39-darwin.so differ
diff --git a/build/lib.macosx-11.2-arm64-3.9/zoomg.cpython-39-darwin.so b/build/lib.macosx-11.2-arm64-3.9/zoomg.cpython-39-darwin.so
new file mode 100755
index 0000000..d6076bc
Binary files /dev/null and b/build/lib.macosx-11.2-arm64-3.9/zoomg.cpython-39-darwin.so differ
diff --git a/build/temp.macosx-11-arm64-3.9/zoomg.o b/build/temp.macosx-11-arm64-3.9/zoomg.o
new file mode 100644
index 0000000..0194545
Binary files /dev/null and b/build/temp.macosx-11-arm64-3.9/zoomg.o differ
diff --git a/build/temp.macosx-11.2-arm64-3.9/zoomg.o b/build/temp.macosx-11.2-arm64-3.9/zoomg.o
new file mode 100644
index 0000000..571ff14
Binary files /dev/null and b/build/temp.macosx-11.2-arm64-3.9/zoomg.o differ
diff --git a/deploy.sh b/deploy.sh
new file mode 100644
index 0000000..9499134
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,15 @@
+pip install wheel twine pybind11
+
+pandoc --from markdown --to rst zoomg_docs.md -o README.rst # ドキュメント作成
+
+rm -rf zoomg.egg-info/* dist/*
+python setup.py sdist
+python setup.py bdist_wheel
+
+pyenv local 3.9.1 # twineが3.6.4では動かない
+twine upload --repository testpypi dist/* # テスト
+# pip --no-cache-dir install --upgrade --index-url https://test.pypi.org/simple/ zoomg # テストダウンロード
+
+# twine upload --repository pypi dist/* # 本番
+# pip --no-cache-dir install --upgrade zoomg # 本番ダウンロード
+pyenv local 3.6.4
\ No newline at end of file
diff --git a/dist/zoomg-2.0.5-cp39-cp39-macosx_11_0_arm64.whl b/dist/zoomg-2.0.5-cp39-cp39-macosx_11_0_arm64.whl
new file mode 100644
index 0000000..6d8e04f
Binary files /dev/null and b/dist/zoomg-2.0.5-cp39-cp39-macosx_11_0_arm64.whl differ
diff --git a/dist/zoomg-2.0.5.tar.gz b/dist/zoomg-2.0.5.tar.gz
new file mode 100644
index 0000000..4021e00
Binary files /dev/null and b/dist/zoomg-2.0.5.tar.gz differ
diff --git a/images/ctf.gif b/images/ctf.gif
new file mode 100644
index 0000000..6f1781d
Binary files /dev/null and b/images/ctf.gif differ
diff --git a/images/icon.png b/images/icon.png
new file mode 100644
index 0000000..9aaa12e
Binary files /dev/null and b/images/icon.png differ
diff --git a/images/image_123.png b/images/image_123.png
new file mode 100644
index 0000000..f751c4c
Binary files /dev/null and b/images/image_123.png differ
diff --git a/images/room.png b/images/room.png
new file mode 100644
index 0000000..3087542
Binary files /dev/null and b/images/room.png differ
diff --git a/images/sample_01.gif b/images/sample_01.gif
new file mode 100644
index 0000000..d8d5bf6
Binary files /dev/null and b/images/sample_01.gif differ
diff --git a/images/sample_01_1-10.png b/images/sample_01_1-10.png
new file mode 100644
index 0000000..cb96053
Binary files /dev/null and b/images/sample_01_1-10.png differ
diff --git a/images/sample_01_500_500_check.png b/images/sample_01_500_500_check.png
new file mode 100644
index 0000000..c153444
Binary files /dev/null and b/images/sample_01_500_500_check.png differ
diff --git a/images/sample_01_room.png b/images/sample_01_room.png
new file mode 100644
index 0000000..28d4e18
Binary files /dev/null and b/images/sample_01_room.png differ
diff --git a/images/sample_02_500_500_check.png b/images/sample_02_500_500_check.png
new file mode 100644
index 0000000..8044b4b
Binary files /dev/null and b/images/sample_02_500_500_check.png differ
diff --git a/images/sample_02_room.png b/images/sample_02_room.png
new file mode 100644
index 0000000..9b7b5ba
Binary files /dev/null and b/images/sample_02_room.png differ
diff --git a/images/sample_02_room_5.png b/images/sample_02_room_5.png
new file mode 100644
index 0000000..c75e843
Binary files /dev/null and b/images/sample_02_room_5.png differ
diff --git a/images/sample_03_1000_1000_check.png b/images/sample_03_1000_1000_check.png
new file mode 100644
index 0000000..a1b5deb
Binary files /dev/null and b/images/sample_03_1000_1000_check.png differ
diff --git a/images/sample_03_500_500_check.png b/images/sample_03_500_500_check.png
new file mode 100644
index 0000000..198d4b0
Binary files /dev/null and b/images/sample_03_500_500_check.png differ
diff --git a/images/sample_03_room.png b/images/sample_03_room.png
new file mode 100644
index 0000000..cef633f
Binary files /dev/null and b/images/sample_03_room.png differ
diff --git a/images/verification.gif b/images/verification.gif
new file mode 100644
index 0000000..642d145
Binary files /dev/null and b/images/verification.gif differ
diff --git a/images/zoom_0_500_500_check.png b/images/zoom_0_500_500_check.png
new file mode 100644
index 0000000..9e60984
Binary files /dev/null and b/images/zoom_0_500_500_check.png differ
diff --git a/images/zoom_0_room.png b/images/zoom_0_room.png
new file mode 100644
index 0000000..a974576
Binary files /dev/null and b/images/zoom_0_room.png differ
diff --git a/images/zoom_1_500_500_check.png b/images/zoom_1_500_500_check.png
new file mode 100644
index 0000000..5992ae3
Binary files /dev/null and b/images/zoom_1_500_500_check.png differ
diff --git a/images/zoom_1_room_60.png b/images/zoom_1_room_60.png
new file mode 100644
index 0000000..77fdddb
Binary files /dev/null and b/images/zoom_1_room_60.png differ
diff --git a/images/zoom_1_room_90.png b/images/zoom_1_room_90.png
new file mode 100644
index 0000000..850e722
Binary files /dev/null and b/images/zoom_1_room_90.png differ
diff --git a/images/zoom_vbg.png b/images/zoom_vbg.png
new file mode 100644
index 0000000..3884cd6
Binary files /dev/null and b/images/zoom_vbg.png differ
diff --git a/zoomg/requirements.txt b/requirements.txt
similarity index 100%
rename from zoomg/requirements.txt
rename to requirements.txt
diff --git a/resources/README.md b/resources/README.md
new file mode 100644
index 0000000..bb6b987
--- /dev/null
+++ b/resources/README.md
@@ -0,0 +1,13 @@
+# Resources
+
+## verification.mp4
+
+理想的な復元可能動画
+
+![verification.gif](https://github.com/Tsuku43/zoomg/blob/master/images/verification.gif?raw=true)
+
+## verification.png
+
+![verification.png](https://github.com/Tsuku43/zoomg/blob/master/resources/verification.png?raw=true)
+
+理想的な復元可能動画の背景画像
diff --git a/sample/README.md b/sample/README.md
new file mode 100644
index 0000000..ac6c5ef
--- /dev/null
+++ b/sample/README.md
@@ -0,0 +1,49 @@
+# Sample
+
+## [main.py](https://github.com/Tsuku43/zoomg/blob/master/sample/main.py)
+
+zoomg を用いた最も簡単なサンプルプログラム
+
+```python
+import zoomg
+import cv2
+import sys
+import numpy
+from tqdm import tqdm
+
+# ビデオ読み込みの初期設定
+filename = sys.argv[1]
+video = cv2.VideoCapture(filename)
+height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
+width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
+count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
+
+# zoomgの初期化
+zoom = zoomg.Zoomg(height, width)
+
+# 進捗バー
+bar = tqdm(total=count)
+
+while True:
+    # フレーム読み込み
+    ret, frame = video.read()
+    if not ret:
+        break
+    # zoomgに画像を追加
+    zoom.add_image(frame)
+    # 進捗バー更新
+    bar.update(1)
+
+# 背景画像を生成
+zoom.generate_image()
+# 背景画像を取得
+image = zoom.get_image()
+
+# 背景画像を保存
+cv2.imwrite("room.png", numpy.array(image))
+bar.close()
+```
+
+## room.png
+
+![room.png](https://github.com/Tsuku43/zoomg/blob/master/sample/room.png?raw=true)
diff --git a/zoomg/setup.py b/setup.py
similarity index 99%
rename from zoomg/setup.py
rename to setup.py
index df93865..ea3fe38 100644
--- a/zoomg/setup.py
+++ b/setup.py
@@ -119,7 +119,7 @@ def build_extensions(self):
 setup(
     name="zoomg",
     copyright="Copyright (C) 2020 Ryusei Ishikawa, Satoki Tsuji",
-    version="1.0.9",
+    version="2.0.5",
     license="MIT",
     author="Ryusei Ishikawa, Satoki Tsuji",
     author_email="",
diff --git a/zoomg/zoomg.cpp b/zoomg.cpp
similarity index 58%
rename from zoomg/zoomg.cpp
rename to zoomg.cpp
index ebc78c6..b0ac325 100644
--- a/zoomg/zoomg.cpp
+++ b/zoomg.cpp
@@ -2,15 +2,26 @@
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h>
 
+#include <cassert>
 #include <iostream>
 #include <map>
 #include <tuple>
 #include <vector>
 
+#include "ColorSpace/src/ColorSpace.h"
+#include "ColorSpace/src/Comparison.h"
+
 using Pixel = std::vector<uint8_t>;
 using Image = std::vector<std::vector<Pixel>>;
 using Movie = std::vector<Image>;
 
+void my_assert(bool conditions, std::string msg = "something error.") {
+    if (!conditions) {
+        printf("[ERROR] %s\n", msg.c_str());
+    }
+    assert(conditions);
+}
+
 class Zoomg {
    private:
     // 画素の値がキー，値を<個数, 出現タイミング>として出現頻度を管理
@@ -62,7 +73,28 @@ class Zoomg {
             }
         }
     }
-    void generate_image(const double param, const int noise_frame) {
+    void generate_image(const std::string comp, double param,
+                        const int noise_frame) {
+        // default値の設定
+        if (param == -1) {
+            if (comp == "ciede2000") {
+                param = 5.06;
+            } else if (comp == "cos_sim") {
+                param = 0.75;
+            }
+        }
+        // validation
+        my_assert((comp == "ciede2000" || comp == "cos_sim"),
+                  "Please set 'ciede2000' or 'cos_sim' for 'camp'");
+        if (comp == "ciede2000") {
+            my_assert((0.0 <= param && param <= 100.0),
+                      "The range of the parameters of 'ciede2000' is "
+                      "between 0.0 and 100.0");
+        } else if (comp == "cos_sim") {
+            my_assert((0.0 <= param && param <= 1.0),
+                      "The range of the parameters of 'cos_sim' is "
+                      "between 0.0 and 1.0");
+        }
         // 画像を生成
         for (int h = 0; h < height; ++h) {
             for (int w = 0; w < width; ++w) {
@@ -88,10 +120,28 @@ class Zoomg {
                 [&]() -> void {
                     // コサイン類似度がparam未満で出現タイミングが最も早い画素を探索
                     for (auto p : most_common) {
-                        if (cos_sim(std::get<0>(p), most) < param) {
-                            ++omgc;
-                            image[h][w] = std::get<0>(p);
-                            return;
+                        if (comp == "ciede2000") {
+                            Pixel p_bgr = std::get<0>(p);
+                            Pixel most_bgr = most;
+                            ColorSpace::Rgb p_color(p_bgr[2], p_bgr[1],
+                                                    p_bgr[0]);
+                            ColorSpace::Rgb most_color(most_bgr[2], most_bgr[1],
+                                                       most_bgr[0]);
+                            auto color_diff =
+                                ColorSpace::Cie2000Comparison::Compare(
+                                    &p_color, &most_color);
+
+                            if (color_diff > param) {
+                                ++omgc;
+                                image[h][w] = std::get<0>(p);
+                                return;
+                            }
+                        } else if (comp == "cos_sim") {
+                            if (cos_sim(std::get<0>(p), most) < param) {
+                                ++omgc;
+                                image[h][w] = std::get<0>(p);
+                                return;
+                            }
                         }
                     }
                     // 探索しても見つからなかった場合
@@ -120,18 +170,53 @@ class Zoomg {
         // 生成された画像を取得
         return {height, width};
     }
-    std::tuple<int, int, double> verify(const pybind11::array_t<int> &img_np) {
+    std::tuple<int, int, double> verify(const pybind11::array_t<int> &img_np,
+                                        const std::string comp, double param) {
         // 生成した画像がどれくらい部屋を復元できているか検証
+        // default値の設定
+        if (param == -1) {
+            if (comp == "ciede2000") {
+                param = 5.06;
+            } else if (comp == "cos_sim") {
+                param = 0.99;
+            }
+        }
+        // validation
+        my_assert((comp == "ciede2000" || comp == "cos_sim"),
+                  "Please set 'ciede2000' or 'cos_sim' for 'camp'");
+        if (comp == "ciede2000") {
+            my_assert((0.0 <= param && param <= 100.0),
+                      "The range of the parameters of 'ciede2000' is "
+                      "between 0.0 and 100.0");
+        } else if (comp == "cos_sim") {
+            my_assert((0.0 <= param && param <= 1.0),
+                      "The range of the parameters of 'cos_sim' is "
+                      "between 0.0 and 1.0");
+        }
         const uint8_t *verify_img = (const uint8_t *)img_np.request().ptr;
         int ok = 0, ng = 0;
         for (int h = 0; h < height; ++h) {
             for (int w = 0; w < width; ++w) {
                 const Pixel p = Pixel(verify_img + 3 * (h * width + w),
                                       verify_img + 3 * (h * width + w + 1));
-                if (cos_sim(image[h][w], p) > 0.999) {
-                    ++ok;
-                } else {
-                    ++ng;
+                if (comp == "ciede2000") {
+                    ColorSpace::Rgb p_color(p[2], p[1], p[0]);
+                    ColorSpace::Rgb most_color(image[h][w][2], image[h][w][1],
+                                               image[h][w][0]);
+                    auto color_diff = ColorSpace::Cie2000Comparison::Compare(
+                        &p_color, &most_color);
+
+                    if (color_diff < param) {
+                        ++ok;
+                    } else {
+                        ++ng;
+                    }
+                } else if (comp == "cos_sim") {
+                    if (cos_sim(image[h][w], p) > param) {
+                        ++ok;
+                    } else {
+                        ++ng;
+                    }
                 }
             }
         }
@@ -146,9 +231,8 @@ const int w := 画像のはば
 const int frame := 生成するフレーム数
 const double rate := 過疎率
 */
-
-void add_noise(const pybind11::array_t<uint8_t> &image, const int h, const int w,
-               const double rate) {
+void add_noise(const pybind11::array_t<uint8_t> &image, const int h,
+               const int w, const double rate) {
     // 画像をノイズ入り動画へ変換
     uint8_t *img = (uint8_t *)image.request().ptr;
     srand((unsigned)time(NULL));
@@ -168,13 +252,15 @@ PYBIND11_MODULE(zoomg, m) {
              pybind11::arg("w"))
         .def("add_image", &Zoomg::add_image)
         .def("generate_image", &Zoomg::generate_image,
-             pybind11::arg("param") = 0.75, pybind11::arg("noise_frame") = 0)
+             pybind11::arg("comp") = "ciede2000", pybind11::arg("param") = -1,
+             pybind11::arg("noise_frame") = 0)
         .def("get_image", &Zoomg::get_image)
         .def("get_omgc", &Zoomg::get_omgc)
-        .def("verify", &Zoomg::verify)
+        .def("verify", &Zoomg::verify, pybind11::arg("img_np"),
+             pybind11::arg("comp") = "ciede2000", pybind11::arg("param") = -1)
         .def("get_height", &Zoomg::get_height)
         .def("get_width", &Zoomg::get_width)
         .def("get_shape", &Zoomg::get_shape);
     m.def("add_noise", &add_noise, pybind11::arg("image"), pybind11::arg("h"),
           pybind11::arg("w"), pybind11::arg("rate") = 0.0003);
-}
+}
\ No newline at end of file
diff --git a/zoomg.cpython-36m-darwin.so b/zoomg.cpython-36m-darwin.so
new file mode 100755
index 0000000..223f113
Binary files /dev/null and b/zoomg.cpython-36m-darwin.so differ
diff --git a/zoomg/LICENSE b/zoomg/LICENSE
deleted file mode 100644
index 7f047d4..0000000
--- a/zoomg/LICENSE
+++ /dev/null
@@ -1,6 +0,0 @@
-Copyright (c) 2020 Ryusei Ishikawa, Satoki Tsuji
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/zoomg/README.rst b/zoomg/README.rst
deleted file mode 100644
index c0fc432..0000000
--- a/zoomg/README.rst
+++ /dev/null
@@ -1,1 +0,0 @@
-We are just getting ready...
diff --git a/zoomg/build/temp.macosx-10.15-x86_64-3.6/zoomg.o b/zoomg/build/temp.macosx-10.15-x86_64-3.6/zoomg.o
deleted file mode 100644
index f14a3d3..0000000
Binary files a/zoomg/build/temp.macosx-10.15-x86_64-3.6/zoomg.o and /dev/null differ
diff --git a/zoomg/dist/zoomg-1.0.9-cp36-cp36m-macosx_10_15_x86_64.whl b/zoomg/dist/zoomg-1.0.9-cp36-cp36m-macosx_10_15_x86_64.whl
deleted file mode 100644
index 5d6f6ae..0000000
Binary files a/zoomg/dist/zoomg-1.0.9-cp36-cp36m-macosx_10_15_x86_64.whl and /dev/null differ
diff --git a/zoomg/dist/zoomg-1.0.9.tar.gz b/zoomg/dist/zoomg-1.0.9.tar.gz
deleted file mode 100644
index 909cc97..0000000
Binary files a/zoomg/dist/zoomg-1.0.9.tar.gz and /dev/null differ
diff --git a/zoomg/var/folders/0c/n1zxxl1d5bz0y497czjwxlh00000gn/T/tmp4k43lfu5.o b/zoomg/var/folders/0c/n1zxxl1d5bz0y497czjwxlh00000gn/T/tmp4k43lfu5.o
deleted file mode 100644
index afb876a..0000000
Binary files a/zoomg/var/folders/0c/n1zxxl1d5bz0y497czjwxlh00000gn/T/tmp4k43lfu5.o and /dev/null differ
diff --git a/zoomg/var/folders/0c/n1zxxl1d5bz0y497czjwxlh00000gn/T/tmp8v6aqxg6.o b/zoomg/var/folders/0c/n1zxxl1d5bz0y497czjwxlh00000gn/T/tmp8v6aqxg6.o
deleted file mode 100644
index afb876a..0000000
Binary files a/zoomg/var/folders/0c/n1zxxl1d5bz0y497czjwxlh00000gn/T/tmp8v6aqxg6.o and /dev/null differ
diff --git a/zoomg/zoomg.cpython-36m-darwin.so b/zoomg/zoomg.cpython-36m-darwin.so
deleted file mode 100755
index 12e8620..0000000
Binary files a/zoomg/zoomg.cpython-36m-darwin.so and /dev/null differ
diff --git a/zoomg/zoomg.egg-info/PKG-INFO b/zoomg/zoomg.egg-info/PKG-INFO
deleted file mode 100644
index 01f5aaf..0000000
--- a/zoomg/zoomg.egg-info/PKG-INFO
+++ /dev/null
@@ -1,11 +0,0 @@
-Metadata-Version: 1.0
-Name: zoomg
-Version: 1.0.9
-Summary: Restoring room images from virtual background images.
-Home-page: https://github.com/Tsuku43/zoomg
-Author: Ryusei Ishikawa, Satoki Tsuji
-Author-email: UNKNOWN
-License: MIT
-Description: UNKNOWN
-Keywords: zoom virtual background reconstruction
-Platform: UNKNOWN
diff --git a/zoomg/zoomg.egg-info/SOURCES.txt b/zoomg/zoomg.egg-info/SOURCES.txt
deleted file mode 100644
index e0fc5b4..0000000
--- a/zoomg/zoomg.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-LICENSE
-MANIFEST.in
-README.rst
-setup.py
-zoomg.cpp
-zoomg.egg-info/PKG-INFO
-zoomg.egg-info/SOURCES.txt
-zoomg.egg-info/dependency_links.txt
-zoomg.egg-info/not-zip-safe
-zoomg.egg-info/requires.txt
-zoomg.egg-info/top_level.txt
\ No newline at end of file
diff --git a/zoomg/zoomg.egg-info/dependency_links.txt b/zoomg/zoomg.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/zoomg/zoomg.egg-info/dependency_links.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-
diff --git a/zoomg/zoomg.egg-info/not-zip-safe b/zoomg/zoomg.egg-info/not-zip-safe
deleted file mode 100644
index 8b13789..0000000
--- a/zoomg/zoomg.egg-info/not-zip-safe
+++ /dev/null
@@ -1,1 +0,0 @@
-
diff --git a/zoomg/zoomg.egg-info/requires.txt b/zoomg/zoomg.egg-info/requires.txt
deleted file mode 100644
index cc35cb4..0000000
--- a/zoomg/zoomg.egg-info/requires.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-pybind11>=2.4
diff --git a/zoomg/zoomg.egg-info/top_level.txt b/zoomg/zoomg.egg-info/top_level.txt
deleted file mode 100644
index 9377acc..0000000
--- a/zoomg/zoomg.egg-info/top_level.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-zoomg
diff --git a/zoomg_docs.md b/zoomg_docs.md
new file mode 100644
index 0000000..4e5658d
--- /dev/null
+++ b/zoomg_docs.md
@@ -0,0 +1,320 @@
+[![PyPI version](https://badge.fury.io/py/zoomg.svg)](https://badge.fury.io/py/zoomg) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Downloads](https://pepy.tech/badge/zoomg)](https://pepy.tech/project/zoomg)
+
+# zoomg Docs
+
+バーチャル背景適用済み動画からバーチャル背景を復元するライブラリ
+
+![icon](https://github.com/Tsuku43/zoomg/blob/master/images/icon.png?raw=true)
+
+## System Requirements / 動作保証環境
+
+- python 3.6.4
+- pip 20.2.4
+- OS
+  - macOS Catalina 10.15.7 (x86_64)
+  - macOS Bug Sur 11.4 (aarch64)
+  - Ubuntu 20.04.1 LTS / 18.04.4 LTS
+
+## Installing / インストール
+
+* aarch64環境の場合
+
+```shell
+pip install zoomg
+```
+
+* x86_64環境の場合
+
+```shell
+pip install git+https://github.com/Tsuku43/zoomg
+```
+
+**Windows では動作保証をしていません**
+
+## How to use / 使用方法
+
+### 簡単な使用方法
+
+```sh
+python3 sample.py sample_video.mp4
+```
+
+```python
+import zoomg
+import cv2
+import sys
+import numpy
+
+
+# ビデオ読み込みの初期設定
+filename = sys.argv[1]
+video = cv2.VideoCapture(filename)
+height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
+width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
+
+# zoomgの初期化
+zoom = zoomg.Zoomg(height, width)
+
+while True:
+    # フレーム読み込み
+    ret, frame = video.read()
+    if not ret:
+        break
+    # zoomgに画像を追加
+    zoom.add_image(frame)
+
+# 背景画像を生成
+zoom.generate_image()
+# 背景画像を取得
+image = zoom.get_image()
+# 背景画像を保存
+cv2.imwrite("room.png", numpy.array(image))
+```
+
+### Zoomg クラス
+
+背景画像の生成を行います.
+
+#### **コンストラクタ**
+
+```python
+zoom = zoomg.Zoomg(height, width)
+```
+
+- 引数
+
+| パラメータ | 型  | キーワード引数 | 省略 | 説明           |
+| ---------- | --- | -------------- | ---- | -------------- |
+| height     | int | 可(h)          | -    | 入力画像の高さ |
+| width      | int | 可(w)          | -    | 入力画像の幅   |
+
+- 返り値
+
+| パラメータ | 型    | 説明               |
+| ---------- | ----- | ------------------ |
+| zoom       | Zoomg | Zoomg オブジェクト |
+
+---
+
+#### **Zoomg.add_image**
+
+zoomg オブジェクトに画像を追加します.動画を入力したい場合はフレーム単位で分割する必要があります.
+
+```python
+zoom.add_image(frame)
+```
+
+- 引数
+
+| パラメータ | 型                   | キーワード引数 | 省略 | 説明                             |
+| ---------- | -------------------- | -------------- | ---- | -------------------------------- |
+| frame      | 3 次元 numpy.ndarray | -              | -    | zoomg オブジェクトに追加する画像 |
+
+- 返り値
+  - なし
+
+---
+
+#### **Zoomg.generate_image**
+
+`Zoomg.add_image`で追加した画像から背景画像を復元する.
+
+```python
+zoom.generate_image(comp, param, noise_frame)
+```
+
+- 引数
+
+| パラメータ  | 型     | キーワード引数  | 省略                                  | 説明                                                                                                |
+| ----------- | ------ | --------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| comp        | string | 可(comp)        | 可(default="ciede2000")               | 色差を決定する．詳細は表「[色差](#色差)」を参照．                                                   |
+| param       | float  | 可(param)       | 可(default=表「[色差](#色差)」を参照) | 各ピクセルが部屋の背景かバーチャル背景か判定するためのパラメータ．詳細は表「[色差](#色差)」を参照． |
+| noise_frame | int    | 可(noise_frame) | 可(default=1)                         | 画像にノイズが多く含まれている場合,ノイズを軽減するためのパラメータ                                 |
+
+##### 色差
+
+| 色差計算アルゴリズム | comp        | param 指定可能範囲 | 省略             | 説明                                                                   |
+| -------------------- | ----------- | ------------------ | ---------------- | ---------------------------------------------------------------------- |
+| コサイン類似度       | `cos_sim`   | [0.0, 1.0]         | 可(default=0.75) | 高くすると復元できるピクセル数が**減り**,低くすると誤判定が**増える**. |
+| CIEDE2000            | `ciede2000` | [0.0, 100]         | 可(default=5.06) | 高くすると誤判定が**増え**,低くすると復元できるピクセル数が**減る**.   |
+
+- 返り値
+  - なし
+
+---
+
+#### **Zoomg.get_image**
+
+`Zoomg.generate_image`で生成した画像を取得します.
+
+```python
+image = zoom.get_image()
+```
+
+- 引数
+
+  - なし
+
+- 返り値
+
+| パラメータ | 型                 | 説明                 |
+| ---------- | ------------------ | -------------------- |
+| image      | int 型 3 次元 list | 復元した画像ファイル |
+
+---
+
+#### **Zoomg.get_omgc**
+
+`Zoomg.generate_image`を使用した際,正しく復元できたか拘らず,復元したピクセル数を返します.この数は`Zoomg.generate_image`の引数`param`に影響されます.
+
+```python
+omgc = zoom.get_omgc()
+```
+
+- 引数
+
+  - なし
+
+- 返り値
+
+| パラメータ | 型  | 説明               |
+| ---------- | --- | ------------------ |
+| omgc       | int | 復元したピクセル数 |
+
+---
+
+#### **Zoomg.verify**
+
+`Zoomg.generate_image`の`param`引数の値がどれだけいいものか検証します.部屋の画像と復元した部屋の画像からどれだけ二つの画像が似ているか計測し,復元精度を返します.
+
+```python
+ok, ng, acc = zoomg.verify(room_image, comp, param)
+```
+
+- 引数
+
+| パラメータ | 型                   | キーワード引数 | 省略                                  | 説明                                                                                                |
+| ---------- | -------------------- | -------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------- |
+| room_image | 3 次元 numpy.ndarray | -              | -                                     | 部屋の画像                                                                                          |
+| comp       | string               | 可(comp)       | 可(default="ciede2000")               | 色差を決定する．詳細は表「[色差](#色差)」を参照．                                                   |
+| param      | float                | 可(param)      | 可(default=表「[色差](#色差)」を参照) | 各ピクセルが部屋の背景かバーチャル背景か判定するためのパラメータ．詳細は表「[色差](#色差)」を参照． |
+
+- 返り値
+
+| パラメータ | 型    | 説明                                   |
+| ---------- | ----- | -------------------------------------- |
+| ok         | int   | 部屋の画像と復元画像のピクセル一致数   |
+| ng         | int   | 部屋の画像と復元画像のピクセル不一致数 |
+| acc        | float | 精度(`ok / (ok + ng)`)                 |
+
+---
+
+#### **Zoomg.get_height**
+
+生成画像の高さを取得します.`zoomg.Zoomg(height, width)`の`height`と同一の値になります.
+
+```python
+height = zoomg.get_height()
+```
+
+- 引数
+
+  - なし
+
+- 返り値
+
+| パラメータ | 型  | 説明           |
+| ---------- | --- | -------------- |
+| height     | int | 生成画像の高さ |
+
+---
+
+#### **Zoomg.get_width**
+
+生成画像の幅を取得します.`zoomg.Zoomg(height, width)`の`width`と同一の値になります.
+
+```python
+width = zoomg.get_width()
+```
+
+- 引数
+
+  - なし
+
+- 返り値
+
+| パラメータ | 型  | 説明         |
+| ---------- | --- | ------------ |
+| width      | int | 生成画像の幅 |
+
+---
+
+#### **Zoomg.get_shape**
+
+生成画像の高さと幅を取得します.`zoomg.Zoomg(height, width)`の`height`と同一の値になります.
+
+```python
+height, width = zoomg.get_shape()
+```
+
+- 引数
+
+  - なし
+
+- 返り値
+
+| パラメータ | 型  | 説明           |
+| ---------- | --- | -------------- |
+| height     | int | 生成画像の高さ |
+| width      | int | 生成画像の幅   |
+
+---
+
+### Function
+
+その他,利用できる関数をこちらに記載します.
+
+#### **add_noise()**
+
+背景画像の生成を妨害します.画像に対してノイズを入ります.
+
+```python
+zoomg.get_shape(image&, height, width, rate)
+```
+
+- 引数
+
+| パラメータ | 型                          | キーワード引数 | 省略               | 説明                 |
+| ---------- | --------------------------- | -------------- | ------------------ | -------------------- |
+| image      | 3 次元 numpy.ndarray の参照 | -              | -                  | ノイズを入れたい画像 |
+| height     | int                         | 可(h)          | -                  | `image`の高さ        |
+| width      | int                         | 可(w)          | -                  | `image`の幅          |
+| rate       | float                       | 可(rate)       | 可(default=0.0003) | ノイズの入れる割合   |
+
+- 返り値
+
+| パラメータ | 型  | 説明           |
+| ---------- | --- | -------------- |
+| height     | int | 生成画像の高さ |
+| width      | int | 生成画像の幅   |
+
+---
+
+## Build / ビルド
+
+- 本ソースコードのコンパイル
+
+```sh
+> pwd
+ほにゃらら/zoomg/zoomg
+
+> clang++ -O3 -Wall -shared -std=c++17 -fPIC `python -m pybind11 --includes` -undefined dynamic_lookup zoomg.cpp ColorSpace/src/Comparison.cpp ColorSpace/src/ColorSpace.cpp ColorSpace/src/Conversion.cpp -o zoomg`python3-config --extension-suffix`
+```
+
+- 実行
+
+```sh
+> cd test
+> pip uninstall zoomg # いらないかも
+> python test.py sample_02.mp4
+```


Test patch:
diff --git a/ColorSpace/test.cpp b/ColorSpace/test.cpp
new file mode 100644
index 0000000..dfb1069
--- /dev/null
+++ b/ColorSpace/test.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+
+#include "src/ColorSpace.h"
+#include "src/Comparison.h"
+using namespace std;
+int main() {
+    ColorSpace::Rgb a(132, 132, 32);
+    ColorSpace::Rgb b(132, 131, 32);
+    auto p = ColorSpace::Cie2000Comparison::Compare(&a, &b);
+    cout << p << endl;
+}
\ No newline at end of file