記事の最後にある公式アカウントに返信して
深圳杯B题
、全内容を入手してください。
この記事の本文、数式、コードはすべて部分的に表示されています。
記事ディレクトリ
1. トピック
著作権とも呼ばれる著作権には、出版、著作権、改変、作品の完全性の保護、複製、頒布、レンタル、展示、公演、映写、放送、情報ネットワークの普及、映画化、翻案の権利、翻訳の権利が含まれます。著作権者が享受すべき権利、編集権、その他の権利。
今日、コンピュータ ネットワークの普及により、ますます多くの電子リソースがネットワークを介して迅速に転送されるようになります。同時に、電子リソースの著作権をどのように保護するかが徐々に重要になってきています。この問題は、情報セキュリティの分野でも重要な問題の 1 つです。この問題を解決するキーテクノロジーの一つが電子透かし(電子透かし)技術です。しかし、可視透かし(可視透かし)は、電子画像の著作権保護に適用される場合、画像自体の構造を破壊することが多く、また、埋め込まれた情報が目に見えるため、識別され除去されやすい。したがって、ステガノグラフィーは広く注目され、使用されています。
ステガノグラフィーは一般に、実際に存在する情報を隠す方法に特化した情報隠蔽の重要な分野とみなされています。ステガノグラフィーの歴史は古く、紀元前数百年に遡るケースもあります。コンピュータとインターネット技術の急速な発展に伴い、現代のステガノグラフィー技術の研究は 1990 年代に始まったと考えられています。ステガノグラフィー技術は、情報担体に特定の情報を埋め込むことができ、検出されにくいため、著作権保護、データ追加などの分野で広く使用できます。
- 質問 1: 添付資料 1 の画像 P について、画像 SP が人間の視覚における元の画像 P にできるだけ近くなるように、埋め込み情報「深セン杯数学モデリング チャレンジ」を含む画像 SP を生成するための数学的モデルを確立してください。画像 SP を生成するアルゴリズムを設計および実装し、生成された SP ソース コードと結果の画像 SP をエントリの付録 A に配置し、画像 SP から著作権情報を抽出するために使用したソース コードをエントリの付録 B に配置します。 。
- 質問 2 質問 1 のモデルとアルゴリズムを使用して、「中華人民共和国著作権法」(修正第 3 条) [1] のすべてのテキスト情報を添付 1 の画像に埋め込むことは可能ですか? そうでない場合、最大でどのくらい埋め込むことができますか?
- 質問 3 電子画像の送信の過程で、画像は圧縮されたり、異なる画像形式で保存されたり、拡大縮小、回転、その他の幾何学的変形が行われる場合があります。この時点で、質問 1 のアルゴリズムはまだ使用可能ですか? そうでない場合、どのように改善できますか?
- 質問 4 他の電子画像の著作権を保護したい場合、質問 1 のアルゴリズムを使用する際に注意すべき点は何ですか? 注意事項を 3 つまで挙げ、その理由も説明してください。
参考文献
[1] http://www.gov.cn/guoqing/2021-10/29/content_5647633.htm
2. アイデアと解決策
2.1 質問 1
2.11 LSB 法のテスト
これは、lsb メソッドを使用して実現できます。
LSB ステガノグラフィーは、画像の最下位ビット (Least Significant Bit、LSB) を使用して情報を隠す技術です。画像の各ピクセルは 3 色 (赤、緑、青) で構成され、各色は 8 ビット、つまり 1 バイトを占めます。LSB ステガノグラフィーは、隠蔽する情報の 2 進ビットを画像の各ピクセルの最下位ビットに置き換えて、情報の埋め込みを実現します。最下位ビットは画質にほとんど影響を与えないため、人間の目で違いを検出するのが難しく、この方法の方が隠蔽性に優れています。
stegano ライブラリを呼び出して、lsb メソッドがどのように動作するかをテストして確認できます。
- ライブラリでは入力画像が PNG 形式である必要があるため、最初に元の画像を PNG 形式に変換します。
- このライブラリは中国語を十分にサポートしていないため (UTF-8 がすぐに使用されます)、この記事ではまず埋め込む情報を Base64 エンコードしてから画像に埋め込みます。
- 画像内の情報を解析する場合、操作は逆になります。
...
# 嵌入信息到图片中
def embed_info(image_path, message, output_path):
# 把中文转换为base64编码
message = base64.b64encode(message.encode('utf-8')).decode('ascii')
secret = lsb.hide(image_path, message)
secret.save(output_path)
# 从图片中提取信息
def extract_info(image_path):
secret_message = lsb.reveal(image_path)
# 把base64编码还原为中文
secret_message = base64.b64decode(secret_message.encode('ascii')).decode('utf-8')
return secret_message
...
操作結果:
元画像:
情報埋め込み後の画像:
2 つの画像のサイズは同じで、埋め込まれている情報量は画像のサイズに比べて 0.02% (24バイト/1228800バイト)。
2 つの画像間の差異を比較するには、平均二乗誤差 (MSE) や構造類似性指数 (SSIM) など、多くの方法や指標があります。これらの手法は、2 つの写真のピクセル値に基づいて、2 つの写真間の差異の度合いを計算し、差異が小さいほど、写真は類似していると判断します。
コード:
...
# 定义MSE函数
def mse(imageA, imageB):
# 计算两张图片之间的均方误差
# 两张图片必须有相同的尺寸
err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2)
err /= float(imageA.shape[0] * imageA.shape[1])
# 返回MSE值,越小越相似
return err
...
結果:
「Shenzhen Cup Mathematical Modeling Challenge」を埋め込んだ後、2 つの写真の差は非常に小さいことがわかります。
タイトルの第 2 段落も画像に埋め込むと、その差はもう少し大きくなります。
2.12 LSB 法のモデリング
上記の方法は、lsb 方法を使用して画像に情報を埋め込むことが可能であることを示しています。したがって、lsb 法の数学的モデルを確立し、lsb 法の原理に従ってプログラムを作成します。
タイトルにある画像は jpg 形式であるため、このセクションのモデルとコードは jpg 形式の元の画像の入力をサポートしています。
ただし、元の jpg 画像に情報を埋め込んだ後は、jpg 形式で保存することはできません。jpg では詳細がまったく失われないことを保証できず、埋め込まれた情報が損なわれるため、出力は損失なく PNG 形式で保存する必要があります。 、画像の各ピクセルの rgb 値を完全に記録できるようにします。
数学的モデル:
これら 2 つの関数の基本原理は、画像の最下位ビット (LSB) を使用して情報を埋め込み、抽出することです。この方法は、画像ピクセルの最下位ビットを変更することで情報を埋め込む単純なステガノグラフィー手法です。これは、変更が画像に視覚的にほとんどまたはまったく影響を与えず、ほとんど知覚できないためです。
これら 2 つの関数の数学的モデルは次のとおりです。
-
埋め込み情報:
c
メッセージ内の各文字をmessage
8 ビットのバイナリ表現に変換しますb(c)
。次に、画像の各ピクセルを反復処理し(r, g, b)
、各カラー チャネルの最下位ビットを のb(c)
単一ビットに置き換えます。これは次の式で表すことができます。。。。...... 。。。...... 。。。......
このうち
r'
、g'
、b'
は新しいピクセル値、b(c)_i
は のb(c)
ビットi
、mod
はモジュロ演算です。
-
情報の抽出:
画像の各ピクセルを反復処理し
(r, g, b)
、各カラー チャネルの最下位ビットから情報ビットを抽出します。これらの情報ビットは 8 ビットのバイナリ表現に結合され、文字に変換されます。これは次の式で表すことができます。b ( c ) i = rmod 2 b(c)_i = r mod 2b ( c )私は=r mod 2 。 _ _ 。。...... b ( c ) i + 2 = bmod 2 b(c)_{i+2} = b mod 2b ( c )私+2 _=bm o d 2
ここでは のビットでb(c)_i
あり、モジュロ演算です。次に、文字に変換します。b(c)
i
mod
b(c)
c
コード:
# -*- coding: UTF-8 -*-
...
# 嵌入信息到图片中
def embed_info(image_path, message, output_path):
# 把中文转换为base64编码
message = base64.b64encode(message.encode('utf-8')).decode('ascii')
# 把信息转换为二进制位
bits = ''.join(format(ord(x), '08b') for x in message)
info_len = len(bits)
# 打开图片
img = Image.open(image_path)
# 获取图片的宽度和高度
width, height = img.size
# 获取图片的像素数据
pixels = img.load()
# 初始化索引
index = 0
# 遍历每个像素
for x in range(width):
for y in range(height):
# 获取当前像素的RGB值
r, g, b = pixels[x, y]
# 如果还有未嵌入的信息位
if index < info_len:
# 把当前像素的红色分量的最低有效位替换为信息位
r = int(format(r, '08b')[:-1] + bits[index], 2)
# 索引加一
index += 1
# 如果还有未嵌入的信息位
if index < info_len:
...
情報分析検査:
類似性テスト: 平均二乗誤差は使用したライブラリーよりも低く、構造類似性指数はわずかに高く、それでも肉眼では区別できません。
出力画像:
2.2 質問 2
結果はOKです。
理由:
- 元の画像のサイズは です
1280*1896
。この論文の lsb モデルによると、情報の保存に使用できるバイナリ ビットは合計で次のように3 * 1280*1896
なります。 - この論文では、「中華人民共和国著作権法」をサイズ 33KB の txt ファイルとして保存し、モデル内でエンコード変換を行った後、最終的にバイナリ ビットで表現します
349952
。 - 隠される情報のビット数は、画像内に保存できるビット数よりもはるかに小さいです。したがって、添付ファイル 1 の画像にすべてのテキスト情報を埋め込むことができます。
情報埋め込み効果:
前後の写真の違い:
2.3 質問 3
以前の lsb 方法は非常に効果的であり、画像への視覚的な影響は最小限に抑えられます。
ただし、画像が圧縮されたり、別の画像形式で保存されたりすると、拡大縮小、回転、その他の幾何学的変形が行われる場合があります。
従来の情報埋め込みアルゴリズムでは、画像から埋め込まれた情報を抽出できませんでした。(これらの操作によりピクセル値の最下位ビットが変更され、埋め込まれた情報が破壊される可能性があるため)
したがって、アルゴリズムを改善する必要があります。
2.31 方法と手順の概要
「堅牢な」情報隠蔽と呼ばれる手法を使用できます。堅牢な情報隠蔽技術の目標は、画像処理 (圧縮、拡大縮小、回転など) 後に隠蔽された情報を抽出することです。改善するには次のような方法が考えられます。
-
より高度な埋め込み技術を使用します。たとえば、離散コサイン変換 (DCT) や離散ウェーブレット変換 (DWT) などの周波数領域の方法を使用した情報埋め込みです。これらの方法では、LSB のような空間領域で直接情報を隠すのではなく、画像の周波数領域で情報を隠します。このようにして、画像を何らかの処理した後でも、隠された情報を抽出することができます。
-
誤り訂正符号化を使用する: たとえば、ハミング符号やリードソロモン符号などの誤り訂正符号化を使用して、隠された情報を符号化します。これにより、画像処理中に情報の一部が破壊されても、誤り訂正符号化により元の情報を復元することができる。
-
透かし技術の使用: 透かしは、画像内の識別子を隠すことを目的とした特別な情報隠蔽技術であり、画像が処理された後でも識別子を検出できます。透かし技術は通常、堅牢性を向上させるために、いくつかの複雑な埋め込みおよび抽出アルゴリズムを使用します。
-
より強力な機械学習手法を使用します。たとえば、情報の隠蔽と抽出に深層学習を使用します。ディープラーニングは、さまざまな画像処理操作の下で情報の隠蔽と抽出を維持する方法を学習し、それによって堅牢性を向上させることができます。
上記の方法はすべて、情報隠蔽技術の堅牢性を向上させることができますが、堅牢性を向上させると、通常、隠蔽された情報容量がある程度犠牲になることにも注意する必要があります。ただし、著作権を保護するために使用される場合、画像に埋め込む必要がある情報はそれほど多くありません。
この論文では、情報の埋め込みに透かし技術(肉眼では見えない暗透かし)を使用しています。
主な手順は次のとおりです。
- 透かし画像 (正方形) を生成します。
- テキストの長さに基づいて適切な行数を計算します。
- 空のイメージを作成します。
- 画像上にテキストを描画します。
- 画像を保存する。
- …
- 埋め込まれた透かし。
- …
- …
- 右…
- ウォーターマークを抽出します。
- 透かし入りの画像を元の画像にできるだけ近い状態に復元します (回転、トリミング、拡大縮小の場合)。
- …
- …;
- 抽出された透かし画像に対して Arnold 逆変換を実行します (埋め込まれた黒いシルクが Arnold 変換された透かし画像の場合)。
2.32 DCTベースの暗透かし情報埋め込みモデル
2.32 - 1 透かし画像の生成
メインコード:
def create_watermark(text, font_path, font_size=26, opacity=100):
# Calculate lines
n = int(math.sqrt(len(text))) + 1
lines = [text[i:i + n] for i in range(0, len(text), n)]
# Create a blank image with white background
width, height = n * font_size, n * font_size
img = Image.new('RGBA', (width, height), (255, 255, 255))
# Load font
font = ImageFont.truetype(font_path, font_size)
# Initialize ImageDraw
draw = ImageDraw.Draw(img)
# Set text color
text_color = (0, 0, 0, opacity)
# Draw text on image
for i, line in enumerate(lines):
# Calculate the width of the line
text_bbox = draw.textbbox((0, 0), line, font)
line_width = text_bbox[2] - text_bbox[0]
# Calculate the x coordinate to center the line
x = (width - line_width) / 2
draw.text((x, i * font_size), line, font=font, fill=text_color)
# Save the image
img.save('watermark.png', 'PNG')
透かし画像:
2.32 - 2 ウォーターマーク画像アーノルド スクランブル
つまり、透かし情報をスクランブルすることで、情報が均等に分散され、損失の可能性が減り、同時に透かしが他人によって抽出されたり改ざんされたりするのを防ぐことができます。
アーノルド スクランブリングとは、VI アーノルドによって提案された 2 次元画像のスクランブル変換手法である画像暗号化技術です。その基本的な考え方は、画像を 2 次元の整数平面上の関数と見なし、画像暗号化の目的を達成するために、特定の幾何学的変換を通じて元の画像のピクセル位置をスクランブルすることです。
アーノルド スクランブリングの基本式は次のとおりです。
イメージ内の各ピクセル (x, y) について、Arnold スクランブル後、ピクセルの新しい位置 (x', y') は次の式で計算できます。
。。。...... y ' = ( x + 2 y ) mod N y' = (x + 2y) mod Ny』=( ×+2 y ) mod N _ _
このうち、N は画像の幅または高さ (画像が正方形であると仮定)、mod はモジュロ演算です。
Arnold スクランブルの逆の操作、つまり復号化プロセスは、次の式で実行できます。
x = ( 2 x ' − y ' ) mod N x = (2x' - y') mod Nバツ=( 2x _』−y' )mまたはdNy = 。。。そして=...y=...
これら 2 つの式セットは、アーノルド スクランブリングとその逆演算の基本式です。これら 2 つの式により、画像の暗号化と復号化の操作を実現できます。
効果:
コードの一部:
# 对水印图片进行 Arnold 置乱
def arnold_scramble(image, iterations):
# Convert the image to a numpy array
array = np.array(image)
# Get the size of the image
height, width, _ = array.shape
# Create an empty array to hold the scrambled image
scrambled_array = np.empty_like(array)
# Perform the scrambling
for _ in range(iterations):
for y in range(height):
for x in range(width):
scrambled_array[x,y] = array[(x + y) % height, (x + 2 * y) % width]
array = scrambled_array.copy()
# Convert the scrambled array back to an image
scrambled_image = Image.fromarray(np.clip(scrambled_array, 0, 255).astype('uint8'))
return scrambled_image
2.32 - 2 透かし埋め込み
この論文では、DCT ベースの暗透かし技術を使用しています。つまり、透かし画像は、前の LSB の空間領域ではなく、画像の周波数領域に埋め込まれます。
離散コサイン変換 (DCT) の結果では、通常、色や明るさの変化など、画像のほとんどの情報が低周波部分に含まれます。これは、通常、画像のほとんどの領域が同様の色と明るさを持ち、この情報が周波数領域の低周波成分として現れるためです。したがって、DCT 画像の左上隅 (低周波部分) に明るいスポットが多く存在していることがわかります。
逆に、高周波部分には、エッジやテクスチャなどの画像のディテールやテクスチャ情報が含まれます。これらの情報は、周波数領域の高周波成分として現れます。したがって、DCT 画像の右下隅 (高周波部分) にいくつかの明るいスポットがあることがわかりますが、通常は低周波部分よりも少ないです。
中音域はその中間に位置し、色と明るさの変化、および詳細とテクスチャ情報が含まれます。
画像の周波数領域表現では、通常、高周波部分に含まれる情報が最も少なくなります。それの訳は…
それどころか、…
したがって、一般に中間周波数部分が透かしを埋め込むのに最適な場所であると考えられています。中周波数部分には、色と明るさの変化、および詳細とテクスチャ情報が含まれるため、この部分に透かしを埋め込んでも画像の視覚効果が大きく変わる可能性は低いです。同時に、画像の圧縮や低解像度化の際に中間周波部分の情報が破棄されにくいため、この部分に埋め込まれた透かしも保存されやすくなります。
そこで、本記事ではDCT変換後の画像の中間周波部分にウォーターマークを埋め込みます。
もちろん、次は離散コサイン変換 (DCT) の公式です。
1 次元信号の場合、DCT の式は次のとおりです。
長さ N の実数列 x(n) の場合、その DCT 変換は X(k) であり、計算式は次のとおりです。
。。。......
このうち、n=0,1,...,N-1; k=0,1,...,N-1。
2D 画像の場合、2 方向 (x と y) の信号と考えることができるため、各方向に対して個別の DCT を実行できます。すべての信号は、最初に一方向 (行など) に DCT 変換され、次に他の方向 (列など) に DCT 変換されます。このようにして、2 次元 DCT 変換が得られます。
2 次元 DCT の式は次のとおりです。
F ( u , v ) = C ( u ) C ( v ) / 4 ∗ sumx = 0 M − 1 sumy = 0 N − 1 f ( x , y ) cos [ ( 2 x + 1 ) u ∗ pi / 2 M ] cos [ ( 2 y + 1 ) v ∗ pi / 2 N ] F(u,v) = C(u)C(v)/4 * sum_{x=0}^{M-1} sum_{y= 0}^{N-1} f(x,y) cos [ (2x+1)u*pi / 2M ] cos [ (2y+1)v*pi / 2N ]F ( u ,v )=C ( u ) C ( v ) /4∗うーん_ _x = 0M − 1うーん_ _y = 0N − 1f ( x ,y ) cos [( 2 x+1 )あなた∗p i /2 M [ cos ] ( 2 y+1 ) v∗p i /2 N ]
このうち、x と y は画像の座標、M と N は画像の幅と高さ、F(u, v) は周波数領域の値、f(x, y) は周波数領域の値です。時間領域、u と v は周波数です。C(u) と C(v) は正規化係数で、u または v が 0 の場合、C(u) または C(v) は 1/√2、それ以外の場合は 1 になります。
これらの式はすべてコサイン関数に基づいているため、「離散コサイン変換」と呼ばれます。
1 次元信号の場合、逆 DCT の式は次のとおりです。
長さ N の実数シーケンス X(k) の場合、その逆 DCT 変換は x(n) であり、計算式は次のとおりです。
x ( n ) = sumk = 0 N − 1 X ( k ) cos [ ( pi / N ) ( n + 1 / 2 ) k ] 、 n = 0 , 1 , . 。。, N − 1 x(n) = sum_{k=0}^{N-1} X(k) cos [ (pi/N) (n + 1/2) k ], n = 0, 1, .. .、N-1x ( n )=うーん_ _k = 0N − 1X ( k ) cos [ ( pi / N ) ( n+1/2 ) k ] 、n=0 、1 、... 、N−1
このうち、n=0,1,...,N-1; k=0,1,...,N-1。
2D 画像の場合、2 方向 (u と v) の信号と考えることができるため、逆 DCT を各方向に対して個別に実行できます。すべての信号はまず一方向 (行など) に逆 DCT 変換され、次に他の方向 (列など) に逆 DCT 変換されます。このようにして、2 次元逆 DCT 変換が得られます。
2 次元逆 DCT の式は次のとおりです。
。。。......
このうち、x と y は画像の座標、M と N は画像の幅と高さ、F(u, v) は周波数領域の値、f(x, y) は周波数領域の値です。時間領域、u と v は周波数です。C(u) と C(v) は正規化係数で、u または v が 0 の場合、C(u) または C(v) は 1/√2、それ以外の場合は 1 になります。
エフェクトデモ:
alpha=0.1
alpha = 0.9
コードの一部:
# 对原始图像执行离散余弦变换(DCT)
def perform_dct(original_array):
height, width, _ = original_array.shape
dct_blocks = np.empty_like(original_array, dtype=np.float64)
for i in range(0, height, 8):
for j in range(0, width, 8):
dct_blocks[i:i + 8, j:j + 8] = dct(dct(original_array[i:i + 8, j:j + 8], axis=0, norm='ortho'), axis=1,
norm='ortho')
return dct_blocks
# 将水印嵌入到DCT块中
def embed_watermark(dct_blocks, watermark_array, alpha=0.05):
dct_blocks_with_watermark = dct_blocks.copy()
dct_blocks_with_watermark[::8, ::8] += alpha * watermark_array
return dct_blocks_with_watermark
2.32 - 3 ウォーターマーク抽出
最初のケースでは、回転された画像から透かし情報が抽出されます。まず、Canny オペレーターによってエッジ抽出が実現され、次に、ハフ変換を使用して画像の幾何学的形状が検出されます。適切な回転角度は、適切なしきい値を設定し、そのレベルに復元します。最後に、無効な画像フレームを切り取って得られた画像を使用して透かしを抽出することができます。
2 番目のケースでは、切り取られた画像の透かし情報が抽出されます。
3 番目のケースでは、ズームされた画像の場合、... が提供するズーム操作機能を通じて得られた画像から透かしを抽出できます。
透かしを抽出するプロセスでは、まずピクチャを 8×8 ブロックに分割し、次にサブブロックから透かしを抽出する必要があります。前の操作で透かし画像が暗号化およびスクランブルされているため、ここでは逆アーノルド変換が必要で、透かし情報の復号と復元を実現し、最終的に透かし画像を抽出します。
効果:
コードの一部:
def process_images(image_with_watermark_path, original_image_path, alpha=0.05):
# 加载图像
image_with_watermark = load_image(image_with_watermark_path)
original_image = load_image(original_image_path)
# 将图像转换为数组
image_with_watermark_array = image_to_array(image_with_watermark)
original_array = image_to_array(original_image)
# 对图像执行DCT
dct_blocks_with_watermark = perform_dct(image_with_watermark_array)
original_dct_blocks = perform_dct(original_array)
# 提取水印
watermark_array = extract_watermark(dct_blocks_with_watermark, original_dct_blocks, alpha)
# 裁剪和转换图像
watermark_array = clip_and_convert(watermark_array)
# 将数组转换回图像
watermark_image = array_to_image(watermark_array)
return watermark_image
2.4 質問 4
LSB (最下位ビット) は一般的な情報隠蔽技術であり、通常は電子透かしやステガノグラフィーで使用されます。LSBを情報埋め込みに使用する場合は、以下の点に注意する必要があります。
-
適切な埋め込み位置を選択します。LSB は通常、画像に埋め込まれる情報の最下位ビットです。これは、画像への影響が最も少なく、人間の目で検出することが難しいためです。ただし、画像が圧縮または他の形式の処理を受ける可能性がある場合、これらの処理により最下位ビットが変更され、埋め込まれた情報が失われる可能性があります。したがって、画像がこの種の処理を受けることが予想される場合は、より高いビットなど、別の埋め込み位置を選択する必要がある場合があります。
-
埋め込み情報の保護: LSB 埋め込みは情報を隠すことができますが、攻撃者が LSB 埋め込みが使用されたことを知っている場合、情報を抽出または破損しようとする可能性があります。したがって、埋め込まれた情報のセキュリティを確保するには、暗号化またはその他の形式の保護を使用する必要がある場合があります。(例:埋め込む情報を暗号化してから埋め込むなど)
-
過剰な埋め込みを避ける: LSB の埋め込みは画像への影響は少ないですが、埋め込まれている情報が多すぎると、画質が大幅に低下する可能性があります。したがって、情報を隠す必要性と画質を維持する必要性の間のバランスを見つける必要があります。
3. 参考文献
これらのドキュメントでは多くの内容が参照されており、いくつかのメソッドの再現および統合とみなすことができます。論文を書くとき、関連する概念や公式についてこれらのドキュメントを参照できます。(ただし、多くの概念とその公式も示しました)
すべて:
部分プレビュー: