数字图像处理——图像读取与显示、图像融合、图像色调转换

一、前言

  武汉大学测绘学院数字图像处理课程,要求自己编程实现图像处理。今天的内容主要包括图像的读取与显示,图像融合,图像色调转换。本文采用Python语言实现编译,也可以使用C++的OpenCV,C#或者matlab语言编写。咱们废话不多说,直接开始讲解。

二、图像读取与显示

  要求:

  1. 编写读取图像文件(彩色图像、灰度图像):
  • 图像文件的读写;
  • 读取图像文件中某位置(例如(100,100))像素的灰度值。
  • 图像显示与保存。

  为了保证程序的通用性,我选择了把这些功能封装成函数,方便不同脚本相互调用和后续的使用。用python处理图像需要用到一个库叫做pillow,解释器没有安装这个库的话可以通过以下命令安装:

pip install pillow

 读取图像的函数

from PIL import Image

#读取图像文件
def read_image(image_path):
    return Image.open(image_path)

获取指定位置灰度值的函数

#读取指定位置的像素灰度值
def get_pixel_value(image,position):
    if image.mode=='RGB':
        #如果是彩色图像,转换为灰度图像
       gray_image=image.convert('L')
    else:
        gray_image=image
    return gray_image.getpixel(position)

显示图像和保存图像的函数:

#显示图像
def show_image(image):
    image.show()

#保存图像
def save_image(image,save_path):
    image.save(save_path)

函数写完之后可以简单写一个主函数来测试

def main():
    image_path='编程1扩展-1.jpg'
    image=read_image(image_path)
    #获取指定位置的灰度值
    postion=(100,100)
    pixel_value=get_pixel_value(image,postion)
    print(f"位置{postion}的灰度值是:{pixel_value}")
    #显示图像
    show_image(image)

if __name__=="__main__":
    main()

  注意最后两行,它的作用是当脚本没有被其它脚本引用直接运行时,执行main函数,而当脚本被其它脚步引用时,不执行。

三、图像融合

要求:

  1. 将两幅RGB图像(编程1扩展-1.jpg、编程1扩展-2.jpg)变换至HSI模型中,用第2幅图像的I分量代替第1幅图像的I分量,得到一幅新的图像;
  2. 反变换至RGB模型,就得到一幅“清晰度高、细节丰富、噪声表现及颜色还原度好”的彩色图像;
  3. 显示与保存新图像。

  所用到的知识点及公式: 

1.RGB模型

  RGB模型采用CIE规定的三基色成表色系统。自然界 的任一颜色都可通过这三种基色按不同比例混合而成。 由于RGB模型将三基色同时加入以产生新的颜色,所以, 它是一个加色系统。 设颜色传感器把数字图像上的一个像素编码成(R,G, B),每个分量量化范围为 [0,255]共256级。因此, RGB模型可以表示2 8×2 8×2 8=224=256×256×256=16 777 216≈1670万种颜色。这足以表示自然界的任一颜色,故 又称其为24位真彩色。

  R、G、B分别代表红、绿、蓝

2.HSI模型

  HSI模型是美国色彩学家孟塞尔(H.A.Munseu)于1915年 提出的,它反映了人的视觉系统感知彩色的方式,在艺术上 经常使用HSI模型。 HSI模型中,H表示色调(Hue),S表示饱和度(Saturation), I表示亮度(Intensity,对应成像亮度和图像灰度)。

  色调H(Hue): 与光波的波长有关,它表示人的感官对不同颜色的感受,如红色、绿色、蓝色等,它也可表示一定范 围的颜色,如暖色、冷色等。

  饱和度S(Saturation): 表示颜色的纯度,纯光谱色是完全饱和的,加入白光会稀释饱和度。饱和度越大,颜色看起 来就会越鲜艳,反之亦然。

  强度I(Intensity): 对应成像亮度和图像灰度,是颜色的明亮程度。

  色相由角度表示,它反映了该彩色最接近什么样的光谱波长。 一般假定0°表示的颜色为红色, 120°为绿色, 240°为蓝色。 0°到240°的色相覆盖了所有可见光谱的彩色,在240° 到300°之间为人眼可见的非光谱色(紫色)。

3.RGB模型与HSI模型的相互转换

HSI模型与RGB模型之间可按下述方法相互转换。

(1) RGB转换到HSI

首先,对取值范围为[0,255] 的R、G、B值进行归一化处理,得到3个[0,1]范围内的 r、g、b值:

则对应HSI模型中的H、S、I分量的计算公式为:

(2)HSI转换到RGB

(3)完整代码
import numpy as np
from PIL import Image

def rgb_to_hsi(rgb_image):
        epsilon = 1e-10  # 防止除以零的很小值
        rgb_array = np.array(rgb_image) / 255.0
        # 提取 R、G 和 B 通道
        R = rgb_array[:, :, 0]
        G = rgb_array[:, :, 1]
        B = rgb_array[:, :, 2]

        # 初始化 H、S 和 I
        H = np.zeros_like(R)
        S = np.zeros_like(R)
        I = (R + G + B) / 3

        # 计算 H、S 和 I 分量
        min_of_RGB = np.min(rgb_array, axis=2)
        denominator = R + G + B
        denominator[denominator < epsilon] = epsilon  # 避免除以非常小的值
        S[denominator > epsilon] = 1 - 3 * min_of_RGB[denominator > epsilon] / denominator[denominator > epsilon]

        return H, S, I

def hsi_to_rgb(H, S, I):
    H = H * 2 * np.pi
    R, G, B = np.zeros(H.shape), np.zeros(H.shape), np.zeros(H.shape)

    for i in range(H.shape[0]):
        for j in range(H.shape[1]):
            h = H[i, j]
            s = S[i, j]
            i_val = I[i, j]

            if s == 0:
                R[i, j] = G[i, j] = B[i, j] = i_val
            else:
                h = h * 3
                h = h - np.floor(h)
                x = i_val * (1 - s)
                y = i_val * (1 + s * np.cos(h * np.pi / 3) / np.cos((1 - h * np.pi / 3)))

                if h < 1:
                    R[i, j] = i_val + (y - i_val) * h
                    G[i, j] = x
                    B[i, j] = i_val + (y - i_val) * (1 - h)
                elif h < 2:
                    R[i, j] = x
                    G[i, j] = i_val + (y - i_val) * (h - 1)
                    B[i, j] = i_val + (y - i_val) * (2 - h)
                else:
                    R[i, j] = i_val + (y - i_val) * (3 - h)
                    G[i, j] = x
                    B[i, j] = i_val + (y - i_val) * (h - 2)

    R = np.clip(R * 255, 0, 255).astype(np.uint8)
    G = np.clip(G * 255, 0, 255).astype(np.uint8)
    B = np.clip(B * 255, 0, 255).astype(np.uint8)

    return np.stack([R, G, B], axis=2)


def process_images(image_path1, image_path2, save_path):
    # 读取图像
    img1 = Image.open(image_path1).convert('RGB')
    img2 = Image.open(image_path2).convert('RGB')

    # 转换到 HSI
    H1, S1, I1 = rgb_to_hsi(img1)
    H2, S2, I2 = rgb_to_hsi(img2)

    # 替换 I 分量
    new_I = I2

    # 转换回 RGB
    new_rgb_array = hsi_to_rgb(H1, S1, new_I)
    new_img = Image.fromarray(new_rgb_array)

    # 显示和保存新图像
    new_img.show()
    new_img.save(save_path)
    print(f"新图像已保存到 {save_path}")
(4)转换效果

原图1

原图2

融合图像:

四、图像色调变换

参考了以下文章:

实战 | 用 Python 给照片换色

  要改变图片的色调,核心就是改变HSI模型里面的H值,H值为0时,即为红色,H值为120时为绿色,H值为240时为蓝色。实现代码如下,用到了colorsys库,没有安装需要提前安装:

import colorsys
from PIL import Image

def change_h(image_path,target_hue):
     # 读入图片,转化为 RGB 色值
     image = Image.open(image_path).convert('RGB')
     # 将 RGB 色值分离
     image.load()
     r, g, b = image.split()
     result_r, result_g, result_b = [], [], []
     # 依次对每个像素点进行处理
     for pixel_r, pixel_g, pixel_b in zip(r.getdata(), g.getdata(), b.getdata()):
        # 转为 HSV 色值
        h, s, v = colorsys.rgb_to_hsv(pixel_r / 255., pixel_b / 255., pixel_g / 255.)
        #转回R,G,B
        rgb = colorsys.hsv_to_rgb(target_hue, s, v)
        pixel_r, pixel_g, pixel_b = [int(x * 255.) for x in rgb]
        # 每个像素点结果保存
        result_r.append(pixel_r)
        result_g.append(pixel_g)
        result_b.append(pixel_b)

     r.putdata(result_r)
     g.putdata(result_g)
     b.putdata(result_b)

     # 合并图片
     image = Image.merge('RGB', (r, g, b))
     return image

通过以上算法,可以随意改变图片的色调,挺好玩的,效果如下:

五、总结:

  本次的内容就分享到这里了,感兴趣的同学可以点个关注,后续会持续分享更多优质的内容哦。

  大家需要完整资源的,可以免费下载哦,内容包括所有源代码和测试所用的图片以及相关知识点的PPT,下载链接如下:

【免费】数字图像处理-图像读取与显示、图像融合、图像色调转换资源-CSDN文库

  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两眼一睁就是学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值