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

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

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

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

Python

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

Q&A

3回答

953閲覧

OpenCVで円筒が積まれた画像から各円筒の外形を取得したい

Shimama

総合スコア0

OpenCV

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

Python

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

0グッド

1クリップ

投稿2023/04/30 04:08

編集2023/04/30 04:14

Python OpenCVで円筒が積まれた画像から、各円筒の外形を取得したいと思っています。
イメージ説明
イメージ説明
・下記のコードにて輪郭を抽出して試してみましたが、内側の形状が取得され円筒の外形は取得できずにいます。
・画像は円筒材料の切断面なのですが、切断のバリが内側にあるため正確に円の形状を把握できず苦戦しています。


OpenCVで円筒が積まれた画像から各円筒の外形を取得したい

#画像を平滑化してノイズを除去
blur = cv2.GaussianBlur(img, (9,9), 0)

gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
cv2_imshow(gray)

th, dst = cv2.threshold(gray, 160, 255, cv2.THRESH_BINARY)
cv2_imshow(dst)

#閾値処理
ret,thresh = cv2.threshold(dst,120,255,cv2.THRESH_BINARY)

#輪郭検出 (cv2.ChAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)


試しに輪郭検出でRETR_EXTERNALも試してみましたが、検出できませんでした。
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

どなたかアドバイスいただけると幸いです。

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

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

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

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

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

Shimama

2023/05/07 07:04

1T2R3M4さま ご指摘ありがとうございました。初めての投稿でよくルールを分かっていませんでした。別の質問サイトで取消ししました。失礼いたしました。
guest

回答3

0

python

1import cv2 2# 画像 3img = cv2.imread('test.jpeg') 4# グレースケール変換 5gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 6# 閾値処理 7thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,7,0) 8cv2.imshow('thresh', thresh) 9cv2.waitKey(0)

結果
イメージ説明

適応閾値でなんとなくの結果ですが分離はできそうです
♯パラメータの調整が難しいけれども
なおフィルターでぼかすとくっつくので、この用途ではやめたほうがいい

投稿2023/05/01 18:14

yominet

総合スコア187

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

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

Shimama

2023/05/02 09:23

yominetさん 閾値処理についてアドバイスありがとうございます。 こんなに輪郭をくっきりさせることが出来るんですね。適応閾値の処理は知らなかったのですが、光の当たり方に左右されずに形状を抽出できたり奥が深いですね。 この処理を入れてみたら、外周を検出して取得しやすくなりました。ありがとうございます!
guest

0

もしも,安定して

内側の形状が取得

できるのだとすれば……
私なら,「その結果に基づいて「外側」の輪郭を探すことはできないのか?」と考えるかもしれません.

例えば,至極単純には,その内側形状の各点から「外側」方向に向かって,想定する輝度勾配方向を持つエッジ点を探索してみるような処理が考えられそうですよね.
(筒の径と厚みとの間の比率のような前提知識があるなら探索範囲もある程度に制限できるかと)

でも,そういう処理をするとしたら,隣の筒と接しているような箇所において間違った探索結果(隣の内側のエッジを見つける)を生じそうですよね.何か対策できるだろうか?

大多数の箇所では外側の点を正しく見つけることができるのだとしたら,例えばRANSAC的に楕円を当てはめるような処理でそういった点は棄却できるのではないかな,とか,
あるいは,もっと単純に「(隣の筒の内側も検出できているなら)接しそうな方向は使わない」という方向も考えられるかな,とか.

……みたいな愚直なことをしたならば{それでどこまでいけるのか? ダメそうなら課題点は何か?}みたいな検討をまずはざっくりとやってみてはどうでしょうか.

投稿2023/04/30 08:08

fana

総合スコア11652

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

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

Shimama

2023/04/30 09:17

fanaさん ありがとうございます。 確かに内側のデータはある意味安定して取れているので、そこを起点として外側を探していくという方法は可能かもしれないですね。 そして確かに悩ましいのが隣の筒と接している箇所が悩ましいです。RANSACというのは外れ値が含まれていると想定して影響を押さえる手法なんですね。私は素人なので知らなかったのですが、少し調べて考えてみようと思います。
guest

0

HoughCirclesを使用してみたらいかがでしょうか。
円筒の外形を取得するために、画像処理のアプローチを変更すると良いと思います。

python

1import cv2 2import numpy as np 3 4# 画像を読み込み 5img = cv2.imread('') 6 7# 画像を平滑化してノイズを除去 8blur = cv2.GaussianBlur(img, (9, 9), 0) 9 10# グレースケール変換 11gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) 12 13# 閾値処理 14ret, thresh = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY) 15 16# HoughCirclesを使用して円を検出 17circles = cv2.HoughCircles(thresh, cv2.HOUGH_GRADIENT, dp=1, minDist=20, 18 param1=50, param2=30, minRadius=10, maxRadius=0) 19 20# 検出された円を描画 21if circles is not None: 22 circles = np.round(circles[0, :]).astype("int") 23 24 for (x, y, r) in circles: 25 cv2.circle(img, (x, y), r, (0, 255, 0), 2) 26 27 cv2.imshow('Detected Circles', img) 28 cv2.waitKey(0) 29 cv2.destroyAllWindows()

これを実行すれば円筒の外形を検出できるかと思います。

投稿2023/04/30 07:48

編集2023/04/30 08:52
jp-seemore.com

総合スコア62

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

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

fana

2023/04/30 08:18 編集

「説明が不足している」とかいうのを投じてみました. 「XXXを使えばどうか」と言う場合には「XXXを使えばこんないいことがある」という理由や考えがあるはずで,そこの部分こそが重要であり,それが明確に示されていないと読み手には伝わらない可能性が大きいと思うので.
Shimama

2023/04/30 09:22

NICKOさん コメントありがとうございます。 頂いたアドバイスでは円形を見つけ、中心座標と半径を取得できるのですが、対象となるワークは真円ではなく、その円形のいびつさを計るプロセスとしてワークの輪郭外周の座標データを取得したいと考えています。
jp-seemore.com

2023/04/30 09:49

import cv2 # 画像を読み込み img = cv2.imread('') # 画像を平滑化してノイズを除去 blur = cv2.GaussianBlur(img, (9, 9), 0) # グレースケール変換 gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) # 閾値処理 ret, thresh = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY) # 輪郭検出 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 近似輪郭を格納するリスト approx_contours = [] for contour in contours: # 輪郭の近似 epsilon = 0.01 * cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, epsilon, True) approx_contours.append(approx) # 近似輪郭を描画(デバッグ用) cv2.drawContours(img, [approx], 0, (0, 255, 0), 2) # 近似輪郭を表示(デバッグ用) cv2.imshow('Approximated Contours', img) cv2.waitKey(0) cv2.destroyAllWindows() # いびつな形状の外周座標データ print(approx_contours) これで外周の座標データを取得できるはずです。 細かい調整は適宜すると精度が高まるかもです。
Shimama

2023/04/30 12:28

ありがとうございます。試してみましたが、やはり内側の輪郭を取得してしまいます…
jp-seemore.com

2023/04/30 22:09

import cv2 # 画像を読み込む img = cv2.imread('') # 画像を平滑化してノイズを除去 blur = cv2.GaussianBlur(img, (9, 9), 0) # グレースケール変換 gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY) # 閾値処理 ret, thresh = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY) # 輪郭検出 contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 最大輪郭の取得 max_contour = max(contours, key=cv2.contourArea) # 凸包を求める hull = cv2.convexHull(max_contour) # 凹凸を検出するための輪郭と凸包の差 defects = cv2.convexityDefects(max_contour, cv2.convexHull(max_contour, returnPoints=False)) if defects is not None: for i in range(defects.shape[0]): s, e, f, d = defects[i, 0] start = tuple(max_contour[s][0]) end = tuple(max_contour[e][0]) far = tuple(max_contour[f][0]) cv2.line(img, start, end, [0, 255, 0], 2) cv2.circle(img, far, 5, [0, 0, 255], -1) cv2.imshow('Image with Defects', img) cv2.waitKey(0) cv2.destroyAllWindows() おそらくこちらのコードで、輪郭データから凹凸を検出できうるかと思います。
Shimama

2023/05/01 08:26

コメントありがとうございます。試してみましたがダメでした。 私は素人でよくわかっていないのですが、こちらは何をねらいとしてどんな処理をしているのでしょうか?
jp-seemore.com

2023/05/01 08:42

円筒の輪郭から凹凸を検出して座標データを表示し、歪さを評価しようとしようとしています。
Shimama

2023/05/01 09:09

そうなんですね。私には使いこなせませんでした。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問