我一直在互联网上寻找合适的imfill函数(如 Matlab 中的函数),但在 C++ 中使用 OpenCV。经过一番研究,我终于想出了一个解决方案:
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 函数的参数设置: cvDrawContours(dst, contour, white, white, 0, CV_FILLED);
- dst = 目标图像
- 轮廓 = 指向第一个轮廓的指针
- 白色 = 用于填充轮廓的颜色
- 0 = 绘制轮廓的最大级别。如果为 0,则仅绘制轮廓
- CV_FILLED = 绘制轮廓线的粗细。如果它是负数(例如,=CV_FILLED),则绘制轮廓内部。
openCV 文档中的更多信息。
可能有一种方法可以直接将“dst”作为二进制图像获取,但我找不到如何将 cvDrawContours 函数与二进制值一起使用。