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

请注意,硬币的边界是黑色的,与白色背景不同。因此,我们使用简单的图像阈值来将边界与背景分开。换句话说,我们说强度高于某个值(阈值)的像素是背景,其余像素是前景。上图中间图像显示通过阈值分割获得图像(黑色代表背景,白色代表前景)。不幸的是,即使边界被很好地提取(它是纯白色),硬币的内部也具有与背景类似的强度。因此,阈值操作不能将其与背景分开。我们如何用白色填充圆形边界内的所有像素?然后将其分开。

1 imfill in OpenCV

MATLAB有一个名为imfill的函数 ,可以让你填充孔洞。OpenCV中没有imfill功能,但我们肯定可以写一个!我们知道像素点(0,0)连接到背景。因此,我们可以通过从像素(0,0)执行填充操作来提取背景。不受漫水填充操作影响的像素必然位于边界内。阈值图像与漫水填充图像或非运算后图像为前景掩模!

漫水填充算法是用来标记一片区域的:设置一个种子点,然后种子点附近的相似点都被填充同一种颜色。该算法应用性很广,比如目标识别,photoshop 的魔术棒功能等等,是填充类算法中应用最为广泛的一个算法。漫水填充也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或者只处理掩码指定的像素点。其中掩膜Mask用于进一步控制那些区域将被填充颜色。漫水填充在OpenCV中通过floodfill函数实现,具体见:

https://blog.csdn.net/qq_37385726/article/details/82313004

在OpenCV中实现imfill结果类似下图,步骤如下:

1)读取图像,并转换为灰度图像,如下图1所示;

2)对输入图像进行阈值分割以获得二值图像,如下图2所示;

3)对于阈值分割后的图像进行漫水填充,从像素(0,0)填充颜色。请注意,步骤2和步骤3的输出之间的差异在于步骤3中的背景现在是白色的,如下图3所示。

4)反转漫水填充后的图像(即黑色变为白色,白色变为黑色),如下图4所示。

5)使用按位OR运算将阈值图像与反向漫水填充图像组合以获得填充有孔的最终前景掩模。步骤4中的图像在边界内具有一些黑色区域。根据设计,步骤2中的图像填充了这些孔。因此,我们将两者结合起来获得掩模,如下图5所示。

2 完整代码

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

本文所有代码见:

https://github.com/luohenyueji/OpenCV-Practical-Exercise

C++:

#include "pch.h"
#include <opencv2/opencv.hpp> using namespace cv; int main()
{
// Read image 读取图像
Mat im_in = imread("./image/nickel.jpg", 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) 以点(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);
return 0;
}

python:

#!/usr/bin/env python

import cv2;
import numpy as np; # Read image
im_in = cv2.imread("./image/nickel.jpg", cv2.IMREAD_GRAYSCALE); # Threshold.
# Set values equal to or above 220 to 0.
# Set values below 220 to 255. th, im_th = cv2.threshold(im_in, 220, 255, cv2.THRESH_BINARY_INV); # Copy the thresholded image.
im_floodfill = im_th.copy() # Mask used to flood filling.
# Notice the size needs to be 2 pixels than the image.
h, w = im_th.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8) # Floodfill from point (0, 0)
cv2.floodFill(im_floodfill, mask, (0,0), 255); # Invert floodfilled image
im_floodfill_inv = cv2.bitwise_not(im_floodfill) # Combine the two images to get the foreground.
im_out = im_th | im_floodfill_inv # Display images.
cv2.imshow("Thresholded Image", im_th)
cv2.imshow("Floodfilled Image", im_floodfill)
cv2.imshow("Inverted Floodfilled Image", im_floodfill_inv)
cv2.imshow("Foreground", im_out)
cv2.waitKey(0)

3 参考

https://www.learnopencv.com/filling-holes-in-an-image-using-opencv-python-c/

[OpenCV实战]30 使用OpenCV实现图像孔洞填充的更多相关文章

  1. [OpenCV实战]45 基于OpenCV实现图像哈希算法

    目前有许多算法来衡量两幅图像的相似性,本文主要介绍在工程领域最常用的图像相似性算法评价算法:图像哈希算法(img hash).图像哈希算法通过获取图像的哈希值并比较两幅图像的哈希值的汉明距离来衡量两幅 ...

  2. [OpenCV实战]44 使用OpenCV进行图像超分放大

    图像超分辨率(Image Super Resolution)是指从低分辨率图像或图像序列得到高分辨率图像.图像超分辨率是计算机视觉领域中一个非常重要的研究问题,广泛应用于医学图像分析.生物识别.视频监 ...

  3. [OpenCV实战]20 使用OpenCV实现基于增强相关系数最大化的图像对齐

    目录 1 背景 1.1 彩色摄影的一个简短而不完整的历史 1.2 OpenCV中的运动模型 2 使用增强相关系数最大化(ECC)的图像对齐 2.1 findTransformECC在OpenCV中的示 ...

  4. [OpenCV实战]46 在OpenCV下应用图像强度变换实现图像对比度均衡

    本文主要介绍基于图像强度变换算法来实现图像对比度均衡.通过图像对比度均衡能够抑制图像中的无效信息,使图像转换为更符合计算机或人处理分析的形式,以提高图像的视觉价值和使用价值.本文主要通过OpenCV ...

  5. [OpenCV实战]50 用OpenCV制作低成本立体相机

    本文主要讲述利用OpenCV制作低成本立体相机以及如何使用OpenCV创建3D视频,准确来说是模仿双目立体相机,我们通常说立体相机一般是指双目立体相机,就是带两个摄像头的那种(目就是指眼睛,双目就是两 ...

  6. [OpenCV实战]29 使用OpenCV实现红眼自动去除

    目录 1 红眼消除 1.1 眼部检测 1.2 红眼遮掩 1.3 清除瞳孔掩模空洞 1.4 红眼修复 2 结果与完整代码 2.1 结果 2.2 代码 3 参考 在本教程中,我们将学习如何完全自动地从照片 ...

  7. [OpenCV实战]48 基于OpenCV实现图像质量评价

    本文主要介绍基于OpenCV contrib中的quality模块实现图像质量评价.图像质量评估Image Quality Analysis简称IQA,主要通过数学度量方法来评价图像质量的好坏. 本文 ...

  8. [OpenCV实战]47 基于OpenCV实现视觉显著性检测

    人类具有一种视觉注意机制,即当面对一个场景时,会选择性地忽略不感兴趣的区域,聚焦于感兴趣的区域.这些感兴趣的区域称为显著性区域.视觉显著性检测(Visual Saliency Detection,VS ...

  9. [OpenCV实战]19 使用OpenCV实现基于特征的图像对齐

    目录 1 背景 1.1 什么是图像对齐或图像对准? 1.2 图像对齐的应用 1.3 图像对齐基础理论 1.4 如何找到对应点 2 OpenCV的图像对齐 2.1 基于特征的图像对齐的步骤 2.2 代码 ...

随机推荐

  1. 学习ASP.NET Core Blazor编程系列六——初始化数据

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  2. 【博学谷学习记录】超强总结,用心分享|Linux修改文件权限方法总结

    一.介绍 linux中"一切皆文件".每个文件都设定了针对不同用户的访问权限. 文件权限主要针对以下三种对象: 属主:拥有者 属组:所属的组 其他人:不属于上述两类 二.文件权限 ...

  3. 微信电脑版DAT文件转图片工具

    一键批量将微信聊天接受到的加密存储DAT图片文件转化为普通图片. 通过查看转化后的图片,您可以: (1)清理无用的历史图片,节省电脑硬盘存储空间. (2)恢复寻找重要照片资料. 下载地址:点此下载 微 ...

  4. Invalid bound statement (not found)出现原因和解决方法

    Invalid bound statement (not found)出现原因和解决方法 前言: 想必各位小伙伴在码路上经常会碰到奇奇怪怪的事情,比如出现Invalid bound statement ...

  5. 2022-08-05-欢迎使用_Typecho

    layout: post cid: 1 title: 欢迎使用 Typecho slug: start date: 2022/08/05 14:21:51 updated: 2022/08/05 14 ...

  6. Ubuntu 下安装 redis 并且设置远程登陆和密码

    安装redis sudo apt-get install -y redis-server 更改配置 sudo vim /etc/redis/redis.conf 如果不知道怎么找 直接在命令行模式下输 ...

  7. 华为开发者大会HDC2022:HMS Core 持续创新,与开发者共创美好数智生活

    11月4日,华为开发者大会HDC2022在东莞松山湖拉开帷幕.HMS Core在本次大会上带来了包括音频编辑服务的高拟真歌声合成技术.视频编辑服务的智能提取精彩瞬间功能.3D Engine超大规模数字 ...

  8. 这是不是你想要了解SQL的艺术,基础语法等等

    一.基础sql语句: 模块定义 基础语句 基础功能 数据定义 create table 创建数据库表 drop table 删除数据表 alter table 修改表结构 create view 创建 ...

  9. Dockerfile 使用 SSH docker build

    如果在书写 Dockerfile 时,有些命令需要使用到 SSH 连接,比如从私有仓库下载文件等,那么我们应该怎么做呢? Dockerfile 文件配置 为了使得 Dockerfile 文件中的命令可 ...

  10. PEP8语法规范解释说明

    PEP8规范解析 内容概要: 1.PEP8规范是什么? 2.PEP8相关内容 1.PEP8规范是什么 PEP是Python Enhancement Proposal的缩写,翻译为:"Pyth ...