私は適切なimfill関数 (Matlab のものなど) を見つけるためにインターネットを見回してきましたが、OpenCV を使用して C++ で作業しています。いくつかの研究の後、私は最終的に解決策を思いつきました:
IplImage* imfill(IplImage* src)
{
CvScalar white = CV_RGB( 255, 255, 255 );
IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3);
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
cvFindContours(src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
cvZero( dst );
for( ; contour != 0; contour = contour->h_next )
{
cvDrawContours( dst, contour, white, white, 0, CV_FILLED);
}
IplImage* bin_imgFilled = cvCreateImage(cvGetSize(src), 8, 1);
cvInRangeS(dst, white, white, bin_imgFilled);
return bin_imgFilled;
}
この場合:元のバイナリ イメージ
結果:最終的なバイナリ イメージ
トリックは、cvDrawContours 関数のパラメーター設定にあります。
- dst = 宛先イメージ
- 輪郭 = 最初の輪郭へのポインタ
- 白 = 輪郭の塗りつぶしに使用される色
- 0 = 描かれた等高線の最大レベル。0 の場合、輪郭のみが描画されます
- CV_FILLED = 輪郭を描く線の太さ。負の場合 (たとえば、=CV_FILLED)、輪郭の内部が描画されます。
詳細については、openCV のドキュメントを参照してください。
「dst」をバイナリ イメージとして直接取得する方法はおそらくありますが、cvDrawContours 関数をバイナリ値で使用する方法が見つかりませんでした。