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

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

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

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

Python

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

Q&A

解決済

1回答

1179閲覧

opencv 色 円 検出

退会済みユーザー

退会済みユーザー

総合スコア0

OpenCV

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

Python

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

1グッド

2クリップ

投稿2017/07/20 01:19

編集2017/07/20 01:25

###前提・実現したいこと
以前にした質問1
以前にした質問2
を使って円検出の精度を上げたいと思っています。
###発生している問題
知識不足で申し訳ないですがどう組み合わせればいいかわかりません。円を検出した後に色を確認したほうがいいのか、順番を変えたほうがいいのか具体的にどう条件分岐をさせればいいか教えていただきたいです。

#該当のソースコード

python

1import numpy as np 2import cv2 3 4cam = cv2.VideoCapture(0) 5 6 7while(cam.isOpened()): 8 9 ret, frame = cam.read() 10 cam_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 11 cam_hsv = cv2.inRange(cam_hsv, (30,100,100), (60,160,160)) 12 13 cam_color = frame.copy() 14 cam_color[cam_hsv==0] = 0 15 16 17 element = np.ones((5,5)).astype(np.uint8) 18 cam_hsv = cv2.erode(cam_hsv, element) 19 cam_hsv = cv2.dilate(cam_hsv, element) 20 points = np.dstack(np.where(cam_hsv>0)).astype(np.float32) 21 center, radius = cv2.minEnclosingCircle(points) 22 cv2.circle(frame, (int(center[1]), int(center[0])), int(radius), (255,0,0), thickness=3) 23 24 25 cv2.imshow('preview', frame) 26 27 if cv2.waitKey(1) & 0xFF == ord('q'): 28 break

python

1import numpy as np 2import cv2 3 4cam = cv2.VideoCapture(0) 5 6while(cam.isOpened()): 7 8 ret, frame = cam.read() 9 10 size = (640, 480) 11 frame = cv2.resize(frame, size) 12 13 gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) 14 gray = cv2.GaussianBlur(gray, (33,33), 1) 15 16 colimg = frame.copy() 17 18 circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 60, param1=40, param2=75, minRadius=10, maxRadius=100) 19 20 if circles is not None: 21 circles = np.uint16(np.around(circles)) 22 for i in circles[0,:]: 23 24 cv2.circle(colimg,(i[0],i[1]),i[2],(255,255,0),2) 25 26 cv2.imshow('preview', colimg) 27 if cv2.waitKey(1) & 0xFF == ord('q'): 28 break 29 30cam.release() 31cv2.destroyAllWindows()
退会済みユーザー👍を押しています

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/07/21 12:54 編集

ハフ変換での円の検出vs画像処理で円を際立たせてからの外接円による円の検出なので、大変面白い質問だと思います。 確認ですが、検出するのはボールのような球ではなく(紙に印字したりなんなりの)円なのですね?質問の意図は、形状が常に真円に近い状態か楕円になるかということを確認するためです。
退会済みユーザー

退会済みユーザー

2017/07/23 07:55

すいません。ボールトラッキングをするつもりです。
退会済みユーザー

退会済みユーザー

2017/07/23 08:34 編集

ボールなら「(影を除けばまずもって)色は固定」「どこから見ても常に円」ですので、色でマスクして丸を検出の cv2.minEnclosingCircle(points)がよさげですね。柄もののボール(ビーチボール?)などの場合、ボールを見ながら色味の調整が必要だと思います。
退会済みユーザー

退会済みユーザー

2017/07/24 07:03

ありがとうございます。試してみます。
guest

回答1

0

ベストアンサー

調べてもそれっぽいのがありませんでしたので、私の考えで書きます。

*2つの違い
2つのコードを見て考えたのですが、それぞれ思想が違いますよね。

上のコード:
特定範囲の色で、しかも円が来ると決まりきっている場合
(だから先に不要な色は黒色でつぶしてしまい、色のついていない部分を負荷の少ない方法で検出)

下のコード:
何色が来るかわからなくて、円に近いと思われる場合
(だから色でなく色の境目を使うcanny処理を利用。線ばかりの中からそれっぽい部分を拾うため負荷が高い...と言っても実際問題として多分軽いです)

多分上のコードの方が軽くて速い代わりにあんまり融通が利きません。
下のコードは全く反対の特性と思われます。
(どれくらいの違いがあるかは試さないとわかりませんが...)

*精度UP?
円がたくさんあって、色で分離する必要があれば検出後にあれこれいるかもしれませんが、とりあえず検出するだけなら、いずれのアルゴリズムでも今の処理の順番でよいと思います。
円が真円から離れて楕円になる可能性がある場合、楕円の検出アルゴリズムを使えば精度は上がるかもしれませんが、標準では実装されていないため多分複雑な処理が必要になると思います。


書き換えてはいませんが以下の#部分のコメントを見ると雰囲気が伝わりやすいかと思います。

*上のコード

Python

1import numpy as np 2import cv2 3 4cam = cv2.VideoCapture(0) 5 6# カメラが有効な間ループ 7while(cam.isOpened()): 8 # 画像を読み取る 9 ret, frame = cam.read() 10 11 # RGB(赤青緑)からHSV(色味、鮮やかさ、明るさ)に変換する 12 cam_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) 13 14 # 特定の色だけのマスクを作る 15 cam_hsv = cv2.inRange(cam_hsv, (30,100,100), (60,160,160)) 16 17 # オリジナルの画像をコピーし、マスクされている部分を0にする(黒くする) 18 cam_color = frame.copy() 19 cam_color[cam_hsv==0] = 0 20 21 # ゴマ粒ノイズを消すためのマスクを用意する 22 element = np.ones((5,5)).astype(np.uint8) 23 24 # ゴマ粒ノイズを消す(?)ために膨張収縮させる 25 cam_hsv = cv2.erode(cam_hsv, element) 26 cam_hsv = cv2.dilate(cam_hsv, element) 27 28 # ノイズを消し、しかもオリジナルの画像にマスク処理をして不要な部分をつぶした画像に対して、円の検出処理をする 29 # この時、「外接円」を探す 30 points = np.dstack(np.where(cam_hsv>0)).astype(np.float32) 31 center, radius = cv2.minEnclosingCircle(points) 32 cv2.circle(frame, (int(center[1]), int(center[0])), int(radius), (255,0,0), thickness=3) 33 34 35 cv2.imshow('preview', frame) 36 37 if cv2.waitKey(1) & 0xFF == ord('q'): 38 break

*下のコード

Python

1import numpy as np 2import cv2 3 4cam = cv2.VideoCapture(0) 5 6# カメラが有効な間ループ 7while(cam.isOpened()): 8 9 # 画像を読み取る 10 ret, frame = cam.read() 11 12 size = (640, 480) 13 frame = cv2.resize(frame, size) 14 15 # 画像をRGB(赤緑青)からグレースケール(色味なし)に変更 16 gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) 17 18 # ギザギザを目立たなくなるようにぼかす 19 gray = cv2.GaussianBlur(gray, (33,33), 1) 20 21 # 元画像をコピーする 22 colimg = frame.copy() 23 24 # ハフ検出をする(内部では色の切り変わり目を線にして=canny処理、円に近い部分を検出) 25 circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 60, param1=40, param2=75, minRadius=10, maxRadius=100) 26 27 # 円が一つでもあれば 28 if circles is not None: 29 30 # 円を書く 31 circles = np.uint16(np.around(circles)) 32 for i in circles[0,:]: 33 cv2.circle(colimg,(i[0],i[1]),i[2],(255,255,0),2) 34 35 cv2.imshow('preview', colimg) 36 37 if cv2.waitKey(1) & 0xFF == ord('q'): 38 break 39 40cam.release() 41cv2.destroyAllWindows()

投稿2017/07/21 13:13

編集2017/07/23 08:36
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問