pyfusion.Brovery 源代码

import cv2
import numpy as np

from .utils import Image, ReadImageFile, GetOutputDriverFor

from osgeo import gdal, gdalconst

[文档]def BroveryByFilePath(srcpath:str, panpath:str, resultpath:str, driver:str): """Using Brovery method fusion image The output only support tif format :param srcpath: `source` image path :param panpath: Panchromatic image path :param resultpath: result image path :return: None :rtype: None """ Brovery(ReadImageFile(srcpath), ReadImageFile(panpath), None, resultpath, driver)
[文档]def Brovery(src:Image, pan:Image, block_size=None ,result_path=None, driver=None): """ Using Brovery method to fusion image The source image should not be upsampled :param src: `source` image, the image should be RGB color space :param pan: Panchromatic image, the image should be grayscale :param block_size: block_size :param result_path: result image path, it can be any format supported by gdal :param driver: gdal write driver :return: fusion image :rtype: `pyfusion.utils.Image` """ assert src.image.RasterCount == 3, "src image should be 3 bands" assert pan.image.RasterCount == 1, "pan image should be 1 band" if block_size is None: block_size = 4096 dstDs = None # if not result_path, it will store the result into memory if result_path is None: driver = gdal.GetDriverByName("MEM") dstDs = driver.Create("", pan.image.RasterXSize, pan.image.RasterYSize, 3, options=["INTERLEAVE=PIXEL"]) # if give result_path, it will write result into file elif driver is not None: driver = gdal.GetDriverByName(driver) dstDs = driver.Create(result_path, pan.image.RasterXSize, pan.image.RasterYSize, 3, options=["INTERLEAVE=PIXEL"]) else: driver = GetOutputDriverFor(result_path) dstDs = driver.Create(result_path, pan.image.RasterXSize, pan.image.RasterYSize, 3, options=["INTERLEAVE=PIXEL"]) dstDs.SetGeoTransform(pan.image.GetGeoTransform()) dstDs.SetProjection(pan.image.GetProjection()) dstDs.SetSpatialRef(pan.image.GetSpatialRef()) dstImage = Image(dstDs) xsize = dstImage.image.RasterXSize ysize = dstImage.image.RasterYSize x_blocks = xsize // block_size y_blocks = ysize // block_size if x_blocks == 0: x_blocks += 1 if y_blocks == 0: y_blocks += 1 x_size_true = (xsize // x_blocks) + 1 y_size_true = (ysize // y_blocks) + 1 x_rate, y_rate = src.image.RasterXSize/xsize, src.image.RasterYSize/ysize for i in range(x_blocks): for j in range(y_blocks): x_start, y_start = i*x_size_true, j*y_size_true x_end, y_end = i*x_size_true+x_size_true, j*y_size_true+y_size_true if x_end > xsize: x_end = xsize if y_end > ysize: y_end = ysize try: dstImage[y_start:y_end, x_start:x_end] = _Brovery(src[int(y_start*y_rate):int(y_end*y_rate), int(x_start*x_rate):int(x_end*x_rate)], pan[y_start:y_end, x_start:x_end]) except Exception as e: print(x_start, x_end, y_start, y_end) print(int(x_start*x_rate), int(x_end*x_rate), int(y_start*y_rate), int(y_end*y_rate)) print(i, j) print(x_blocks, y_blocks) print(x_size_true, y_size_true) print(xsize, ysize) raise e return dstImage
def _Brovery(src, pan): """ Using Brovery method to fusion image The source image should not be upsampled :param src: `source` image, the image should be RGB color space :param pan: Panchromatic image, the image should be grayscale :return: fusion image :rtype: `numpy.ndarray` """ img_bgr = cv2.resize(src, tuple(reversed(pan.shape))) if np.max(img_bgr) == 0: return np.zeros(img_bgr.shape ,dtype=np.uint8) pan = pan.astype(np.float32) r,g,b = cv2.split(img_bgr) b = b.astype(np.float32) g = g.astype(np.float32) r = r.astype(np.float32) rf = (3*pan)*r/(b+g+r) gf = (3*pan)*g/(b+g+r) bf = (3*pan)*b/(b+g+r) bf = bf.astype(np.uint8) gf = gf.astype(np.uint8) rf = rf.astype(np.uint8) img_brovery = cv2.merge((rf,gf,bf)) return img_brovery