前提・実現したいこと
単純に興味だけであって、困っているわけではないのですが、
windowsのエクスプローラで画像のサムネイルを表示するとき、
いつも違和感なくサイズだけ変わっていてすごいなと思いました。(処理も早い)
opencvではcv2.resizeのinterpolationとして、
- cv2.INTER_NEAREST 最近傍補間
- cv2.INTER_LINEAR バイリニア補間(デフォルト)
- cv2.INTER_AREA 平均画素法
- cv2.INTER_CUBIC 4×4 の近傍領域を利用するバイキュービック補間
- cv2.INTER_LANCZOS4 8×8 の近傍領域を利用する Lanczos法の補間
がありますが、
cv2.INTER_AREAにかなり近いのではないかと思っています。
画像処理に詳しい方がいたら、サムネイル表示の際にはどんな処理が行われていて、
もし分かればその理由も教えていただけないでしょうか。
よろしくお願いいたします。
試したこと
ここに問題に対して試したことを記載してください。
666×666 個の半径5の円が並んだ水玉模様画像に対して、上記の手法で圧縮をかけて、
100×100 pixelの画像にしたところ、やはり見た目的にはcv2.INTER_AREAが一番似ていて、
その他の3手法はあまり違いが分かりません。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
投稿2020/07/21 06:34
編集2020/07/21 06:35総合スコア11996
0
Windowsのサムネイル画像の縮小アルゴリズムについて調べてみましたが、分かりませんでした。
ただ、サムネイル画像は同階層にある隠しファイルthumbs.db
に格納されています。
Thumbs.dbのフォーマット調べて抽出ツール作ったによると、画像は無圧縮で暗号化もされていない
状態で格納されているようなので、まずはそれらを抽出します。
抽出はUtility to batch extract images from a thumbs.db thumbnail databaseによるとVinettoでできるようです。
あとは元画像を各種アルゴリズムで縮小した結果と比較すれば、どのアルゴリズムを使っているか見当がつくかと思います。
投稿2020/07/21 05:51
総合スコア38341
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
サムネイル表示の際にはどんな処理が行われていて、もし分かればその理由も教えていただけないでしょうか。
Windows はオープンソースでないので、中の人でないと、補完方式になにを使っているかを知るのは難しいかと思います。
最近傍補間以外の上記にあげた補完方式は、どれを使っても人の目で見てわかる違いはほぼないのではないでしょうか。画像処理のりサイズには、速度と品質の観点からバイリニア補間が一般的に使われます。cv2.INTER_AREA、cv2.INTER_LANCZOS は、バイリニア補完に比べて処理時間が大きくかかるので、1フォルダに何千枚の画像を表示するような状況を考慮すると、使われている可能性は低いと思います。サムネイルなので、画質より速度が重要です。
OpenCV - resize で画像をリサイズする方法 - pystyle
バイリニア補完でアスペクト比を固定してリサイズすれば、エクスプローラーに表示されるのと同等の画像は作成できると思います。
python
1import cv2 2 3 4def scale_box(img, width, height): 5 """指定した大きさに収まるように、アスペクト比を固定して、リサイズする。 6 """ 7 h, w = img.shape[:2] 8 aspect = w / h 9 if width / height >= aspect: 10 nh = height 11 nw = round(nh * aspect) 12 else: 13 nw = width 14 nh = round(nw / aspect) 15 16 dst = cv2.resize(img, dsize=(nw, nh)) 17 18 return dst 19 20 21img = cv2.imread("sample.jpg") 22dst = scale_box(img, 150, 150) 23print(f"{img.shape} -> {dst.shape}")
追記
thumbs.db は 256x256 に fit するようにアスペクト比を固定してリサイズし、jpeg 形式に圧縮して保存されているようです。
- thumbs.db に格納されている画像
- 元画像を (256, 256) にアスペクト比を固定してリサイズし、jpeg で圧縮してから再読み込みした画像
の2つを作成し、輝度値の差分の平均をとったところ、たしかに INTER_AREA が一番差分が小さいようですね。
python
1import cv2 2import numpy as np 3import pandas as pd 4 5img1 = cv2.imread("original.jpg") # 元画像 6img2 = cv2.imread("thumbs.jpg") # thumbs.db から抽出した画像 7 8 9def scale_box(img, width, height, interpolation): 10 """指定した大きさに収まるように、アスペクト比を固定して、リサイズする。 11 """ 12 h, w = img.shape[:2] 13 aspect = w / h 14 if width / height >= aspect: 15 nh = height 16 nw = round(nh * aspect) 17 else: 18 nw = width 19 nh = round(nw / aspect) 20 21 dst = cv2.resize(img, dsize=(nw, nh), interpolation=interpolation) 22 23 img_bytes = cv2.imencode(".jpg", dst)[1] 24 dst = cv2.imdecode(img_bytes, cv2.IMREAD_UNCHANGED) 25 26 return dst 27 28 29interpolations = { 30 "cv2.INTER_NEAREST": cv2.INTER_NEAREST, 31 "cv2.INTER_LINEAR": cv2.INTER_LINEAR, 32 "cv2.INTER_CUBIC": cv2.INTER_CUBIC, 33 "cv2.INTER_AREA": cv2.INTER_AREA, 34 "cv2.INTER_LANCZOS4": cv2.INTER_LANCZOS4, 35} 36 37results = [] 38for name, interpolation in interpolations.items(): 39 img3 = scale_box(img1, 256, 256, interpolation) 40 41 diff = np.abs(img3.astype(int) - img2.astype(int)).sum() / img3.size 42 43 results.append( 44 {"interpolation": name, "diff": f"{diff:.2f}",} 45 ) 46results = pd.DataFrame(results) 47results
interpolation | diff | |
---|---|---|
0 | cv2.INTER_NEAREST | 8.84 |
1 | cv2.INTER_LINEAR | 6.05 |
2 | cv2.INTER_CUBIC | 6.67 |
3 | cv2.INTER_AREA | 3.51 |
4 | cv2.INTER_LANCZOS4 | 6.71 |
投稿2020/07/21 05:49
編集2020/07/21 14:52総合スコア21956
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/21 06:13 編集
2020/07/21 07:36
2020/07/21 08:08
2020/07/21 08:22
2020/07/21 14:44
2020/07/22 03:01
2020/07/22 03:16 編集
2020/07/22 04:19
2020/07/22 05:43
2020/07/22 08:53
2020/07/22 09:03 編集
2020/07/29 00:55
0
まずバイキュービック(やLanczos)っぽくはないです。
これらは急峻なエッジがあると周辺でオーバーシュートが見られます。
しかしWindowsのサムネイルはこれがなく、元画像に含まれる色とその中間色しか見られません。
また、バイリニアっぽくもないです。
バイリニアでは極端に縮小すると、元画像のごく一部のピクセルしか出力に影響を与えないため、細い線は途切れます。
Windowsのサムネイルにはこれがありません。
(下図右は1万px程度の画像を縮小したものです)
平均画素法はオーバーシュートを起こさず元画像のすべての画素が出力に影響しますので、確かに観測によく合いますね。
なお縮小はClip Studio Paintで行いました。
最初はGIMPで試したのですが、「キュービック」ではオーバーシュートが出ず「線形」では不思議な乱れ方をして、どうも単純なバイリニアやバイキュービックとは異なるアルゴリズムを使っているようです。
投稿2020/07/22 18:39
総合スコア3047
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/21 08:35