前言:
由于遥感图像通常巨大,opencv自带的imread函数可能读取图像失败,所以用gdal库写个readTif函数;自带的floodfill函数运行会时间太久,所以也自己写叭。。。
先看一下需求:
算法流程:
1、以原图像的补集作为Mask,用来限制膨胀结果;
2、以带有白色边框的黑色图像为初始Marker,用SE对其进行连续膨胀,直至收敛;
3、最后对Marker取补即得到最终图像,与原图相减可得到填充图像。
python代码:
# -*- coding:utf-8 -*-
import numpy as np
import cv2
class kdtc():
def __init__(self):
pass
def readTif(self,fileName):
import gdal
dataset = gdal.Open(fileName)
if dataset == None:
print(fileName+"文件无法打开")
return
im_width = dataset.RasterXSize #栅格矩阵的列数
im_height = dataset.RasterYSize #栅格矩阵的行数
im_bands = dataset.RasterCount #波段数
im_data = dataset.ReadAsArray(0,0,im_width,im_height)#获取数据
im_geotrans = dataset.GetGeoTransform()#获取仿射矩阵信息
im_proj = dataset.GetProjection()#获取投影信息
im_blueBand = im_data[2,0:im_height,0:im_width]#获取蓝波段
im_greenBand = im_data[1,0:im_height,0:im_width]#获取绿波段
im_redBand = im_data[0,0:im_height,0:im_width]#获取红波段
#im_nirBand = im_data[3,0:im_height,0:im_width]#获取近红外波段
im_data = cv2.merge([im_blueBand, im_greenBand, im_redBand])
#print(type(im_data))
return im_data
def kongdongtianchong(self,img_name,TF=True):
img = self.readTif(img_name)
img = img[:, :, 0]
if TF:
se0 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (30, 30))
img = cv2.dilate(img, se0)
mask = 255 - img
# 构造Marker
#marker = np.zeros_like(img)
#marker[0, :] = 255
#marker[-1, :] = 255
#marker[:, 0] = 255
#marker[:, -1] = 255
#marker_0 = marker.copy()
# 构造Marker
SE=cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (50, 50))
marker=cv2.erode(mask,SE)
# 形态学重建
se = cv2.getStructuringElement(shape=cv2.MORPH_CROSS, ksize=(25, 25))
while True:
marker_pre = marker
dilation = cv2.dilate(marker, kernel=se)
marker = np.min((dilation, mask), axis=0)
if (marker_pre == marker).all():
break
dst = 255 - marker
dst=cv2.erode(dst,se0)
print('----------孔洞填充完成----------')
return dst
else:
return img