傾いた画像を自動で水平にする
傾いたお札が写った写真を、お札が水平になるように自動で回転します。
ライブラリopencvのcv2.findContours()メソッドの領域検出機能によりお札の領域を検出、cv2.minAreaRect()メソッドにより回転外接矩形を求め、戻り値の回転角を使って、お札が水平になるように画像全体を回転します。
関連記事
環境
準備
5000円札が傾いて写っている写真を用意し、jupyter notebookファイル(***.ipynb)と同じディレクトリにファイル名'5000.jpg'で保存しました。
コード
cv2.findContours()メソッドにより多数の領域が検出されます。お札の領域を指定するため領域の面積が10000~15000の範囲にある場合に回転外接矩形を求め、回転外接矩形の回転角を用いて、元画像を回転しています。
import cv2 img = cv2.imread('5000.jpg') # 画像読み出し height, width, _ = img.shape # 形状取得 center = (int(width/2), int(height/2)) # 中心座標設定 img_gray = cv2.imread('5000.jpg', 0) # グレースケール読み出し ret, img_binary = cv2.threshold(img_gray, 180, 255, cv2.THRESH_BINARY) # 輝度180を境界に二値化 contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 領域検出 # 各領域を読み出し for i in contours: area = cv2.contourArea(i) # 各領域の面積 if 10000<area<15000: # 10000<面積<15000の場合 rect = cv2.minAreaRect(i) # 回転外接矩形の算出 angle = 90+rect[2] # 回転角を設定 trans = cv2.getRotationMatrix2D(center, angle, scale=1) # 変換行列の算出 img2 = cv2.warpAffine(img, trans, (width, height)) # 元画像を回転 cv2.imwrite('rot5000.jpg', img2) # 回転画像を保存
実行結果
お札が水平になった画像が保存されます。
以下のサイトを参考にさせていただきました
OpenCV-Python Tutorials 1 documentation >> 領域(輪郭)の特徴
Pythonの文法メモ > 【OpenCV】warpAffineによる画像の並進,回転