質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.93%

【画像処理】windowsのエクスプローラでサムネイルを表示するとき、元画像にどんな圧縮をかけているか知りたいです

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 778

ysk_snn

score 18

前提・実現したいこと

単純に興味だけであって、困っているわけではないのですが、
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手法はあまり違いが分かりません。
イメージ説明

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+3

Windowsのサムネイル画像の縮小アルゴリズムについて調べてみましたが、分かりませんでした。

ただ、サムネイル画像は同階層にある隠しファイルthumbs.dbに格納されています。
Thumbs.dbのフォーマット調べて抽出ツール作ったによると、画像は無圧縮で暗号化もされていない状態で格納されているようなので、まずはそれらを抽出します。
抽出はUtility to batch extract images from a thumbs.db thumbnail databaseによるとVinettoでできるようです。
あとは元画像を各種アルゴリズムで縮小した結果と比較すれば、どのアルゴリズムを使っているか見当がつくかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+3

適当に黒地に白と灰色の矩形を書いた画像のサムネイルを表示させて
そのスクリーンショットを撮ってみました.

画像の上側がサムネイルのスクリーンショットを(もちろん補間無しで)拡大したもので,
下側は,適当にペイントで塗りつぶしを行ってみた結果です.

とりあえず,バイキュービックやLanczosのような広い範囲を見た補間では無さそうな気がしますが…はたして?

イメージ説明

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/21 17:35

    縮小倍率から処理を選択的に変えたりとかも考えられるし,
    「手法Aである程度まで縮小して,そこに手法Bを用いて最終サイズに縮小」みたいな合わせ技(?)とかも考えられるか……
    現物から見ていくなら,こんな1例だけではなく,もっといろんなパターンのIN/OUTから推測する必要があるのかも.

    キャンセル

checkベストアンサー

+2

サムネイル表示の際にはどんな処理が行われていて、もし分かればその理由も教えていただけないでしょうか。

Windows はオープンソースでないので、中の人でないと、補完方式になにを使っているかを知るのは難しいかと思います。

最近傍補間以外の上記にあげた補完方式は、どれを使っても人の目で見てわかる違いはほぼないのではないでしょうか。画像処理のりサイズには、速度と品質の観点からバイリニア補間が一般的に使われます。cv2.INTER_AREA、cv2.INTER_LANCZOS は、バイリニア補完に比べて処理時間が大きくかかるので、1フォルダに何千枚の画像を表示するような状況を考慮すると、使われている可能性は低いと思います。サムネイルなので、画質より速度が重要です。

OpenCV - resize で画像をリサイズする方法 - pystyle

バイリニア補完でアスペクト比を固定してリサイズすれば、エクスプローラーに表示されるのと同等の画像は作成できると思います。

import cv2


def scale_box(img, width, height):
    """指定した大きさに収まるように、アスペクト比を固定して、リサイズする。
    """
    h, w = img.shape[:2]
    aspect = w / h
    if width / height >= aspect:
        nh = height
        nw = round(nh * aspect)
    else:
        nw = width
        nh = round(nw / aspect)

    dst = cv2.resize(img, dsize=(nw, nh))

    return dst


img = cv2.imread("sample.jpg")
dst = scale_box(img, 150, 150)
print(f"{img.shape} -> {dst.shape}")

イメージ説明

イメージ説明

追記

thumbs.db は 256x256 に fit するようにアスペクト比を固定してリサイズし、jpeg 形式に圧縮して保存されているようです。

  1. thumbs.db に格納されている画像
  2. 元画像を (256, 256) にアスペクト比を固定してリサイズし、jpeg で圧縮してから再読み込みした画像

の2つを作成し、輝度値の差分の平均をとったところ、たしかに INTER_AREA が一番差分が小さいようですね。

import cv2
import numpy as np
import pandas as pd

img1 = cv2.imread("original.jpg")  # 元画像
img2 = cv2.imread("thumbs.jpg")  # thumbs.db から抽出した画像


def scale_box(img, width, height, interpolation):
    """指定した大きさに収まるように、アスペクト比を固定して、リサイズする。
    """
    h, w = img.shape[:2]
    aspect = w / h
    if width / height >= aspect:
        nh = height
        nw = round(nh * aspect)
    else:
        nw = width
        nh = round(nw / aspect)

    dst = cv2.resize(img, dsize=(nw, nh), interpolation=interpolation)

    img_bytes = cv2.imencode(".jpg", dst)[1]
    dst = cv2.imdecode(img_bytes, cv2.IMREAD_UNCHANGED)

    return dst


interpolations = {
    "cv2.INTER_NEAREST": cv2.INTER_NEAREST,
    "cv2.INTER_LINEAR": cv2.INTER_LINEAR,
    "cv2.INTER_CUBIC": cv2.INTER_CUBIC,
    "cv2.INTER_AREA": cv2.INTER_AREA,
    "cv2.INTER_LANCZOS4": cv2.INTER_LANCZOS4,
}

results = []
for name, interpolation in interpolations.items():
    img3 = scale_box(img1, 256, 256, interpolation)

    diff = np.abs(img3.astype(int) - img2.astype(int)).sum() / img3.size

    results.append(
        {"interpolation": name, "diff": f"{diff:.2f}",}
    )
results = pd.DataFrame(results)
results
      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/22 17:53

    いちおうあれこれ調べてみまして、
    https://koneta.nifty.com/koneta_detail/170220000222_1.htm
    ここを参考に、
    「視覚効果」タブ内で「カスタム」にチェックを入れ、「アイコンの代わりに縮小版を表示する」のチェックが入っていることを確認して、
    フォルダを開いて「表示」→「オプション」と進み、「フォルダーオプション」内の表示タブで、「隠しファイル、隠しフォルダー、および隠しドライブを表示する」にチェックをいれてあることを確認しております。

    https://www.qam-web.com/?p=12022
    またここを参考に、
    「コントロールパネル」を開いて→「システムとセキュリティ」→「システム」と進み、左メニューから「システムの詳細設定」を選択。
    さらに、「詳細設定」を選択し、「パフォーマンス」項目中の「設定」ボタンをクリック、チェックボックスがたくさん出てくるので、「アイコンの代わりに縮小版を表示する」のチェックが入っていることを確認してもみました。

    https://moondoldo.com/wordpress/?p=461
    ここを参考に、
    非表示のthumbs.dbファイルで縮小表示のキャッシュを無効にする]が[未構成]になっていることも確認しました。

    おそらくはthumbs.dbを作成する設定になっていて、それを表示するようにしているのですが、表示されない状況です。

    もともとの質問からずれてしまって本当に申し訳ございません...
    また、これから少しの間PCをいじれなくなるのでこちらからの回答が遅くなってしまうと思います...

    キャンセル

  • 2020/07/22 18:03 編集

    というか自分も今確認したところ、新しいフォルダ作ってそこに画像入れてみたら、thumbs.db が作られないですね。検証した際に使った画像があるディレクトリは win7 時代からあるものなので、そこにあった thumbs.db がいつ作られたのかわからないです。
    なんかのタイミングで作られるか、いつの間にか thumb.db が廃止になったのかはわかりません。
    質問とは別問題だと思うので、一旦クローズして新しく質問を立てたほうがよいのではないでしょうか。

    キャンセル

  • 2020/07/29 09:55

    確かにそうですね、、、
    自分で試してみたくもあったのですが、
    数値で比較して差異がきちんと分かった点にはすっきりしました!
    ありがとうございます!

    キャンセル

+1

まずバイキュービック(やLanczos)っぽくはないです。
これらは急峻なエッジがあると周辺でオーバーシュートが見られます。
しかしWindowsのサムネイルはこれがなく、元画像に含まれる色とその中間色しか見られません。

また、バイリニアっぽくもないです。
バイリニアでは極端に縮小すると、元画像のごく一部のピクセルしか出力に影響を与えないため、細い線は途切れます。
Windowsのサムネイルにはこれがありません。
(下図右は1万px程度の画像を縮小したものです)

平均画素法はオーバーシュートを起こさず元画像のすべての画素が出力に影響しますので、確かに観測によく合いますね。
バイキュービックとバイリニアとWindowsのサムネイル
なお縮小はClip Studio Paintで行いました。
最初はGIMPで試したのですが、「キュービック」ではオーバーシュートが出ず「線形」では不思議な乱れ方をして、どうも単純なバイリニアやバイキュービックとは異なるアルゴリズムを使っているようです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/27 11:25

    バイキュービック、バイリニアではなさそうという理由がすごく分かりやすいです!
    画像の特徴や縮小率によって手法をミックスしているかもしれませんが、

    >最初はGIMPで試したのですが...
    同じ手法名でもアプリやライブラリによって処理内容が違うこともあるのですかね...
    これもまた勉強になりました...!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • 【画像処理】windowsのエクスプローラでサムネイルを表示するとき、元画像にどんな圧縮をかけているか知りたいです