2017-10-04 17:14:21 qq_30311601 阅读数 8717

(这里的二值为0和255)

二值图像的孔洞填充是基于图像形态学操作的基本运算,本文参考数字图像处理(冈萨雷斯著)相关章节的有关内容并结合作者自己的思考,给出了基于C# 二值图像孔洞填充的可行程序。

基础知识:参考数字图像处理 P402-P415

数学形态学的语言是集合论,这里所说的孔洞是二值图像内部八连通点阵组成的闭合圈内的像素点集,孔洞填充的基本步骤如下:
1.确定二值图像像素[0,0]为初始种子点,这里认为[0,0]像素点为背景点,而非某个孔洞内部的点。

2.以种子点为起点,采用形态学膨胀算法对背景进行填充。膨胀到不能膨胀为止。膨胀运算采用四连通结构元。

 

 


四连通结构元(即中心像素为种子,以四连通的方式向周围膨胀):

 

 

3.背景填充结束后,对得到的二值图像取反得到新的二值图像,此时图像为全部孔洞的点集。

4.将第三步骤得到的二值图像与原二值图像相加及得到孔洞填充的结果。

 

这样的算法对于大多数图像有效,然而对于[0,0]位置的像素,若为某孔洞内部的点则无法实现有效的孔洞填充。为了解决这一问题,这里采用拓展图像的方法,即在原图像的上下左右分别增加一行或一列数值为255的像素。使原图像尺寸由a*b 变为(a+2)*(b+2),以增加的四周全部像素或[0,0]处的像素为种子,对原图像进行膨胀运算。

结果如下:(图中未被填充“孔洞”是由于边缘未闭合)

         





2018-04-22 11:45:37 jkjj2015 阅读数 7243

      matlab中的imfill函数可以方便得实现二值图像的孔洞填充,而在opencv中并没有相同功能的函数。因此,在opencv的基础上编写实现孔洞填充的函数,并且能够设定阈值,对面积大于阈值的孔洞不进行填充。使用形态学重建的算法能够有效地实现孔洞填充,具体算法参照《数字图像处理》第三版9.5.9节,孔洞填充。

    主要实现代码如下所示:其中imfill函数即为空洞填充的实现函数,第一个参数是二值图像(0~1),第二个参数是填充孔洞的阈值。若孔洞面积大于阈值则不填充,反之则填充。

#include "iostream"
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
Mat inv_board(Mat src);
Mat inv_img(Mat src);
void delarea(Mat& bw, int max);
Mat imfill(Mat I, int max);
void main()
{
	Mat scr = imread("2.png");
	Mat I, src_gray, F_B, F_BI_C, temp, H, I_fill;
	cvtColor(scr, src_gray, COLOR_BGR2GRAY);
	threshold(src_gray, I, 0.1, 1,0);
	I_fill = imfill(I,40);
	imshow("原二值图", I * 255);
	imshow("填充图", I_fill*255);
	waitKey(0);
}


Mat imfill(Mat I,int max)
{
	Mat  src_gray, F_B, F_BI_C, temp, H, I_fill;
	I_fill = I.clone();
	Mat F = inv_board(I);
	Mat I_C = inv_img(I);
	Mat element = getStructuringElement(0, Size(3, 3), Point(1, 1));
	while (1)
	{


		dilate(F, F_B, element);
		F_BI_C = F_B.mul(I_C);
		temp = F_BI_C - F;
		if (sum(temp) == Scalar(0))
			break;
		else
			F = F_BI_C.clone();
	}
	H = inv_img(F_BI_C);
	Mat H_IC = H.mul(I_C);
	delarea(H_IC, max);
	for (int i = 0; i < H_IC.rows; i++)
	{
		for (int j = 0; j < H_IC.cols; j++)
		{
			if (H_IC.at<uchar>(i, j) == 1)
				I_fill.at<uchar>(i, j) = 1;
		}
	}
	return I_fill;
}
Mat inv_board(Mat src)
{
	
	int rows = src.rows;
	int cols = src.cols;
	Mat dst = Mat::zeros(rows, cols, CV_8UC1);
	for (int i = 0; i < cols; i++)
	{
		dst.at<uchar>(0, i) = 1 - src.at<uchar>(0, i);
	}
	for (int i = 0; i < cols; i++)
	{
		dst.at<uchar>(rows-1, i) = 1 - src.at<uchar>(rows - 1, i);
	}
	for (int i = 1; i < rows-1; i++)
	{
		dst.at<uchar>(i, 0) = 1 - src.at<uchar>(i, 0);
	}
	for (int i = 1; i < rows - 1; i++)
	{
		dst.at<uchar>(i, cols-1) = 1 - src.at<uchar>(i, cols-1);
	}
	return dst;
}


Mat inv_img(Mat src)
{
	int rows = src.rows;
	int cols = src.cols;
	Mat dst = src.clone();
	for (int i = 0; i < rows; i++)
		for (int j = 0; j < cols; j++)
			dst.at<uchar>(i, j) = 1 - src.at<uchar>(i, j);
	return dst;
}


void delarea(Mat& bw, int max )
{
	Mat bw_copy = bw.clone();
	int flag = 0; 
	Mat H_b, H_bw, temp;
	Mat H = Mat::zeros(bw.size(), bw.type());
	for (int i = 0; i < bw.rows; i++)
	{
		for (int j = 0; j < bw.cols; j++)
		{
			if (bw_copy.at<uchar>(i, j) == 1)
			{
				H.at<uchar>(i, j) = 1;
	Mat element = getStructuringElement(0, Size(3, 3), Point(1, 1));
	while (1)
	{
		dilate(H, H_b, element); 
		H_bw = H_b.mul(bw);
		temp = H_bw - H;
		if (sum(temp) == Scalar(0))
			break;
		else
			H = H_bw.clone();
	}
	bw_copy = bw_copy - H_bw;
    if (sum(H_bw).val[0] > max)
	{
		bw = bw - H_bw;
	}
	H = Mat::zeros(bw.size(), bw.type());
			}
			
		}
	}
}


2018-02-02 16:56:10 u014030821 阅读数 2406

第九章 形态学图像处理

形态学图像处理 将数学形态学作为工具从图像中提取表达和描绘区域形状的有用图像分量,如边界、骨架和凸壳等。最常见的有腐蚀和膨胀、开操作和闭操作、击中和击不中变换。本章一开始将讨论 二值图像 的处理,之后将扩展到 灰度图像

一:腐蚀和膨胀

1.1 腐蚀

B对A的腐蚀是一个用z平移的B包含在A中的所有的点z的集合:
这里写图片描述
这里写图片描述
这里写图片描述
腐蚀缩小或细化了二值图像中的物体,可以将腐蚀视为形态学滤波操作,这种操作将小于结构元的图像细节从图像中滤除(去除)。

1.2 膨胀

膨胀的定义为:
这里写图片描述
这里写图片描述
这里写图片描述
最简单的膨胀应用之一是连接裂缝。

膨胀和腐蚀彼此关于集合求补运算和反射运算是对偶的。

二:开操作与闭操作

膨胀会扩大一幅图像的组成部分,而腐蚀会缩小一幅图像中的组成部分。开操作一般会平滑物体的轮廓、断开较窄的狭颈并消除较细的突出物。闭操作同样也会平滑轮廓的一部分,但与开操作相反,它通常会弥合较窄的间断和细长的沟壑,消除较小的孔径,填补轮廓线中的断裂。
这里写图片描述
这里写图片描述
这里写图片描述

开操作和闭操作彼此关于集合求补和反射也是对偶的。

三:击中或击不中变换

形态学击中或击不中变换是形状检测的基本工具。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

四:一些基本的形态学算法

4.1 边界提取

表示为B(A)的集合A的边界可以通过先用B对A腐蚀,而后执行A和腐蚀的结果之间的差集得到:
这里写图片描述
这里写图片描述
这里写图片描述

4.2 孔洞填充

孔洞定义为由前景像素连接的边界所包围的背景区域。
这里写图片描述
这里写图片描述

4.3 连通分量的提取

这里写图片描述
这里写图片描述

4.4 凸壳

这里写图片描述

4.5 细化

这里写图片描述

4.6 粗化

这里写图片描述

4.7 骨架

这里写图片描述
这里写图片描述

4.8 裁剪

裁剪方法本质上是对细化和骨架算法的补充,因为这些过程会保留某些寄生部分,因而需要用后处理来清除这些寄生部分。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

4.9 形态学重建

形态学重建涉及两幅图像和一个结构元。一幅图像是标记,它包含变换的起始点,另一个图像是模板,它用来约束该变换。

4.9.1 测地膨胀和腐蚀

形态学重建的核心是测地腐蚀和测地膨胀。
测地膨胀以及F关于G的大小为n的测地膨胀定义为:
这里写图片描述
这里写图片描述
测地腐蚀以及F关于G的大小为n的测地腐蚀定义为:
这里写图片描述
这里写图片描述

4.9.2 用膨胀和腐蚀的形态学重建

这里写图片描述
迭代k次,直至:
这里写图片描述

五:灰度级形态学

将之前的形态学讨论从二值图像处理扩展到灰度级图像。

5.1 腐蚀和膨胀

腐蚀和膨胀:
这里写图片描述
这里写图片描述
非平坦结构元bN对图像的腐蚀和膨胀:
这里写图片描述
这里写图片描述

如二值情况那样,腐蚀和膨胀是关于函数的补集和反射对偶的。

5.2 开操作和闭操作

这里写图片描述
这里写图片描述

5.3 一些基本的灰度级形态学算法

5.3.1 形态学平滑

这里写图片描述

5.3.2 形态学梯度

这里写图片描述
这里写图片描述

5.3.3 顶帽变换和底帽变换

这里写图片描述
这里写图片描述
这里写图片描述

5.3.4 粒度测定

这里写图片描述

5.3.5 纹理分割

这里写图片描述

5.4 灰度级形态学重建

与二值图像的重建基本类似。测地膨胀和测地腐蚀:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

2019-04-23 10:31:08 weixin_42181588 阅读数 840

我们在进行图像分割后,分割图像结果有时会有一些小孔洞,如下图所示。今天我们就用python语言基于OpenCV实现孔洞填充。
有孔洞的分割图像
代码实现:

import cv2;
import numpy as np;

'''
图像说明:
图像为二值化图像,255白色为目标物,0黑色为背景
要填充白色目标物中的黑色空洞
'''
def FillHole(imgPath,SavePath):
    im_in = cv2.imread(imgPath, cv2.IMREAD_GRAYSCALE);

    # 复制 im_in 图像
    im_floodfill = im_in.copy()
    
    # Mask 用于 floodFill,官方要求长宽+2
    h, w = im_in.shape[:2]
    mask = np.zeros((h+2, w+2), np.uint8)
    
    # floodFill函数中的seedPoint必须是背景
    isbreak = False
    for i in range(im_floodfill.shape[0]):
        for j in range(im_floodfill.shape[1]):
            if(im_floodfill[i][j]==0):
                seedPoint=(i,j)
                isbreak = True
                break
        if(isbreak):
            break
    # 得到im_floodfill
    cv2.floodFill(im_floodfill, mask, seedPoint, 255);

    # 得到im_floodfill的逆im_floodfill_inv
    im_floodfill_inv = cv2.bitwise_not(im_floodfill)
    # 把im_in、im_floodfill_inv这两幅图像结合起来得到前景
    im_out = im_in | im_floodfill_inv
     
    # 保存结果
    cv2.imwrite(SavePath, im_out)
    

孔洞填充结果如下:
孔洞填充结果图像

附:rgb图像填充孔洞
https://blog.csdn.net/weixin_42181588/article/details/89467590

图像处理步骤

阅读数 49

没有更多推荐了,返回首页