画像圧縮は、視覚的な品質を維持しながら、画像をより効率的に保存および送信できるようにする、コンピュータ ビジョンにおける重要なテクノロジです。理想的には、小さなファイルを最高の品質で提供したいと考えています。ただし、トレードオフを考慮して、どちらがより重要かを決定する必要があります。
このチュートリアルでは、理論と実践的なアプリケーションをカバーしながら、OpenCV を使用した画像圧縮について説明します。最後には、コンピューター ビジョン プロジェクト (またはその他のプロジェクト) で写真を適切に圧縮する方法を理解できるようになります。
画像圧縮とは、許容可能なレベルの視覚的な品質を維持しながら、画像のファイル サイズを削減することです。圧縮には主に 2 つのタイプがあります:
よく聞くように「ディスク容量が安い」のであれば、なぜ画像を圧縮する必要があるのでしょうか?小規模な規模では画像圧縮はあまり重要ではありませんが、大規模な規模では非常に重要になります。
たとえば、ハード ドライブにいくつかの画像がある場合、それらを圧縮して数メガバイトのデータを保存できます。ハードドライブがテラバイト単位で測定される場合、これは大きな影響はありません。しかし、ハード ドライブに 100,000 枚の画像がある場合はどうなるでしょうか?いくつかの基本的な圧縮により、リアルタイムの時間と費用が節約されます。パフォーマンスの観点から見ても、それは同じです。 Web サイトに大量の画像があり、1 日に 10,000 人が Web サイトにアクセスする場合、圧縮が重要になります。
そうする理由は次のとおりです:
画像圧縮技術は 2 種類の冗長性を利用します:
空間冗長性は、ほとんどの自然画像では隣接するピクセルが同様の値を持つ傾向があるという事実を利用します。これにより、スムーズなトランジションが作成されます。ある領域から別の領域への自然な流れがあるため、多くの写真は「本物のように見えます」。隣接するピクセルの値が大きく異なる場合、「ノイズの多い」画像が得られます。ピクセルを単一の色にグループ化し、画像を小さくすることで、トランジションの「滑らかさ」を低下させるためにピクセルが変更されました。
一方、色の冗長性は、画像内の隣接する領域がどのように類似した色を共有することが多いかに焦点を当てています。青い空や緑の野原を思い浮かべてください。画像の大部分が非常に似た色の値を持っている可能性があります。グループ化して単色にしてスペースを節約することもできます。
OpenCV は、これらのアイデアに取り組むための強力なツールを提供します。たとえば、OpenCV の cv2.inpaint() 関数は、空間的冗長性を使用して、近くのピクセルからの情報を使用して画像の欠落または破損した領域を埋めます。 OpenCV では、開発者は cv2.cvtColor() を使用して、色の冗長性に関して複数の色空間間で画像を変換できます。特定の種類の画像をエンコードする場合、一部の色空間が他の色空間より効果的であるため、これは多くの圧縮技術の前処理ステップとしてある程度役立ちます。
この理論の一部を今からテストしてみます。遊んでみましょう。
OpenCV の Python バインディングを使用して画像を圧縮する方法を見てみましょう。このコードを書き出すかコピーします:
ここからソース コードも入手できます
import cv2 import numpy as np def compress_image(image_path, quality=90): # Read the image img = cv2.imread(image_path) # Encode the image with JPEG compression encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality] _, encoded_img = cv2.imencode('.jpg', img, encode_param) # Decode the compressed image decoded_img = cv2.imdecode(encoded_img, cv2.IMREAD_COLOR) return decoded_img # Example usage original_img = cv2.imread('original_image.jpg') compressed_img = compress_image('original_image.jpg', quality=50) # Display results cv2.imshow('Original', original_img) cv2.imshow('Compressed', compressed_img) cv2.waitKey(0) cv2.destroyAllWindows() # Calculate compression ratio original_size = original_img.nbytes compressed_size = compressed_img.nbytes compression_ratio = original_size / compressed_size print(f"Compression ratio: {compression_ratio:.2f}")
この例には、2 つのパラメータを取る compress_image 関数が含まれています:
次に、元の画像をoriginal_imgに読み込みます。次に、同じ画像を 50% 圧縮して、新しいインスタンス (compressed_image) にロードします。
次に、元の画像と圧縮された画像を並べて表示します。
次に圧縮率を計算して表示します。
この例では、OpenCV で JPEG 圧縮を使用して画像を圧縮する方法を示します。品質パラメータは、ファイル サイズと画質のトレードオフを制御します。
実行しましょう:
最初に画像を見てみると、ほとんど違いがわかりません。ただし、ズームインすると品質の違いがわかります:
そしてウィンドウを閉じてファイルを見ると、ファイルのサイズが大幅に縮小していることがわかります:
また、さらに下げると、品質を 10% に変更できます
compressed_img = compress_image('sampleimage.jpg', quality=10)
そして結果はさらに劇的です:
ファイル サイズの結果もさらに大幅に大きくなります:
これらのパラメータを非常に簡単に調整して、品質とファイル サイズの間で望ましいバランスを実現できます。
圧縮の影響を評価するには、次のような指標を使用できます:
平均二乗誤差 (MSE) は、2 つの画像が互いにどの程度異なっているかを測定します。イメージを圧縮する場合、MSE は、圧縮されたイメージが元のイメージと比較してどの程度変更されたかを判断するのに役立ちます。
これは、2 つの画像内の対応するピクセルの色の違いをサンプリングし、それらの差を 2 乗して平均することによって行われます。結果は 1 つの数値になります。MSE が低いほど、圧縮されたイメージがオリジナルに近いことを意味します。比較すると、MSE が高いということは、品質の低下がより顕著であることを意味します。
これを測定するための Python コードをいくつか示します:
def calculate_mse(img1, img2): return np.mean((img1 - img2) ** 2) mse = calculate_mse(original_img, compressed_img) print(f"Mean Squared Error: {mse:.2f}")
デモ画像の圧縮は次のようになります:
ピーク信号対雑音比 (PSNR) は、圧縮後に画像の品質がどの程度劣化したかを示す尺度です。これは多くの場合、目で見ることができますが、設定された値が割り当てられます。元の画像と圧縮された画像を比較し、その差を比率で表します。
PSNR 値が高いほど、圧縮された画像の品質がオリジナルに近く、品質の低下が少ないことを意味します。 PSNR が低いほど、劣化が目立ちやすくなります。 PSNR は MSE と併用されることが多く、PSNR は高いほど優れているという解釈しやすいスケールを提供します。
これを測定する Python コードを次に示します:
def calculate_psnr(img1, img2): mse = calculate_mse(img1, img2) if mse == 0: return float('inf') max_pixel = 255.0 return 20 * np.log10(max_pixel / np.sqrt(mse)) psnr = calculate_psnr(original_img, compressed_img) print(f"PSNR: {psnr:.2f} dB")
デモ画像の圧縮は次のようになります:
圧縮後の画像を「目視」して品質に問題がないことを判断します。ただし、大規模な場合は、スクリプトでこれを実行する方が、標準を設定し、画像がそれに従うようにするためのはるかに簡単な方法です。
他のテクニックをいくつか見てみましょう:
より高度な圧縮のために、OpenCV はさまざまなアルゴリズムをサポートしています:
画像を PNG 形式に変換すると、多くの利点があります。次のコード行を使用すると、ニーズに応じて圧縮を 0 から 9 まで設定できます。 0 は圧縮がまったくないことを意味し、9 は最大です。 PNG は「ロスレス」形式であるため、最大圧縮しても画像はそのまま残ることに注意してください。大きなトレードオフは、ファイル サイズと圧縮時間です。
OpenCV で PNG 圧縮を使用するコードは次のとおりです:
cv2.imwrite('compressed.png', img, [cv2.IMWRITE_PNG_COMPRESSION, 9])
結果は次のとおりです:
注: この場合のように、PNG ファイルのサイズが実際には大きいことに気づく場合があります。画像の内容により異なります。
画像を .webp 形式に変換することもできます。これは、人気が高まっている新しい圧縮方法です。私は何年もブログの画像にこの圧縮を使用してきました。
次のコードでは、画像を webp ファイルに書き込み、圧縮レベルを 0 から 100 まで設定できます。0 であるため、PNG のスケールとは逆になります。これは、代わりに quality を設定しているためです。 圧縮。 0 に設定すると、ファイル サイズが小さくなり、損失が大きくなり、品質が最低となるため、この小さな違いは重要です。 100 が最高品質です。これは、最高の画質を持つ大きなファイルを意味します。
これを実現するための Python コードは次のとおりです:
cv2.imwrite('compressed.webp', img, [cv2.IMWRITE_WEBP_QUALITY, 80])
結果は次のとおりです:
これら 2 つの手法は、大量のデータを圧縮するのに最適です。スクリプトを作成して、数千または数十万の画像を自動的に圧縮できます。
画像圧縮は素晴らしいです。これは、特にスペースを節約したり処理速度を向上させたりする場合に、さまざまな点でコンピューター ビジョン タスクに不可欠です。ハード ドライブの容量を減らしたり、帯域幅を節約したい場合には、コンピューター ビジョン以外にも多くの使用例があります。画像圧縮は非常に役立ちます。
その背後にある理論を理解し、それを適用することで、プロジェクトで強力な効果を得ることができます。
効果的な圧縮の鍵は、ファイル サイズの削減とアプリケーションにとって許容可能なビジュアル品質の維持の間のスイート スポットを見つけることであることを覚えておいてください。
お読みいただきありがとうございます。コメントやご質問がございましたら、お気軽にお問い合わせください。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3