HSV遥感图像融合方法+Python代码

    技术2026-02-05  3

    HSV图像融合方法+Python实现

    1、方法原理

    一般图像是有RGB三色通道进行展示的,也就是我们通常认为的红色、绿色、蓝色;

    而HSV不同的是,H是色相(hue),在HSV三维中起到了改变颜色的作用,它是将红,黄,绿,青,蓝,品红6种颜色均匀放在一条直线上,然后对这条直线采用线性插值,就能表示出色相了;

    S是饱和度,色彩的饱和度(saturation)指色彩的鲜艳程度,也称作纯度,S越高颜色掺杂的白色越少;

    V是明度(Value),又称为色彩的亮度。不同颜色会有明暗的差异,相同颜色也有明暗深浅的变化;

    图像融合一般意义上是将高分全色影像和低分RGB影像融合,由此得到高分的彩色影像,而HSV图像融合是将两个影像转换为HSV格式后,用高分影像的V分段替换低分影像的V分段,在逆变换为RGB格式,得到融合后图像。

    RGB->HSV色彩变换有具体的公式: 

                                                                             

                                                                 

                                                                                                

                                                        

                                                                           

                                                                                          

    HSV->RGB公式:

                                                                                      

                                 

                                                                           

    2、代码

    def rgb2hsv(r,g,b): """ RGB转HSV格式 输入:R,G,B np.ndArray格式二维数组 返回:H,S,V np.ndArray格式二维数组 """ h = r.shape[0] w = r.shape[1] H = np.zeros((h, w)) S = np.zeros((h, w)) V = np.zeros((h, w)) r, g, b = r/255.0, g/255.0, b/255.0 for i in range(0, h): for j in range(0, w): mx = max((b[i, j], g[i, j], r[i, j])) mn = min((b[i, j], g[i, j], r[i, j])) dt = mx-mn #H if mx == mn: H[i, j] = 0 elif mx == r[i, j]: if g[i, j] >= b[i, j]: H[i, j] = 60 * (g[i, j] - b[i, j]) / dt else: H[i, j] = 60 * (g[i, j] - b[i, j]) / dt + 360 elif mx == g[i, j]: H[i, j] = 60 * (b[i, j] - r[i, j]) / dt + 120 elif mx == b[i, j]: H[i, j] = 60 * (r[i, j] - g[i, j]) / dt + 240 #S if mx == 0: S[i, j] = 0 else: S[i, j] = dt / mx #V V[i, j] = mx return H, S, V

     

    def hsv2rgb(h, s, v): """ HSV转RGB格式 输入:H,S,V np.ndArray格式二维数组 返回:R,G,B np.ndArray格式二维数组 """ col , row = h.shape[0] , h.shape[1] hi = h / 60.0 hif = hi.astype(np.int) % 6 f = hi - hif p = v * (1 - s) q = v * (1 - f * s) t = v * (1 - (1 - f) * s) r, g, b = np.zeros((col,row)) , np.zeros((col,row)) , np.zeros((col,row)) for i in range(0,col): for j in range(0,row): if hif[i,j] == 0: r[i,j] , g[i,j] , b[i,j] = v[i,j] , t[i,j] , p[i,j] elif hif[i,j] == 1: r[i,j] , g[i,j] , b[i,j] = q[i,j] , v[i,j] , p[i,j] elif hif[i,j] == 2: r[i,j] , g[i,j] , b[i,j] = p[i,j] , v[i,j] , t[i,j] elif hif[i,j] == 3: r[i,j] , g[i,j] , b[i,j] = p[i,j] , q[i,j] , v[i,j] elif hif[i,j] == 4: r[i,j] , g[i,j] , b[i,j] = t[i,j] , p[i,j] , v[i,j] elif hif[i,j] == 5: r[i,j] , g[i,j] , b[i,j] = v[i,j] , p[i,j] , q[i,j] return r, g, b

     

    def rgb2utf8(rgb): """ 转换数据格式为utf-8 输入:numpyArray格式三维数组 返回:utf-8格式可出图三维数组 """ min_val = np.min(rgb.ravel()) max_val = np.max(rgb.ravel()) RGB = np.uint8((rgb.astype(np.float) - min_val) / (max_val - min_val) * 255) return RGB

    下面是总的执行代码:

    def HSV(data_low,data_high): """ 将色彩空间RGB转为HSV,H色调,S饱和度,V明度 输入:np.ndArray格式的三维数组np.array((3,h,w)) 返回:可绘出图像的utf-8格式的三维数组 """ min_val = np.min(data_low.ravel()) max_val = np.max(data_low.ravel()) data_low = np.uint8((data_low.astype(np.float) - min_val) / (max_val - min_val) * 255) H_low , S_low , V_low = rgb2hsv(data_low[0],data_low[1],data_low[2]) H_high ,S_high , V_high = rgb2hsv(data_high[0],data_high[1],data_high[2]) R,G,B = hsv2rgb(H_low,S_low,V_high) R = rgb2utf8(R) G = rgb2utf8(G) B = rgb2utf8(B) merged = cv2.merge([R,G,B]) RGB = Image.fromarray(merged) return RGB

    如果需要运用公式进行图像融合,自己按照公式进行代码撰写当然是能浅显易懂的,但是由于冗长的循环迭代,导致整个代码的时间复杂度较高。如果遥感数据的尺寸再大些,可能需要运行很长一段时间。于是可以考虑使用opencv中的cv2.cvtColor函数进行RGB->HSV与HSV->RGB的变换。

    3、opencv库cv2.cvtColor函数

    # coding=utf-8 ''' Created on 2020-6-1 @author: jiangao Project: HSV图像融合方法 ''' import numpy as np import cv2 import scipy.misc as smi from PIL import Image from osgeo import gdal def HSV(data_low,data_high): """ 使用opencv将色彩空间RGB转为HSV,H色调,S饱和度,V明度 输入:图像三维数组 返回:可绘出图像的utf-8格式的三维数组 """ h_low , s_low , v_low = cv2.split( cv2.cvtColor( data_low,cv2.COLOR_BGR2HSV ) ) h_high , s_high , v_high = cv2.split( cv2.cvtColor( data_high,cv2.COLOR_BGR2HSV ) ) #用高分影像的V替换低分影像的V HSV = cv2.merge([h_low,s_low,v_high]) RGB = Image.fromarray( cv2.cvtColor( HSV,cv2.COLOR_HSV2RGB ) ) return RGB def main(path_low,path_high): data_low = cv2.imread(path_low) data_high = cv2.imread(path_high) h,w = data_high.shape[:2] data_low = cv2.resize(data_low,(h,w),interpolation=cv2.INTER_CUBIC)#重采样 RGB = HSV(data_low,data_high) RGB.save(r'C:\Users\64908\Desktop\HSV2.png','png') if __name__ == "__main__": path_low = r'RGB.tif' path_high = r'Band8.tif' main(path_low,path_high)

    4、执行效果

    RGB图像:

    全色波段图像:

    公式融合结果:

    opencv融合结果:

     效果还是挺不错的。

    Processed: 0.018, SQL: 9