去除NoData参考链接:https://stackoverflow.com/questions/20753288/filling-gaps-on-an-image-using-numpy-and-scipy
图像增强参考链接:https://stackoverflow.com/questions/20753288/filling-gaps-on-an-image-using-numpy-and-scipy
代码还是要改一些的,我把做好的放出来大家参考下
1.去除NoData
第二种方法比较慢
import cv2
import gdal
import scipy.interpolate
import numpy as np
def read_img(filename):
dataset=gdal.Open(filename)
im_width = dataset.RasterXSize
im_height = dataset.RasterYSize
im_geotrans = dataset.GetGeoTransform()
im_proj = dataset.GetProjection()
im_data = dataset.ReadAsArray(0,0,im_width,im_height)
del dataset
return im_proj,im_geotrans,im_width, im_height,im_data
def write_img(filename, im_proj, im_geotrans, im_data):
if 'int8' in im_data.dtype.name:
datatype = gdal.GDT_Byte
elif 'int16' in im_data.dtype.name:
datatype = gdal.GDT_UInt16
else:
datatype = gdal.GDT_Float32
if len(im_data.shape) == 3:
im_bands, im_height, im_width = im_data.shape
else:
im_bands, (im_height, im_width) = 1,im_data.shape
driver = gdal.GetDriverByName("GTiff")
dataset = driver.Create(filename, im_width, im_height, im_bands, datatype)
dataset.SetGeoTransform(im_geotrans)
dataset.SetProjection(im_proj)
if im_bands == 1:
dataset.GetRasterBand(1).WriteArray(im_data)
else:
for i in range(im_bands):
dataset.GetRasterBand(i+1).WriteArray(im_data[i])
del dataset
def NoData_kill(in_path, out_path):
# data = cv2.imread("cq_test.tif")
im_proj,im_geotrans,im_width, im_height,im_data = read_img(in_path)
mask = np.isnan(im_data)
c, w, h = mask.shape
mask_list = []
for i in range(c):
if mask[i].__contains__(True):
mask_list.append(mask[i])
for m in mask_list:
m = m + 0
m = np.uint8(m)
inpainted_img = cv2.inpaint(im_data, m, inpaintRadius=3, flags=cv2.INPAINT_TELEA)
im_data = inpainted_img
# cv2.imwrite('./fixed2.tif', data)
write_img(out_path, im_proj, im_geotrans, im_data)
#too slow
def NoData_kill2(in_path, out_path):
im_proj,im_geotrans,im_width, im_height, data = read_img(in_path)
data = data.transpose(2,1,0)
# a boolean array of (width, height) which False where there are missing values and True where there are valid (non-missing) values
mask = ~( (data[:,:,0] == 255) & (data[:,:,1] == 255) & (data[:,:,2] == 255) )
# array of (number of points, 2) containing the x,y coordinates of the valid values only
xx, yy = np.meshgrid(np.arange(data.shape[1]), np.arange(data.shape[0]))
xym = np.vstack( (np.ravel(xx[mask]), np.ravel(yy[mask])) ).T
# the valid values in the first, second, third color channel, as 1D arrays (in the same order as their coordinates in xym)
data0 = np.ravel( data[:,:,0][mask] )
data1 = np.ravel( data[:,:,1][mask] )
data2 = np.ravel( data[:,:,2][mask] )
# three separate interpolators for the separate color channels
interp0 = scipy.interpolate.NearestNDInterpolator( xym, data0 )
interp1 = scipy.interpolate.NearestNDInterpolator( xym, data1 )
interp2 = scipy.interpolate.NearestNDInterpolator( xym, data2 )
# interpolate the whole image, one color channel at a time
result0 = interp0(np.ravel(xx), np.ravel(yy)).reshape( xx.shape )
result1 = interp1(np.ravel(xx), np.ravel(yy)).reshape( xx.shape )
result2 = interp2(np.ravel(xx), np.ravel(yy)).reshape( xx.shape )
# combine them into an output image
result = np.dstack( (result0, result1, result2) )
result = result.transpose(2,1,0)
write_img(out_path, im_proj, im_geotrans, result)
if __name__ == "__main__":
in_path = 'cq_test.tif'
out_path = './fixed.tif'
NoData_kill(in_path, out_path)
放大看
2.遥感图像增强
import cv2
import gdal
import numpy as np
from PIL import Image, ImageEnhance
import matplotlib.pyplot as plt
def read_img(filename):
dataset=gdal.Open(filename)
im_width = dataset.RasterXSize
im_height = dataset.RasterYSize
im_geotrans = dataset.GetGeoTransform()
im_proj = dataset.GetProjection()
im_data = dataset.ReadAsArray(0,0,im_width,im_height)
del dataset
return im_proj,im_geotrans,im_width, im_height,im_data
def write_img(filename, im_proj, im_geotrans, im_data):
if 'int8' in im_data.dtype.name:
datatype = gdal.GDT_Byte
elif 'int16' in im_data.dtype.name:
datatype = gdal.GDT_UInt16
else:
datatype = gdal.GDT_Float32
if len(im_data.shape) == 3:
im_bands, im_height, im_width = im_data.shape
else:
im_bands, (im_height, im_width) = 1,im_data.shape
driver = gdal.GetDriverByName("GTiff")
dataset = driver.Create(filename, im_width, im_height, im_bands, datatype)
dataset.SetGeoTransform(im_geotrans)
dataset.SetProjection(im_proj)
if im_bands == 1:
dataset.GetRasterBand(1).WriteArray(im_data)
else:
for i in range(im_bands):
dataset.GetRasterBand(i+1).WriteArray(im_data[i])
del dataset
def deaw_gray_hist(gray_img):
'''
:param gray_img大小为[h, w]灰度图像
绘制直方图
'''
# 获取图像大小
h, w = gray_img.shape
gray_hist = np.zeros([256])
for i in range(h):
for j in range(w):
gray_hist[gray_img[i][j]] += 1
x = np.arange(256)
# 绘制灰度直方图
plt.bar(x, gray_hist)
plt.xlabel("gray Label")
plt.ylabel("number of pixels")
plt.show()
def im_enhance(in_path,out_path):
'''
图像锐化
'''
im_proj,im_geotrans,im_width, im_height,im_data = read_img(in_path)
im_data = im_data.transpose(2,1,0)
im_data = Image.fromarray(im_data)
enhancer = ImageEnhance.Sharpness(im_data)
enhanced_im = enhancer.enhance(100.0)
enhanced_im = np.array(enhanced_im)
enhanced_im = enhanced_im.transpose(2,1,0)
write_img(out_path, im_proj, im_geotrans, enhanced_im)
def linear_transform(in_path, a, b, out_path):
'''
# 对图像进行 线性变换
:param img: [h, w, 3] 彩色图像
:param a: float 这里需要是浮点数,把图片uint8类型的数据强制转成float64
:param b: float
:return: out = a * img + b
'''
im_proj,im_geotrans,im_width, im_height,im_data = read_img(in_path)
out = a * im_data + b
out[out > 255] = 255
out = np.around(out)
out = out.astype(np.uint8)
write_img(out_path, im_proj, im_geotrans, out)
def normalize_transform(in_path, out_path):
'''
直方图正规化
cv2.normalize(src,dst,alpha,beta,normType,dtype,mask)
参数:
src: 图像对象矩阵
dst:输出图像矩阵(和src的shape一样)
alpha:正规化的值,如果是范围值,为范围的下限 (alpha – norm value to normalize to or the lower range boundary in case of the range normalization.)
beta:如果是范围值,为范围的上限;正规化中不用到 ( upper range boundary in case of the range normalization; it is not used for the norm normalization.)
norm_type:normalize的类型
cv2.NORM_L1:将像素矩阵的1-范数做为最大值(矩阵中值的绝对值的和)
cv2.NORM_L2:将像素矩阵的2-范数做为最大值(矩阵中值的平方和的开方)
cv2.NORM_MINMAX:将像素矩阵的∞-范数做为最大值 (矩阵中值的绝对值的最大值)
dtype: 输出图像矩阵的数据类型,默认为-1,即和src一样
mask:掩模矩阵,只对感兴趣的地方归一化
'''
im_proj,im_geotrans,im_width, im_height,im_data = read_img(in_path)
c, h, w = im_data.shape
arr_list = []
for i in range(c):
Imin, Imax = cv2.minMaxLoc(im_data[i])[:2]
Omin, Omax = 0, 255
a = float(Omax - Omin) / (Imax - Imin)
b = Omin - a * Imin
out = a * im_data[i] + b
out = out.astype(np.uint8)
arr_list.append(np.expand_dims(out,axis=0))
temp = np.zeros_like(im_data)
for i in range(c-1):
temp[i] = arr_list[i]
nor_out = temp
write_img(out_path, im_proj, im_geotrans, nor_out)
def equalize_transfrom(in_path, out_path):
'''
全局直方图均衡化
cv2.equalizeHist(src,dst)
src: 图像对象矩阵,必须为单通道的uint8类型的矩阵数据
dst:输出图像矩阵(和src的shape一样)
'''
im_proj,im_geotrans,im_width,im_height,im_data = read_img(in_path)
c, h, w = im_data.shape
temp = np.zeros_like(im_data)
for i in range(c):
temp[i] = cv2.equalizeHist(im_data[i])
write_img(out_path, im_proj, im_geotrans, temp)
def restrict_hist(in_path, out_path):
'''
clahe=cv2.createCLAHE(clipLimit,tileGridSize)
clipLimit:限制对比度的阈值,默认为40,直方图中像素值出现次数大于该阈值,多余的次数会被重新分配
tileGridSize:图像会被划分的size, 如tileGridSize=(8,8),默认为(8,8)
calhe.apply(img) #对img进行限制对比度自适应直方图均衡化
'''
im_proj,im_geotrans,im_width,im_height,im_data = read_img(in_path)
c, h, w = im_data.shape
temp = np.zeros_like(im_data)
for i in range(c):
clahe = cv2.createCLAHE(3,(8,8))
temp[i] = clahe.apply(im_data[i])
write_img(out_path, im_proj, im_geotrans, temp)
def gamma_trans(in_path, out_path):
'''
伽马变换
'''
im_proj,im_geotrans,im_width,im_height,im_data = read_img(in_path)
img_norm = im_data/255.0 #注意255.0得采用浮点数
img_gamma = np.power(img_norm,0.4)*255.0
img_gamma = img_gamma.astype(np.uint8)
write_img(out_path, im_proj, im_geotrans, img_gamma)
if __name__ == "__main__":
in_path = './fixed2.tif'
# out_path = './enhance2.tif'
# linear_transform(in_path, 2.0, 10.0, out_path)
# out_path = './enhance3.tif'
# normalize_transform(in_path, out_path)
# out_path = './enhance4.tif'
# equalize_transfrom(in_path, out_path)
# out_path = './enhance5.tif'
# restrict_hist(in_path, out_path)
out_path = './enhance6.tif'
gamma_trans(in_path, out_path)
线性拉伸增强
直方图正规化
直方图均衡化
限制对比度自适应直方图均衡化
伽马变换
注意:如果影像太大,可以滑框做,毕竟遥感都是大影像,滑框做的时候最好选择能兼顾全局的方法