あることをやるために、縦・横向きの写真をまとめてリサイズするPythonを組みました。
OpenCVの勉強になったので、スクリプトの一部を抜粋し「アスペクト比を固定したサイズ方法」をまとめます。
動作環境
- macOS Mojave v10.14.5
- Python 3.7.3
- opencv-python 4.1.0.25(pipでインストール)
リサイズ仕様
- 長辺に対してリサイズ(縮小)するサイズを指定する
- アスペクト比を維持しながら短辺を合わせる
- 正方形の画像には未対応
ソースコード
import math
import cv2
def create_resize_photo(long_side_size):
# 画像の読み込み
img = cv2.imread('sample.jpg')
# 画像の Height & width を取得
img_height, img_width = img.shape[:2]
# 画像の向きを確認
if img_height < img_width: # 横向き
# 縮小率を計算
scale = img_width / long_side_size
# リサイズするサイズ(横, 縦)を設定
size = (long_side_size, math.ceil(img_height / scale))
else: # 縦向き
scale = img_height / long_side_size
size = (math.ceil(img_width / scale), long_side_size)
# 画像をリサイズ(縮小、バイキュービック補間)
cubic_img = cv2.resize(img, size, interpolation=cv2.INTER_CUBIC)
# 画像を保存(圧縮品質80)
cv2.imwrite('dist_sample.jpg', cubic_img, [
int(cv2.IMWRITE_JPEG_QUALITY), 80])
if __name__ == '__main__':
create_resize_photo(1000)
ざっくりこんな風に組みました。
- 画像を読み込む
- 高さ・幅のサイズを取得する
- 高さと幅を比較する
- 縮小率を算出する(scale)
- 縮小サイズを設定する
- リサイズする(以下の補間方法がある)
- cv2.INTER_NEAREST: 最近傍補間法
- cv2.INTER_LINEAR: バイリニア補間
- cv2.INTER_CUBIC: バイキュービック補間
- cv2.INTER_AREA: ピクセル領域の関係を利用したリサンプリング
- cv2.INTER_LANCZOS4: Lanczos法補間
- 保存する
- cv2.IMWRITE_JPEG_QUALITYが高いほど高品質(1〜100)
難しいことはしてなくて、ひとつひとつ順にやっていけば望むものが得られます。コードに書いたように長辺に1000pxを指定するとこうなりました。

4928pxの長辺を1000pxにリサイズ(約1/5)して、短辺が3264px → 663pxへとリサイズ(約1/5)されました。
所感
今回つかった画像では、リサイズすると細部の画質が落ちるように感じました。Photoshopでリサイズしたときと比べてザラザラしているのです。
補間方法を変えても大きく改善されるようには見えないんですよね。画像次第なのかなぁ、う〜ん。
もっと上手いことできるのかと思いますが、これ以上は追求しません。ひとまずリサイズの大きな流れは理解できました。
ってことでよしとします!
