回答編集履歴

1

d

2020/01/27 08:37

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -7,3 +7,95 @@
7
7
 
8
8
 
9
9
  [ヒストグラムが与えられたデータから,中央値を求める方法|数学|苦手解決Q&A|進研ゼミ高校講座|ベネッセコーポレーション](https://kou.benesse.co.jp/nigate/math/a13m0401.html)
10
+
11
+
12
+
13
+ ## 追記
14
+
15
+
16
+
17
+ 最初に書いたヒストグラムの案もそのサイズだと厳しいので、「ブロックごとに中央値を直接計算する」または「ブロックごとにヒストグラムを計算して、中央値をあとから計算する (枚数が256枚以上ならこちらのが省メモリ)」になるかと思います。
18
+
19
+
20
+
21
+ ## コード
22
+
23
+
24
+
25
+ OpenCV のサンプル動画 [vtest.avi](https://github.com/opencv/opencv/raw/master/samples/data/vtest.avi) をフレームごとに切り出して保存した画像で試しました。
26
+
27
+
28
+
29
+ ```python
30
+
31
+ from pathlib import Path
32
+
33
+
34
+
35
+ import cv2
36
+
37
+ import matplotlib.pyplot as plt
38
+
39
+ import numpy as np
40
+
41
+
42
+
43
+ # 画像のパス一覧を取得する。
44
+
45
+ input_dir = Path("input") # 画像があるディレクトリ
46
+
47
+ img_paths = list(input_dir.glob("*.png"))
48
+
49
+
50
+
51
+ # 1枚だけ読み込み画像の幅、高さを取得する。
52
+
53
+ img = cv2.imread(str(img_paths[0]))
54
+
55
+ h, w = img.shape[:2]
56
+
57
+
58
+
59
+
60
+
61
+ median_img = np.empty_like(img)
62
+
63
+
64
+
65
+ stride_y, stride_x = 300, 300 # ブロックの大きさ
66
+
67
+ for y in range(0, h, stride_y):
68
+
69
+ for x in range(0, w, stride_x):
70
+
71
+ # ブロックごとに中央値を計算する。
72
+
73
+ values = []
74
+
75
+ for path in img_paths:
76
+
77
+ img = cv2.imread(str(path))
78
+
79
+ values.append(img[y : y + stride_y, x : x + stride_x])
80
+
81
+ median = np.median(values, axis=0).astype(np.uint8)
82
+
83
+ median_img[y : y + stride_y, x : x + stride_x] = median
84
+
85
+
86
+
87
+ # 結果を可視化する。
88
+
89
+ fig, ax = plt.subplots()
90
+
91
+ ax.imshow(median_img[..., ::-1])
92
+
93
+
94
+
95
+ plt.show()
96
+
97
+ ```
98
+
99
+
100
+
101
+ ![イメージ説明](5369190f3da4b70921e6eb4324a94e28.png)