opencv で マーカー付き用紙の向きを直してみる
マーカーの検出を利用して、向きを直してみます。
カメラの歪み補正等(キャリブレーション)には踏み込みません。
四隅に黒い円のマーカーを付けた用紙です。
この傾きを補正しようと思います。
流れは
マーカー検出
座標の並び替え
射影変換
#!/usr/bin/env python # -*- coding: utf-8 -* import cv2 import numpy as np """ 円検出と、射影変換 """ def main(): image = cv2.imread('DSC_3009.jpg') #cv2.imshow('original', image) height, width ,depth = image.shape # リサイズ image = cv2.resize(image, (width/4, height/4)) imageOrg = image.copy() height, width ,depth = image.shape # グレースケールに変換 image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # ガウシアンフィルタ image = cv2.GaussianBlur(image, (5, 5), 0) # 二値変換 ret, image = cv2.threshold(image,127,255,cv2.THRESH_BINARY) # Python: cv2.findCirclesGridDefault(image, patternSize[, centers[, flags]]) → retval, centers # CALIB_CB_SYMMETRIC_GRID uses symmetric pattern of circles. # CALIB_CB_CLUSTERING uses a special algorithm for grid detection. It is more robust to perspective distortions but much more sensitive to background clutter. retval, centers = cv2.findCirclesGrid(image, (2,2), flags=cv2.CALIB_CB_SYMMETRIC_GRID + cv2.CALIB_CB_CLUSTERING) if retval: print centers image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) image = cv2.drawChessboardCorners(image, (2,2), centers, retval) # 射影変換のために、並び替えた配列を用意する points = np.array([ centers[0], centers[2], centers[3], centers[1] ]) print points # 外接矩形 bRect = cv2.boundingRect(points) print bRect cv2.rectangle(image, (bRect[0], bRect[1]), (bRect[0]+bRect[2], bRect[1]+bRect[3]), (255,0,0), 2) cv2.imshow('drawChessboardCorners', image) cv2.imwrite('90.drawChessboardCorners.png', image) # 射影変換 # 右上、左上、左下、右下 pts1 = np.float32(points) pts2 = np.float32([ [bRect[0]+bRect[2],bRect[1]], [bRect[0],bRect[1]], [bRect[0],bRect[1]+bRect[3]], [bRect[0]+bRect[2],bRect[1]+bRect[3]], ]) print(pts1) print(pts2) M = cv2.getPerspectiveTransform(pts1,pts2) imageOrg = cv2.warpPerspective(imageOrg,M,(width,height)) cv2.imshow('getPerspectiveTransform', imageOrg) cv2.imwrite('90.getPerspectiveTransform.png', imageOrg) cv2.waitKey(0) cv2.destroyAllWindows() return 0 if __name__ == '__main__': try: main() except KeyboardInterrupt: pass
検出された円と、外接矩形
完了