🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

OpenCV

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

Python

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

Q&A

解決済

1回答

997閲覧

画像の細い部分を分割する方法

Gonnnn

総合スコア52

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

OpenCV

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

Python

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

0グッド

0クリップ

投稿2019/12/26 08:28

編集2019/12/27 09:32

画像の編集をしているのですが、画像の細い部分を分割して欲しいのですが、どのようにすればできますか?
具体的には
イメージ説明
このような画像を
イメージ説明
のように分割、もしくは分割した輪郭を取得したいです。
分割した線を曲線に沿って分割されればベストです。
どのようにすれば分割できますか?

・・・追記・・・
元の画像で、画像から顔、目を特定して抽出するところまではできました。
イメージ説明

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

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

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

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

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

fana

2019/12/26 08:33

分割の基準がよくわかりません. (示された例では画像中央上部だけが分割され,他の箇所は分割されていない.分割するかしないかをどうやって決める話ですか?)
退会済みユーザー

退会済みユーザー

2019/12/26 08:41

この手の処理は非常に難しいです。技術的な難しさもありますが「~をしたい」と思っている本人ですらどういうときにその処理を適用するか否か明確な基準を持つことが難しいためです。 ましてや質問に答える側は質問者の感覚レベルの認識も持てないのです。 質問が悪いと言うよりこの手の問題に共通する課題ですね・・・ 複数例が挙がっていたり、細かい方針が提示されていれば答えようはあるかもしれませんが。 とりあえず輪郭追跡処理あたりから入ってみてはどうでしょう?
Gonnnn

2019/12/26 08:45

最終面積が一番大きいところを取得する予定なので、一番分けて欲しいところを画像にしました。。。 画像は目を二値化したもので、黒目の部分だけ抽出したいです。 凹性があるところ?を分割すればいいのではと考えたのですが、白目の頂点のみを取得する方法がわからず分割するという形で質問させていただきました。
fana

2019/12/26 08:50

> 黒目の部分だけ抽出したい この手の処理は,視線検知系の話でよく行われるものだと思うので,それ系の文献などを当ってみてはどうでしょうか?
退会済みユーザー

退会済みユーザー

2019/12/26 08:50

完全に質問と異なる答えになりますが、仮に対象が黒目に限られるなら別のアプローチを検討した方が楽かもしれません。 そもそも今のだと黒目の上の目蓋も取っているっぽいですし、2値化する前の方が情報が多いですので... 黒目は例にすぎず、分割処理が欲しいのでしたら的外れですいません。
Gonnnn

2019/12/26 08:56

私もそれは思いましたが、ネットで調べても瞳が完全に見えている状態のものが多く、瞳が欠けていても瞳を認識するというものがみつかりませんでした。。多少は瞳の範囲からずれていても大丈夫なので、二値化、瞳の範囲を取得、少し縮小すれば大まかな瞳の領域が取得できると考えこの形をとらせていただきました。 他の瞳の領域を取得できる方法があれば教えていただけるとありがたいです。
fana

2019/12/26 09:07

欲しいのは 黒目or瞳(瞳孔)? 画像の程度次第ですが,黒目(あるいは瞳孔)の輪郭点をある程度取得できれば(それが結構難しいのですが…)楕円フィッティングでそれなりには頑張れるんじゃないかと思います. 昔これ系にちょっと携わった際には,上部の山なりカーブを見つけてそれを足掛かりに黒い部分の幅とかを見て睫毛らへんを捨てるみたいな方向の手法もあったような…(忘れた)
退会済みユーザー

退会済みユーザー

2019/12/26 09:08

その程度の雑さで良いのであればシンプルな方法だとOpeningでいっそ細い部分を全部消してしまっても良いかもしれません。 勿論精度は落ちます。 汎用かつ厳密にやろうとすると、もう論文読んで下さいレベルの話になるかもしれません。
tiitoi

2019/12/26 09:21

最終的にやりたい事というのはどういうことなのでしょうか? 顔の画像から瞳の部分だけ抽出したのでしょうか?
Gonnnn

2019/12/26 09:37

欲しいのは黒目の部分です。 黒目の輪郭が難しいですよね。。。 Openigでやってみたらそれっぽい範囲が取得できたので、Openingで進めたいと思います!
fana

2019/12/26 10:07

(要求される処理結果精度や処理のロバスト性が謎ですね)
tiitoi

2019/12/26 10:53

2値化だと画像の明るさとかに左右されるので、画像処理だけでなかなか綺麗に瞳の部分だけ抜き出すのは難しそうですね。 任意の画像に対して、精度よくやりたいなら、CNN 使ったほうが良さそうと思いました。
Gonnnn

2019/12/27 09:41

CNNで学習させるという手もあるんですね! しかし、私の開発環境で他のライブラリを追加する方法がわからず、kerasが入ってなさそうなので諦めます。。。追加する方法がわかればCNNを追加して精度を上げて目の認識をやってみます!!
guest

回答1

0

ベストアンサー

荒業ですが…
イメージ説明

Python3

1import cv2 2import numpy as np 3 4img = cv2.imread('temp.jpeg',0) 5# img = 255-img 6img_blur = cv2.medianBlur(img,11) 7 8cv2.imshow('img_blur',img_blur) 9 10cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 11 12circles = cv2.HoughCircles(img_blur,cv2.HOUGH_GRADIENT,1,2,param1=10,param2=8,minRadius=20,maxRadius=40) 13 14if circles is not None: 15 for i in circles[0,:]: 16 # print(img[int(i[1]),int(i[0])]) 17 if 0 < img_blur[int(i[1]),int(i[0])]: 18 # draw the outer circle 19 cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2) 20 # draw the center of the circle 21 cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) 22 # else: 23 # cv2.circle(cimg,(i[0],i[1]),i[2],(0,64,0),1) 24 # cv2.circle(cimg,(i[0],i[1]),2,(0,0,64),1) 25 26 27 cv2.imshow('detected circles',cimg) 28else: 29 print("No circles detected.") 30 31cv2.waitKey(0) 32cv2.destroyAllWindows() 33

以下、初回投稿部分

最終面積が一番大きいところを取得する予定
画像は目を二値化したもので、黒目の部分だけ抽出したいです。

二値化は便利な処理ですが、何人か指摘されていますように、恐らくここまで削減された情報から黒目らしきものを抽出するのは困難です。

黒目は~~(目玉のオヤジでもない限り)~~瞼や目の下側が欠けますので、ある程度ロバスト性のある丸の検出が必要になります。

その関数がcv2.HoughCircles()です。

その前処理として、二値化を含めcv2.adaptiveThreshold()cv2.Canny()、また、
cv2.Laplacian()のあたりが使えるかもしれません。

外国の方で何人か古いバージョンのOpenCVで挑戦されています。
ここ1
ここ2

どのパラメータが当たりかはやってみて試すしかないと思います。

投稿2019/12/26 13:11

編集2019/12/26 22:24
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Gonnnn

2019/12/27 09:37

サンプルプログラムまでありがとうございます!! 画像は不特定のモノが入り、目の大きさ、黒目の位置などは物によって変わるのですが、このプログラムは動作しますか? あとparam1、param2はどういうパラメーターなのでしょうか。。。
退会済みユーザー

退会済みユーザー

2019/12/27 09:46

> 画像は不特定のモノが入り、目の大きさ、黒目の位置などは物によって変わる もし人の顔であれば、通常のhaar_likeの物体検出で右目左目の位置を抜き出せますので、それで対応できると思います。 黒目が上下左右どこを向いていたとしても、(直感的に、ですが)全体の六割くらいが見えていれば動くと思います。 >このプログラムは動作しますか? 日本人なら黒系の色で閾値を決めて二値化すればよいと思いますし、西洋の人もありえるのであれば、cannyをうまく使って色の依存度の低い丸の検出が必要になるかもしれません。 > param1、param2 線を検出する方法としてCannyという処理があります。輪郭や皺を際立たせる処理です。この時の「あー、これだけ差があれば線でしょう」の閾値がparam1、「円ぽいものが見つかったけれども、(関数内での)投票数がなぁ」の閾値がparam2です。投票の閾値を下げれば当選しやすく、つまり円でないものも円だと検出しやすくなりますので注意が必要です。 http://opencv.jp/opencv-2svn/cpp/feature_detection.html#cv-houghcircles
Gonnnn

2019/12/27 10:03

早い対応ありがとうございます! minRadius、maxRadiusだけ目の領域の大きさから値を入れればいいのですね。 試してみます!!
Gonnnn

2019/12/28 04:24

やりたいことができました!! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問