diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds.mp4" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds.mp4"
new file mode 100644
index 0000000000000000000000000000000000000000..0b7383093d4de16c9b4e8c3aa00008f5bb795df9
Binary files /dev/null and "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds.mp4" differ
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds_concat.jpg" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds_concat.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..ce2e377bc3cc57b3a3d22e16ef42c4907c005d0c
Binary files /dev/null and "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds_concat.jpg" differ
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds_concat.mp4" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds_concat.mp4"
new file mode 100644
index 0000000000000000000000000000000000000000..ef911ca7848d0a5d451cfd34f30f5d8a10ca172e
Binary files /dev/null and "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/birds_concat.mp4" differ
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/bug.jpg" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/bug.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..bb404eace730b21f589a9782d4652e0ea065663a
Binary files /dev/null and "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/bug.jpg" differ
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/bug_band.jpg" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/bug_band.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..c9f1a6b853d31ac8527aeaf9d4cbce71094f381e
Binary files /dev/null and "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/bug_band.jpg" differ
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/config.json" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/config.json"
index 747f6cd75e529f177e9c65c0ff6e6b509ff1e065..2d8573fd27a4e5720ab76844d4c3e3a64c3a67d1 100644
--- "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/config.json"
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/config.json"
@@ -2,5 +2,9 @@
"node_id": "opencv-04cf975c42894174bd5619ed44ea5e87",
"keywords": [],
"children": [],
- "export": []
+ "export": [
+ "img_read_write.json",
+ "video_read_write.json",
+ "img_buffer_convert.json"
+ ]
}
\ No newline at end of file
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.json" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.json"
new file mode 100644
index 0000000000000000000000000000000000000000..fdda203634da2c6660e0b868a9e651f1d4bdd41e
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.json"
@@ -0,0 +1,6 @@
+{
+ "type": "code_options",
+ "author": "huanhuilong",
+ "source": "img_buffer_convert.md",
+ "notebook_enable": true
+}
\ No newline at end of file
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.md" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.md"
new file mode 100644
index 0000000000000000000000000000000000000000..8a49be90e806e6aa326fdbd33182cba12fc730ed
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.md"
@@ -0,0 +1,83 @@
+# 甲壳虫的Base64之旅
+
+如下的一只甲壳虫,我们希望把它编码成 Base64,再从Base64解码出来。
+![](./bug.jpg)
+
+代码框架如下:
+
+```python
+import numpy as np
+import cv2
+import base64
+
+def img_to_base64(img):
+ # TODO(You):
+
+def img_from_base64(img_base64):
+ # TODO(You):
+
+if __name__ == '__main__':
+ img = cv2.imread('bug.jpg')
+
+ img_base64 = img_to_base64(img)
+ img = img_from_base64(img_base64)
+
+ cv2.imshow('img_decode', img)
+ cv2.waitKey()
+ cv2.destroyAllWindows()
+```
+
+以下对两个函数实现正确的是?
+
+## 答案
+
+```python
+def img_to_base64(img):
+ return base64.b64encode(cv2.imencode('.jpg', img)[1]).decode()
+
+def img_from_base64(img_base64):
+ jpg_original = base64.b64decode(img_base64)
+ jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
+ img = cv2.imdecode(jpg_as_np, flags=1)
+ return img
+```
+
+## 选项
+
+### A
+
+```python
+def img_to_base64(img):
+ return base64.b64encode(cv2.imencode('.jpg', img)[1])
+
+def img_from_base64(img_base64):
+ jpg_original = base64.b64decode(img_base64)
+ img = cv2.imdecode(jpg_original, flags=1)
+ return img
+```
+
+### B
+
+```python
+def img_to_base64(img):
+ return base64.b64encode(cv2.imencode('.jpg', img)).decode()
+
+def img_from_base64(img_base64):
+ jpg_original = base64.b64decode(img_base64)
+ jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
+ img = cv2.imdecode(jpg_as_np, flags=1)
+ return img
+```
+
+### C
+
+```python
+def img_to_base64(img):
+ return base64.b64encode(cv2.imencode('.jpg', img)[1]).decode()
+
+def img_from_base64(img_base64):
+ jpg_original = base64.b64decode(img_base64)
+ jpg_as_np = np.frombuffer(jpg_original)
+ img = cv2.imdecode(jpg_as_np, flags=1)
+ return img
+```
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.py" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.py"
new file mode 100644
index 0000000000000000000000000000000000000000..7f55a966f1bb7ec260681484a224292727be454a
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_buffer_convert.py"
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+import numpy as np
+import cv2
+import base64
+
+
+def img_to_base64(img):
+ return base64.b64encode(cv2.imencode('.jpg', img)[1]).decode()
+
+
+def img_from_base64(img_base64):
+ jpg_original = base64.b64decode(img_base64)
+ jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
+ img = cv2.imdecode(jpg_as_np, flags=1)
+ return img
+
+
+if __name__ == '__main__':
+ img = cv2.imread('bug.jpg')
+
+ img_base64 = img_to_base64(img)
+ img = img_from_base64(img_base64)
+
+ cv2.imshow('img_decode', img)
+ cv2.waitKey()
+ cv2.destroyAllWindows()
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_wirte.json" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_wirte.json"
new file mode 100644
index 0000000000000000000000000000000000000000..a68d89b552756d5a14d4e622f82926073e767917
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_wirte.json"
@@ -0,0 +1,6 @@
+{
+ "type": "code_options",
+ "author": "huanhuilong",
+ "source": "img_read_write.md",
+ "notebook_enable": true
+}
\ No newline at end of file
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_write.md" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_write.md"
new file mode 100644
index 0000000000000000000000000000000000000000..9ef32fb1c3b19525ea5fb44fc22d0e842b434702
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_write.md"
@@ -0,0 +1,102 @@
+# 甲壳虫乐队
+
+一只甲壳虫想组个乐队,但是临时找不到队友。请使用 OpenCV 读取下面的彩色甲壳虫图片 `'bug.jpg'`,帮助他变身灰色甲壳虫,然后完成组队。
+![](./bug.jpg)
+
+**显示甲壳虫乐队并写入到 `'bug_band.jpg'`**:
+![](./bug_band.jpg)
+
+以下实现正确的是?
+
+## 答案
+
+```python
+import numpy as np
+import cv2
+
+if __name__ == '__main__':
+ bug_img = cv2.imread("bug.jpg")
+ bug_img_gray = cv2.cvtColor(bug_img, cv2.COLOR_BGR2GRAY)
+
+ bug_img_gray_by_BGR_space = cv2.cvtColor(bug_img_gray, cv2.COLOR_GRAY2BGR)
+ bug_img_concat = np.concatenate(
+ (bug_img, bug_img_gray_by_BGR_space),
+ axis=1
+ )
+ cv2.imwrite("bug_band.jpg", bug_img_gray)
+
+ cv2.imshow('甲壳虫乐队', bug_img_concat)
+
+ cv2.waitKey(0)
+ cv2.destroyAllWindows()
+```
+
+## 选项
+
+### 读写api名字错误
+
+```python
+import numpy as np
+import cv2
+
+if __name__ == '__main__':
+ bug_img = cv2.read("bug.jpg")
+ bug_img_gray = cv2.cvtColor(bug_img, cv2.COLOR_BGR2GRAY)
+
+ bug_img_gray_by_BGR_space = cv2.cvtColor(bug_img_gray, cv2.COLOR_GRAY2BGR)
+ bug_img_concat = np.concatenate(
+ (bug_img, bug_img_gray_by_BGR_space),
+ axis=1
+ )
+ cv2.write("bug_band.jpg", bug_img_gray)
+
+ cv2.imshow('甲壳虫乐队', bug_img_concat)
+
+ cv2.waitKey(0)
+ cv2.destroyAllWindows()
+```
+
+### 写入参数顺序错误
+
+```python
+import numpy as np
+import cv2
+
+if __name__ == '__main__':
+ bug_img = cv2.imread("bug.jpg")
+ bug_img_gray = cv2.cvtColor(bug_img, cv2.COLOR_BGR2GRAY)
+
+ bug_img_gray_by_BGR_space = cv2.cvtColor(bug_img_gray, cv2.COLOR_GRAY2BGR)
+ bug_img_concat = np.concatenate(
+ (bug_img, bug_img_gray_by_BGR_space),
+ axis=1
+ )
+ cv2.imwrite(bug_img_gray, "bug_band.jpg")
+
+ cv2.imshow('甲壳虫乐队', bug_img_concat)
+
+ cv2.waitKey(0)
+ cv2.destroyAllWindows()
+```
+
+### 不能合并彩色和灰色,尺寸不同
+
+```python
+import numpy as np
+import cv2
+
+if __name__ == '__main__':
+ bug_img = cv2.imread("bug.jpg")
+ bug_img_gray = cv2.cvtColor(bug_img, cv2.COLOR_BGR2GRAY)
+
+ bug_img_concat = np.concatenate(
+ (bug_img, bug_img_gray),
+ axis=1
+ )
+ cv2.imwrite("bug_img_concat.jpg", bug_img_concat)
+
+ cv2.imshow('甲壳虫乐队', bug_img_gray)
+
+ cv2.waitKey(0)
+ cv2.destroyAllWindows()
+```
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_write.py" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_write.py"
new file mode 100644
index 0000000000000000000000000000000000000000..6c19d168e4af3c655ca30e2614c6932799c4ed4b
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/img_read_write.py"
@@ -0,0 +1,18 @@
+import numpy as np
+import cv2
+
+if __name__ == '__main__':
+ bug_img = cv2.imread("bug.jpg")
+ bug_img_gray = cv2.cvtColor(bug_img, cv2.COLOR_BGR2GRAY)
+
+ bug_img_gray_by_BGR_space = cv2.cvtColor(bug_img_gray, cv2.COLOR_GRAY2BGR)
+ bug_img_concat = np.concatenate(
+ (bug_img, bug_img_gray_by_BGR_space),
+ axis=1
+ )
+ cv2.imwrite("bug_band.jpg", bug_img_gray)
+
+ cv2.imshow('甲壳虫乐队', bug_img_concat)
+
+ cv2.waitKey(0)
+ cv2.destroyAllWindows()
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.json" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.json"
new file mode 100644
index 0000000000000000000000000000000000000000..dea237cb6da5032c15b16f506cd07af4e06ab430
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.json"
@@ -0,0 +1,6 @@
+{
+ "type": "code_options",
+ "author": "huanhuilong",
+ "source": "video_read_write.md",
+ "notebook_enable": true
+}
\ No newline at end of file
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.md" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.md"
new file mode 100644
index 0000000000000000000000000000000000000000..13d7118710891c102127b4628bc1637ee9e41af0
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.md"
@@ -0,0 +1,104 @@
+# 早起的鸟儿有虫吃
+
+早起的鸟儿不但有虫吃,还可以照镜子。请你帮助鸟儿们跟镜像合影。
+
+这是鸟儿的视频:
+
+
+这是合影的效果:
+
+
+基本的实现代码如下:
+
+```python
+import numpy as np
+import cv2
+
+if __name__ == '__main__':
+ cap = cv2.VideoCapture('birds.mp4')
+
+ out = ...
+ # TODO(You): 请在此正确创建待保存的目标mp4文件`out`
+
+ while(cap.isOpened()):
+
+ ret, bird_frame = cap.read()
+ if bird_frame is None:
+ break
+
+ bird_flip_frame = cv2.flip(bird_frame, 0)
+ bird_concat_frame = np.concatenate(
+ (bird_frame, bird_flip_frame),
+ axis=1
+ )
+
+ cv2.imshow('bird_concat_frame', bird_concat_frame)
+ out.write(bird_concat_frame)
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+ out.release()
+ cap.release()
+
+ cv2.destroyAllWindows()
+```
+
+以下正确创建了输出mp4文件`out`变量的是?
+
+## 答案
+
+```python
+width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
+height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
+fps = cap.get(cv2.CAP_PROP_FPS)
+out = cv2.VideoWriter(
+ 'birds_concat.mp4',
+ cv2.VideoWriter_fourcc(*'mp4v'),
+ fps,
+ (width*2, height)
+)
+```
+
+## 选项
+
+### 宽度不对
+
+```python
+width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
+height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
+fps = cap.get(cv2.CAP_PROP_FPS)
+out = cv2.VideoWriter(
+ 'birds_concat.mp4',
+ cv2.VideoWriter_fourcc(*'mp4v'),
+ fps,
+ (width, height)
+)
+```
+
+### 格式不对
+
+```python
+width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
+height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
+fps = cap.get(cv2.CAP_PROP_FPS)
+out = cv2.VideoWriter(
+ 'birds_concat.mp4',
+ cv2.VideoWriter_fourcc(*'MP4V'),
+ fps,
+ (width, height)
+)
+```
+
+### 宽度和长度类型不对
+
+```python
+width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
+height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
+fps = cap.get(cv2.CAP_PROP_FPS)
+out = cv2.VideoWriter(
+ 'birds_concat.mp4',
+ cv2.VideoWriter_fourcc(*'MP4V'),
+ fps,
+ (width, height)
+)
+```
diff --git "a/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.py" "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.py"
new file mode 100644
index 0000000000000000000000000000000000000000..655b4476ac03196fd4248f4d4406f3cc013f60e1
--- /dev/null
+++ "b/data/1.OpenCV\345\210\235\351\230\266/1.OpenCV\345\237\272\347\241\200/4.IO\344\270\216GUI/video_read_write.py"
@@ -0,0 +1,38 @@
+import numpy as np
+import cv2
+
+
+if __name__ == '__main__':
+ cap = cv2.VideoCapture('birds.mp4')
+
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
+ fps = cap.get(cv2.CAP_PROP_FPS)
+ out = cv2.VideoWriter(
+ 'birds_concat.mp4',
+ cv2.VideoWriter_fourcc(*'mp4v'),
+ fps,
+ (width*2, height)
+ )
+
+ while(cap.isOpened()):
+
+ ret, bird_frame = cap.read()
+ if bird_frame is None:
+ break
+
+ bird_flip_frame = cv2.flip(bird_frame, 0)
+ bird_concat_frame = np.concatenate(
+ (bird_frame, bird_flip_frame),
+ axis=1
+ )
+
+ cv2.imshow('bird_concat_frame', bird_concat_frame)
+ out.write(bird_concat_frame)
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+ out.release()
+ cap.release()
+
+ cv2.destroyAllWindows()