[opencv]空洞填充算法

在Matlab下,使用imfill可以很容易的完成孔洞填充操作,感觉这是一个极为常用的方法,然而不知道为什么Opencv里面却没有集成这个函数。在网上查了好多关于Opencv下的孔洞填充方法,大部分使用轮廓查找方法去做的,但对于这种方法,总感觉不是特别好。之前了解过冈萨雷斯那本书上的孔洞填充算法,所以想着手重新写一个。这里借鉴了冈萨雷斯书上的集合运算方法(并不完全一样)

大致思路如下:

0, 设原图像为 A。

1, 首先A向外延展一到两个像素,并将值填充为背景色(0),标记为B。

2, 使用floodFill函数将B的大背景填充,填充值为前景色(255),种子点为(0,0)即可(步骤一可以确保(0,0)点位于大背景),标记为C。

3, 将填充好的图像裁剪为原图像大小(去掉延展区域),标记为D。

4, 将D取反与A相加即得填充的图像,E=A|(~D)。

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;

void fillHole(const Mat srcBw, Mat &dstBw)
{
    Size m_Size = srcBw.size();
    Mat Temp=Mat::zeros(m_Size.height+2,m_Size.width+2,srcBw.type());//延展图像
    srcBw.copyTo(Temp(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)));

    cv::floodFill(Temp, Point(0, 0), Scalar(255));

    Mat cutImg;//裁剪延展的图像
    Temp(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)).copyTo(cutImg);

    dstBw = srcBw | (~cutImg);
}

int main()
{
    Mat img=cv::imread("/home/leoxae/图片/test.png");

    Mat gray;
    cv::cvtColor(img, gray, COLOR_RGB2GRAY);

    Mat bw;
    cv::threshold(gray, bw, 0, 255, THRESH_BINARY | THRESH_OTSU);

    Mat bwFill;
    fillHole(bw, bwFill);

    imshow("填充前", gray);
    imshow("填充后", bwFill);
    waitKey();
    return 0;
}

运行结果:

原文地址:https://www.cnblogs.com/lx17746071609/p/11665816.html

时间: 2024-10-01 07:21:56

[opencv]空洞填充算法的相关文章

FloodFill填充算法

FloodFill填充算法利用的是一种广度搜索的方法,将处于设定灰度的像素点设置为新像素 一些伪代码http://en.wikipedia.org/wiki/Flood_fill openCV实现 #include <cv.h> #include <highgui.h> void main() { //以原始通道数读取图片1 IplImage* img1 = cvLoadImage("D://vc6.0//MSDev98//MyProjects//MachineVisio

种子填充算法

1 /************************************************************* 2 pb-图形学题4 3 种子填充算法 4 5 *************************************************************/ 6 7 8 #include <GL/glut.h> 9 #include<cstdio> 10 #include<cmath> 11 #include<stack

图形填充之栅栏填充算法

编译器:VS2013 该算法相对边缘填充算法莱说,效率较高来说,选取一个顶点的横坐标为栅栏,将直线和栅栏之间进行填充,如果颜色为背景色,则填充填充色,否则则填充背景色 代码: 1 // 栅栏填充算法.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include<stdio.h> 6 #include"graphics.h" 7 #include<stdlib.h> 8 9 //函数声

CGA填充算法之种子填充算法

CGA填充算法之种子填充算法 平面区域填充算法是计算机图形学领域的一个很重要的算法,区域填充即给出一个区域的边界 (也可以是没有边界,只是给出指定颜色),要求将边界范围内的所有象素单元都修改成指定的颜色(也可能是图案填充).区域填充中最常用的是多边形填色,本文讨论种子填充算法(Seed Filling)   如果要填充的区域是以图像元数据方式给出的,通常使用种子填充算法(Seed Filling)进行区域填充.种子填充算法需要给出图像数据的区域,以及区域内的一个点,这种算法比较适合人机交互方式进

图形填充之边缘填充算法

编译器:VS2013 基本思想: 基本思想:按任意顺序处理多边形的每条边.处理时,先求出该边与扫描线的交点,再对扫描线上交点右方的所有象素取补. 取补:若该像素是背景色,则变为填充色; 若像素是填充色,则变为背景色. 前言:刚开始接触这个算法时,一直不知道怎么找出直线上任意一点x,y的关系,困扰了很久,也和高中数学忘了差不多有关,只记得y=kx+b,然而这题使用 (y1-y0)/(x1-x0)=(y-y0)/(x-x0) 这样一来关系很明显表达出来,而且用k做的话会存在k不存在的情况,而这种做法

OpenCV使用Harris算法实现角点检测

纯粹阅读,请移步OpenCV使用Harris算法实现角点检测 效果图 源码 KqwOpenCVFeaturesDemo 角点是两条边缘的交点或者在局部邻域中有多个显著边缘方向的点.Harris角点检测是一种在角点检测中最常见的技术. Harris角点检测器在图像上使用滑动窗口计算亮度的变化. 封装 这里用到了RxJava.主要是因为图片处理是耗时操作,会阻塞线程,为了防止界面卡顿,这里使用RxJava进行了线程切换. /** * Harris角点检测 * * @param bitmap 要检测的

计算机图形学 - 扫描线种子填充算法

算法描述: 种子填充算法原理和程序都很简单, 但由于多次递归, 费时.费内存, 效率不高.为了减少递归次数, 提高效率可以采用扫描线种子填充算法.算法的基本过程如下: 当给定种子点( x, y) 时, 首先填充种子点所在扫描线上的位于给定区域的一个区段, 然后确定与这一区段相连通的上.下两条扫描线上位于给定区域内的区段, 并依次保存下来.反复这个过程, 直到填充结束. 区域填充的扫描线算法可由下列4 个步骤实现: ①  初始化: 堆栈置空.将种子点(x, y) 入栈. ② 出栈: 若栈空则结束.

java 在centos6.5+eclipse环境下调用opencv实现sift算法

java 在centos6.5+eclipse环境下调用opencv实现sift算法,代码如下: import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfKeyPoint; import org.opencv.highgui.Highgui; import org.opencv.features2d.*; public class ExtractSIFT{ public static

计算机图形学 有效边表填充算法(6)

作者:卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/40154077 本文通过一个完整的实例,展示多边形有效边表填充算法. 1)创建CAET类 头文件:AET.h // AET.h: interface for the CAET class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_AET_