質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3553閲覧

描画した外接矩形の辺の長さを求める

Taka11

総合スコア14

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/10/21 11:57

実現したいこと

輪郭抽出ののち描画した、外接矩形の各辺の長さを求めたいです。

下のコードで描画したそれぞれの外接矩形の各頂点座標がrectsに格納されていることはわかるのですが、
そこから座標情報を取り出して各外接矩形の辺の長さを求める繰り返し処理を行うコードがわかりません、、
どなたか教えていただけると幸いです。

該当のソースコード

python

1import cv2 2import numpy as np 3 4# 画像の読み込み 5img = cv2.imread('C:/Users/ito/Anaconda3/envs/Sample/pic/testimg/IMG_0070.jpg') 6 7# リサイズ 8#img = cv2.resize(img, dsize=None, fx=0.2, fy=0.2) 9 10# グレースケールに変換 11gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 12 13# 二値化 14_, binary = cv2.threshold(gray, 89, 255, cv2.THRESH_BINARY_INV) 15 16#輪郭抽出 17_, contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 18 19# 面積が小さい輪郭削除 20area = img.shape[0] * img.shape[1] 21contours = list(filter(lambda cnt:10< cv2.contourArea(cnt), contours)) 22 23# 外接矩形に変換 24# drawContours() に渡す輪郭は int 型である必要があるため、astype(int) でキャストすること。 25rects = [cv2.boxPoints(cv2.minAreaRect(cnt)).astype(int) for cnt in contours] 26 27# 外接矩形を描画 28cv2.drawContours(img, rects, -1, (0, 255, 0), 1) 29 30#外接矩形の長さを算出 31 32 33# 画像を保存 34cv2.imwrite('C:/Users/ito/Anaconda3/envs/Sample/pic/result/minAR0070_89.jpg', img) 35#cv2.imshow('sample', binary) 36#cv2.waitKey(0) 37#cv2.destroyAllWindows 38 39print(rects)

開発環境

windows7 professional
python3.6.5
opencv3.3.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以下の関数に rects の各要素を渡せば、輪郭の長さが返ってきます。

retval = cv2.arcLength(curve, closed)

引数

  • curve: 輪郭
  • closed: 輪郭が閉じているかどうか。長方形は閉じているので True

返り値

  • retval: 輪郭の長さ

参考リンク

追記

回転した長方形の4点から中心、回転角度、大きさを計算するコード

python

1def get_rect_info(rect): 2 # 長方形の中心 3 center = (rect[0] + rect[2]) / 2 4 5 # 長さが異なる2つの辺の長さをそれぞれ計算する。 6 vec1 = rect[0] - rect[1] 7 vec2 = rect[1] - rect[2] 8 vec1_len = np.linalg.norm(vec1) 9 vec2_len = np.linalg.norm(vec2) 10 11 # 長辺が幅、短辺が高さとする。 12 if vec1_len < vec2_len: 13 widht, height = vec2_len, vec1_len 14 vecw = vec2 15 else: 16 widht, height = vec1_len, vec2_len 17 vecw = vec1 18 19 # x 軸と長辺のなす角を計算する。 20 if np.isclose(vecw[0], 0): 21 angle = 0 22 else: 23 angle = -np.arctan(vecw[1] / vecw[0]) 24 angle = np.rad2deg(angle) 25 26 return {'center': center, 'angle': angle, 'size': (width, height)}

テスト

python

1import cv2 2import matplotlib.pyplot as plt 3import numpy as np 4from matplotlib.patches import Polygon 5 6x, y = 100, 150 7width, height = 300, 100 8rect = np.array([ 9 [x, y], 10 [x + width, y], 11 [x + width, y + height], 12 [x, y + height], 13 [x, y]], dtype=float) 14 15# 長方形を描画する。 16fig, axes = plt.subplots(figsize=(6, 6)) 17axes.set_xlim(0, 500) 18axes.set_ylim(0, 500) 19 20for angle in range(0, 360, 40): 21 # 長方形の中心周りに -angle 回転させる回転行列を作成する。 22 center = tuple(((rect[0] + rect[2]) / 2).astype(int)) 23 R = cv2.getRotationMatrix2D(center, -angle, 1.) 24 25 # 回転行列を適用し、回転した長方形の点を計算する。 26 rotated_rect = cv2.transform(rect.reshape(1, -1, 2), R)[0] 27 28 # 確認用に描画する。 29 axes.add_patch(Polygon(rotated_rect, fill=None, lw=2., color='b')) 30 31 # 4点の座標から中心、回転角度、大きさを計算する。 32 info = get_rect_info(rotated_rect) 33 34 print('center: {}, angle: {:.2f}, size: {}'.format(info['center'], info['angle'], info['size'])) 35 36plt.show()
center: [250. 200.], angle: 0.00, size: (300, 100.0) center: [250. 200.], angle: -40.00, size: (300, 100.00000000000001) center: [250. 200.], angle: -80.00, size: (300, 100.00000000000004) center: [250. 200.], angle: 60.00, size: (300, 100.00000000000004) center: [250. 200.], angle: 20.00, size: (300, 99.99999999999999) center: [250. 200.], angle: -20.00, size: (300, 100.00000000000004) center: [250. 200.], angle: -60.00, size: (300, 100.00000000000001) center: [250. 200.], angle: 80.00, size: (300, 100.00000000000006) center: [250. 200.], angle: 40.00, size: (300, 100.00000000000001)

イメージ説明

投稿2018/10/21 13:42

編集2018/10/21 17:29
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Taka11

2018/10/21 15:12

ご回答いただきありがとうございます! 大変ありがたいのですが、現在求めたいのが周囲長ではなく矩形の短辺と長辺をそれぞれでして、それについての解決方法を教えて頂けますと幸いなんですが、、 よろしくお願いいたします。
tiitoi

2018/10/21 17:30

追記しました。 2つの異なる辺のベクトルを作り、ノルムを計算すればよいです。
Taka11

2018/10/22 00:49

ありがとうございます! 自分の方でも試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問