実現したいこと
下記画像で赤線に塗っている部分のオブジェクトを輪郭検出したい。
前提
画像中の線の数を数えるプログラムを作りたいのですが、見切れているためか検出されない線があります。
どういった手法なら以下の画像中に存在する見切れた線も検出することができるでしょうか?
※7/21追記
みなさんのコメントのおかげでモルフォロジー変換でノイズを飛ばすことができました!
モルフォロジー変換でノイズとして消すことのできなかった部分は領域の大きさで除外しようと思っていたのですが
下記のコードで領域の大きさを視覚化したところどうも赤線部分のオブジェクトは極端に領域の大きさが小さくとらえられているようです。
なにかコードに不備があるのでしょうか?
上記の画像から太線のみを検出できる方法があれば教えていただきたいです。
Python
1from google.colab.patches import cv2_imshow 2import cv2 3import numpy as np 4 5# 画像を読み込む 6image = cv2.imread('/content/28896_12765.png') 7 8# 画像をグレースケールに変換 9gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 10 11# Cannyエッジ検出を適用 12threshold1 = 100 13threshold2 = 650 14edges = cv2.Canny(gray, threshold1, threshold2) 15 16# 輪郭を検出 17contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 18 19# 面積が一定以上の輪郭のみを抽出 20filtered_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > 2] 21 22# 線を描画したコピーを作成 23image_lines = image.copy() 24cv2.drawContours(image_lines, filtered_contours, -1, (0, 255, 0), 2) 25 26# 各輪郭の面積を描画 27for cnt in filtered_contours: 28 # 輪郭の面積を取得 29 area = cv2.contourArea(cnt) 30 31 # 輪郭の中心座標を取得 32 M = cv2.moments(cnt) 33 cx = int(M["m10"] / M["m00"]) 34 cy = int(M["m01"] / M["m00"]) 35 36 # テキストを描画 37 cv2.putText(image_lines, f"S: {area}", (cx - 50, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0, 0, 255), 2) 38 39# 画像を表示 40cv2_imshow(image_lines) 41 42# 検出された輪郭の数を出力 43line_count = len(filtered_contours) 44print("線の数:", line_count)
発生している問題・エラーメッセージ
エラー自体は出ていないのですが、上記の画像のように上手く検出できない線があります。
上から1/4ほどのところで画像を横切っている太い線や画像左下部の3つ並んだ線、画像右下から伸びる少し穴の開いた線なども検出できるようにしたいです。
Python
1from google.colab.patches import cv2_imshow 2import cv2 3import numpy as np 4 5# 画像を読み込む 6image = cv2.imread('/content/gazo1.png') 7 8# 画像をグレースケールに変換 9gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 10 11# Cannyエッジ検出を適用 12threshold1 = 50 13threshold2 = 150 14edges = cv2.Canny(gray, threshold1, threshold2) 15 16# 輪郭を検出 17contours, hierarchy = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 18 19# 輪郭の面積が40以上のもののみ抽出 20filtered_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > 40] 21 22# 線を描画したコピーを作成 23image_lines = image.copy() 24cv2.drawContours(image_lines, filtered_contours, -1, (0, 255, 0), 2) 25 26# 画像を表示 27cv2_imshow(image_lines) 28 29# 検出された輪郭の数を出力 30line_count = len(filtered_contours) 31print("線の数:", line_count)
試したこと
しきい値やthreshold値の変更
![退会済みユーザー](https://ddjkaamml8q8x.cloudfront.net/profileImages/deletedUser/icnUserSample.jpeg)
![退会済みユーザー](https://ddjkaamml8q8x.cloudfront.net/profileImages/deletedUser/icnUserSample.jpeg)
![退会済みユーザー](https://ddjkaamml8q8x.cloudfront.net/profileImages/deletedUser/icnUserSample.jpeg)
![guest](/img/icon/icnUserSample.jpg)
回答1件
あなたの回答
tips
プレビュー