Python画像処理の基本!OpenCV, Pillowで画像の幅・高さを取得する


 

Pythonで画像処理を行う際、画像の**幅(width)高さ(height)**といったサイズ情報を取得することは、処理の計画や画像の表示に不可欠なステップです。特に、NumPyと連携して画像データを扱う場合、その形状からサイズを把握することも重要になります。この記事では、OpenCVとPillow(PIL)という主要な画像処理ライブラリを使って画像の幅と高さを取得する方法について、具体的なサンプルコードを交えながら詳しく解説します。


 

画像サイズ情報の重要性

 

画像の幅と高さは、以下の様な場面で重要な情報となります。

  • 処理の自動化: 画像のサイズに応じてリサイズやクロップのパラメータを調整する。

  • メモリ管理: 大量の画像を処理する際に、メモリ使用量を予測・管理する。

  • 表示の調整: GUIアプリケーションで画像を表示する際に、適切な表示領域を確保する。

  • 機械学習: モデルの入力サイズに合わせて画像データを調整する。


 

1. Pillow (PIL) で画像の幅と高さを取得する

 

Pillowは、Pythonで画像を扱うためのデファクトスタンダードライブラリで、画像の読み込みや保存、基本的な操作に優れています。Pillowで画像を読み込むと、Imageオブジェクトのsize属性から画像の幅と高さを簡単に取得できます。

 

Image.size属性

 

Pillowで開いたImageオブジェクトは、sizeという属性を持っており、(幅, 高さ)のタプル形式で画像のサイズ情報が格納されています。

 

サンプルコード

 

Python
 
from PIL import Image
import numpy as np # NumPyは後述するOpenCVとの連携で重要

# ダミー画像を生成 (Pillowで画像がない場合に備える)
try:
    img_pil = Image.open('dummy_image.jpg')
except FileNotFoundError:
    img_pil = Image.new('RGB', (640, 480), color = 'blue') # 幅640, 高さ480の青い画像
    img_pil.save('dummy_image.jpg')
    img_pil = Image.open('dummy_image.jpg')

# 画像の幅と高さを取得
width_pil, height_pil = img_pil.size

print(f"Pillow (PIL) で取得した幅: {width_pil} px")
print(f"Pillow (PIL) で取得した高さ: {height_pil} px")

 

2. OpenCVで画像の幅と高さを取得する

 

OpenCVは、コンピュータビジョン分野で広く使われる強力なライブラリで、画像解析や機械学習、リアルタイム処理に特化しています。OpenCVで画像を読み込むと、画像データはNumPy配列として扱われ、そのshape属性からサイズ情報を取得します。

 

NumPy配列のshape属性

 

OpenCVが画像を読み込んだ結果はNumPy配列になります。NumPy配列のshape属性は、配列の次元ごとの要素数をタプルで返します。

  • カラー画像: (高さ, 幅, チャンネル数)の順

  • グレースケール画像: (高さ, 幅)の順

そのため、幅と高さを取得する際は、この順序を考慮する必要があります。

 

サンプルコード

 

Python
 
import cv2
import numpy as np # OpenCVはNumPyを内部で利用

# ダミー画像を生成 (OpenCVで画像がない場合に備える)
# Pillowのコードで'dummy_image.jpg'が作成されている前提
try:
    img_cv = cv2.imread('dummy_image.jpg')
    if img_cv is None: # imreadがNoneを返す場合(ファイル破損など)
        raise FileNotFoundError
except FileNotFoundError:
    # NumPyでダミー画像を生成 (赤色の640x480画像)
    dummy_img_np = np.zeros((480, 640, 3), dtype=np.uint8)
    dummy_img_np[:,:,2] = 255 # 赤色チャンネルを最大に
    cv2.imwrite('dummy_image.jpg', dummy_img_np)
    img_cv = cv2.imread('dummy_image.jpg')


print(f"OpenCVで読み込んだNumPy配列の形状: {img_cv.shape}")

# 画像の高さと幅を形状から取得
# (高さ, 幅, チャンネル数) または (高さ, 幅) の順
height_cv, width_cv = img_cv.shape[:2] # スライシングで最初の2つの要素を取得

print(f"OpenCVで取得した幅: {width_cv} px")
print(f"OpenCVで取得した高さ: {height_cv} px")

 

3. NumPy配列から直接画像の幅と高さを取得する

 

PillowやOpenCVで読み込んだ画像は、最終的にNumPy配列として扱われることが多いです。そのため、NumPy配列のshape属性を理解していれば、どのライブラリで読み込んだかに関わらず、幅と高さを取得できます。

 

サンプルコード

 

Python
 
import numpy as np
from PIL import Image # PillowでNumPy配列を生成する例

# Pillowで画像を読み込み、NumPy配列に変換
# dummy_image.jpgが既に存在すると仮定
img_pil = Image.open('dummy_image.jpg')
img_np_from_pil = np.array(img_pil)

# NumPy配列の形状から幅と高さを取得
# カラー画像の場合 (高さ, 幅, チャンネル数)
height_np_pil, width_np_pil = img_np_from_pil.shape[0], img_np_from_pil.shape[1]
print(f"NumPy (Pillow経由) で取得した幅: {width_np_pil} px")
print(f"NumPy (Pillow経由) で取得した高さ: {height_np_pil} px")

# OpenCVで画像を読み込んだNumPy配列の場合も同様
# dummy_image.jpgが既に存在すると仮定
img_cv = cv2.imread('dummy_image.jpg')
height_np_cv, width_np_cv = img_cv.shape[0], img_cv.shape[1]
print(f"NumPy (OpenCV経由) で取得した幅: {width_np_cv} px")
print(f"NumPy (OpenCV経由) で取得した高さ: {height_np_cv} px")

# もしグレースケール画像なら (高さ, 幅)
# 例: グレースケールダミー画像をNumPyで作成
gray_dummy_np = np.zeros((200, 300), dtype=np.uint8) # 高さ200, 幅300
height_gray, width_gray = gray_dummy_np.shape[0], gray_dummy_np.shape[1]
print(f"NumPy (グレースケール) で取得した幅: {width_gray} px")
print(f"NumPy (グレースケール) で取得した高さ: {height_gray} px")

 

まとめ

 

Pythonで画像処理を行う際、画像の幅と高さを取得する方法は、使用するライブラリによって異なりますが、基本的にはシンプルです。

  • Pillow (PIL): Imageオブジェクトの**img.size**属性から(幅, 高さ)のタプルで取得します。

  • OpenCV: cv2.imread()で読み込んだNumPy配列の**img_cv.shape**属性から(高さ, 幅, チャンネル数)の順で取得します(スライシング[:2]が便利)。

  • NumPy: 画像がNumPy配列として存在する場合、その**arr.shape**属性の最初の2つの要素(arr.shape[0]が高さ、arr.shape[1]が幅)が対応します。

これらの方法を理解し、適切に使い分けることで、Pythonでの画像処理ワークフローをスムーズに進めることができるでしょう。画像のサイズ情報を正確に把握し、効率的な画像処理を実現してください!🚀