opencvのcv2.findContours()を利用し、マスク画像を通して対象の輪郭線を抽出することには成功したのですが、対象の輪郭線を半分だけ検出したい場合はどのような方法があるのでしょうか?
なかなか実践している人がいらっしゃらないので質問させていただきます。
イメージでは下図のようなものです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
の輪郭線を半分だけ
の意味合いが不明瞭ですが,「輪郭線の全長の半分」という話であれば,
- 輪郭の座標を(普通に)全部検出し,
- 検出した座標データを半分だけ使う(不要なら「半分捨てる」)
とすれば良いのではないでしょうか.
半分というのが「どこから」「どこまで」の範囲なのかは知りませんが,とにかく必要な箇所を使って不要な箇所を使わなければよいでしょう.
「単純に,findContours が返してきた結果(輪郭の座標群)の後半を捨てる」としたコードを示します.(C++ですが)
C++
1int main() 2{ 3 cv::Mat SrcImg = cv::imread( "Regions.png", cv::IMREAD_GRAYSCALE ); //画像読込 4 if( SrcImg.empty() )return 0; //読込失敗チェック 5 cv::threshold( SrcImg, SrcImg, 128, 255, cv::THRESH_BINARY ); //2値化 6 7 //ふつーにcontour検出 8 std::vector< std::vector< cv::Point > > contours; 9 cv::findContours( SrcImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE ); 10 11 //表示用画像バッファを用意 12 cv::Mat ShowImg; 13 cv::cvtColor( SrcImg, ShowImg, cv::COLOR_GRAY2BGR ); 14 ShowImg *= 0.25; 15 16 //contour検出結果をまずはふつーに赤で描画 17 cv::drawContours( ShowImg, contours, -1, cv::Scalar(0,0,255), 2 ); 18 19 //輪郭データを半分だけにして,シアンで描画 20 for( auto &cont : contours ){ cont.resize( cont.size() / 2 ); } //※各輪郭のデータを半分捨てる 21 cv::polylines( ShowImg, contours, false, cv::Scalar(255,255,0), 2 ); 22 23 // 24 cv::imshow( "ShowImg", ShowImg ); 25 if( cv::waitKey() == 's' ){ cv::imwrite( "Regions_result.png", ShowImg ); } 26 return 0; 27}
処理結果例:
- 用いた入力画像
- 処理結果画像
投稿2021/09/03 02:10
総合スコア11996
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
あってますか?わからないことは英語で探すと大体見つかります。
Python3
1import cv2 2import numpy as np 3 4img_gray= cv2.cvtColor(cv2.imread("./tri.png"),cv2.COLOR_BGR2GRAY) 5 6 7ret, thresh = cv2.threshold(img_gray,127,255,0) 8cv2.imshow("thresh",thresh) 9 10cnts, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 11 12img_mask = np.zeros_like(img_gray) 13img_mask = cv2.drawContours(img_mask, cnts, 1, 255,5) 14 15cv2.imshow("img_mask",img_mask) 16 17out = img_mask.copy() 18out_half = img_mask.copy() 19# https://stackoverflow.com/questions/28759253/how-to-crop-the-internal-area-of-a-contour 20(y, x) = np.where(img_mask == 255) 21(topy, topx) = (np.min(y), np.min(x)) 22(bottomy, bottomx) = (np.max(y), np.max(x)) 23out = out[topy:bottomy+1, topx:bottomx+1] 24 25out_half = out_half[topy:bottomy+1, int(topx/2):int(bottomx/2)+1] 26cv2.imshow("out",out) 27 28 29cv2.imshow("out_half",out_half) 30cv2.imwrite("out_half.png",out_half) 31 32cv2.waitKey(0)
投稿2021/09/01 21:51
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/09/02 01:42
2021/09/02 01:47
退会済みユーザー
2021/09/02 21:52 編集
2021/09/03 01:08
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。