使用OpenCV(C ++)填充图像中的孔

在本教程中,我们将学习如何填充二进制图像中的孔。考虑一下图1左侧的图像。假设我们想找到一个二进制蒙版,它将硬币与背景分离开,如右图所示。在本教程中,包含硬币的圆形区域也称为前景。

CSDN图标

请注意,硬币的边界很暗,与白色背景不同。因此,我们使用简单的图像阈值处理将边界与背景分开。换句话说,我们说强度高于特定值(阈值)的像素是背景,其余像素是前景。上示中间图像显示此阈值图像(黑色代表背景,白色代表前景)。不幸的是,即使边界已被很好地提取(纯白色),硬币的内部强度也与背景相似。因此,阈值操作无法将其与背景区分开。我们如何用白色填充圆形边界内的所有像素?

MATLAB具有称为imfill的功能,该功能允许您填充孔,并且可以按以下方式使用它。

% MATLAB code for filling holes in a binary image. 
im = imfill(im,'holes');

OpenCV中的imfill

OpenCV中没有插入功能,但是我们可以肯定地写一个!这个想法很简单。我们知道像素(0,0)连接到背景。因此,我们可以通过简单地从像素(0,0)进行泛洪操作来提取背景。不受泛洪操作影响的像素必须在边界内。反转并与阈值图像组合时,充满洪水的图像将提供前景遮罩!
在这里插入图片描述

用C ++代码填充二进制图像中的孔

具体代码如下:

#include "opencv2/opencv.hpp"

using namespace cv;

int main(int argc, char **argv)
{
	// Read image
	Mat im_in = imread("nie.png", IMREAD_GRAYSCALE);


	// Threshold.
	// Set values equal to or above 220 to 0.
	// Set values below 220 to 255.
	Mat im_th;
	threshold(im_in, im_th, 220, 255, THRESH_BINARY_INV);

	// Floodfill from point (0, 0)
	Mat im_floodfill = im_th.clone();
	floodFill(im_floodfill, cv::Point(0, 0), Scalar(255));

	// Invert floodfilled image
	Mat im_floodfill_inv;
	bitwise_not(im_floodfill, im_floodfill_inv);

	// Combine the two images to get the foreground.
	Mat im_out = (im_th | im_floodfill_inv);

	// Display images
	imshow("Thresholded Image", im_th);
	imshow("Floodfilled Image", im_floodfill);
	imshow("Inverted Floodfilled Image", im_floodfill_inv);
	imshow("Foreground", im_out);
	waitKey(0);

}

其他技术

还有其他方法可以解决相同的问题。一种方法是使用形态学闭运算。但是,要进行形态学操作,您需要知道孔的最大尺寸。另一种方法是使用findContours查找轮廓,然后使用drawContours填充轮廓。我更喜欢本文中描述的技术的简单性和速度。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值