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

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

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

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

Python

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

Q&A

1回答

3109閲覧

OpenCV 四角形 検出

lebdom_11

総合スコア6

OpenCV

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

Python

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

0グッド

0クリップ

投稿2021/06/20 08:08

前提・実現したいこと

Python
Opencvを用いて,下の画像の白い部分の辺の長さを求めたいです.こちらは,二値化処理を行った後のものです.
辺の長さを求めるうえで,下記の画像を四角形として検出しようと思ったのですが,うまくいきません.
どのようにすれば,下の画像を,四角形として検出できるでしょうか?
また,辺の長さを求められるでしょうか?

イメージ説明

該当のソースコード

python

1import cv2 2import math 3import numpy as np 4 5# pt0-> pt1およびpt0-> pt2からの 6# ベクトル間の角度の余弦(コサイン)を算出 7def angle(pt1, pt2, pt0) -> float: 8 dx1 = float(pt1[0,0] - pt0[0,0]) 9 dy1 = float(pt1[0,1] - pt0[0,1]) 10 dx2 = float(pt2[0,0] - pt0[0,0]) 11 dy2 = float(pt2[0,1] - pt0[0,1]) 12 v = math.sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) ) 13 return (dx1*dx2 + dy1*dy2)/ v 14 15# 画像上の四角形を検出 16def findSquares(bin_image, image, cond_area = 1000): 17 # 輪郭取得 18 contours, _ = cv2.findContours(bin_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 19 for i, cnt in enumerate(contours): 20 # 輪郭の周囲に比例する精度で輪郭を近似する 21 arclen = cv2.arcLength(cnt, True) 22 approx = cv2.approxPolyDP(cnt, arclen*0.02, True) 23 24 #四角形の輪郭は、近似後に4つの頂点があります。 25 #比較的広い領域が凸状になります。 26 27 # 凸性の確認 28 area = abs(cv2.contourArea(approx)) 29 if approx.shape[0] == 4 and area > cond_area and cv2.isContourConvex(approx) : 30 maxCosine = 0 31 32 for j in range(2, 5): 33 # 辺間の角度の最大コサインを算出 34 cosine = abs(angle(approx[j%4], approx[j-2], approx[j-1])) 35 maxCosine = max(maxCosine, cosine) 36 37 # すべての角度の余弦定理が小さい場合 38 #(すべての角度は約90度です)次に、quandrangeを書き込みます 39 # 結果のシーケンスへの頂点 40 if maxCosine < 0.3 : 41 # 四角判定!! 42 rcnt = approx.reshape(-1,2) 43 cv2.polylines(image, [rcnt], True, (0,0,255), thickness=2, lineType=cv2.LINE_8) 44 return image 45 46def main(): 47 image = cv2.imread(r"C:\Users\81808\Pictures\YOLO result\21-0215cut\cut02-1.jpg", cv2.IMREAD_COLOR) 48 if image is None : 49 exit(1) 50 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 51 dst = cv2.Canny(gray, 200.0, 100.0) 52 _, bw = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) 53 rimage = findSquares(dst, image) 54 cv2.imshow('S', dst) 55 cv2.imshow('Square', bw) 56 cv2.imshow('Square Detector', rimage) 57 cv2.imwrite(r"C:\Users\81808\Pictures\YOLO result\21-0215cut\cut02-1-eggi.jpg", bw) 58 c = cv2.waitKey() 59 return 0; 60 61if __name__ == '__main__': 62 main()

試したこと

ちなみに,下記の画像を用いると該当のプログラムで四角形は検出できました.
イメージ説明

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

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

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

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

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

guest

回答1

0

ちなみに,下記の画像を用いると該当のプログラムで四角形は検出できました.

そのような,{人工的な,きれいな,わかりやすい,簡単な,etc...}画像であればできるよ,というプログラムでは結局使い物にならない(かもしれない),という話ですかね.

上記の「かもしれない」の部分を明らかにするために,いろいろと処理経過を見るなりしましょう.
なぜ現状ではできないのか? を分析し,そして,改善の方向性を定めましょう.

  • 「二値化」をもっと頑張れば,「四角形」をもっとまともな(=後段処理で検出できる形に)残せるのだろうか?
  • それが無理そうであるならば,現状の処理とはまったく他の方向で攻める必要があるかもしれない.

例えば,四角形の「四辺」を直線として検出できないのか? とかいう方向を考えることができるのかもしれない.

投稿2021/06/21 02:39

fana

総合スコア11675

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問