微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 PIL 而不是 imagio 库读取图像时,图像无法正确显示

如何解决使用 PIL 而不是 imagio 库读取图像时,图像无法正确显示

我有将图像从 RGB 空间转换为 HSI 空间的代码

import numpy as np
import imageio
from matplotlib import pyplot as plt


def RGB_TO_HSI(img):
    with np.errstate(divide='ignore',invalid='ignore'):

        rgb = np.float32(img) / 255

        # Separate color channels
        red = rgb[:,:,0]
        green = rgb[:,1]
        blue = rgb[:,2]

        # Calculate Intensity
        def calc_intensity(red,green,blue):
            intensity = (red + green + blue + 0.001) / 3
            return intensity

        # Calculate Saturation
        def calc_saturation(red,blue):
            minimum = np.minimum(np.minimum(red,green),blue)
            saturation = 1 - (minimum / calc_intensity(red,blue))
            return saturation

        # Calculate Hue
        def calc_hue(red,blue):
            hue = np.copy(red)  # Basically have our hue = red for Now; we only need its size/dimensions

            for i in range(0,blue.shape[0]):
                for j in range(0,blue.shape[1]):

                    if blue[i][j] <= green[i][j]:
                        hue[i][j] = np.arccos(0.5 * ((red[i][j] - green[i][j]) + (red[i][j] - blue[i][j])) / (np.sqrt((red[i][j] - green[i][j]) ** 2 + (red[i][j] - blue[i][j]) * (green[i][j] - blue[i][j]))))
                    else:
                        hue[i][j] = 2 * np.pi - np.arccos(0.5 * ((red[i][j] - green[i][j]) + (red[i][j] - blue[i][j])) / (np.sqrt((red[i][j] - green[i][j]) ** 2 + (red[i][j] - blue[i][j]) * (green[i][j] - blue[i][j]))))
            return hue

    # Merge channels into picture and return image
    hsi = np.zeros(img.shape)  # instead of having 3 channels,one for each color (RGB),here we have a channel; for "hue",another for "saturation" and another for "intensity"
    hsi[:,0],hsi[:,1],2] = calc_hue(red,blue),calc_saturation(red,calc_intensity(red,blue)
    return hsi

cat = imageio.imread("Path...")
hsi_cat = RGB_TO_HSI(cat)
plt.imshow(hsi_cat)
plt.show()

但是,将代码中的行调整为:hsi = np.zeros(rgb.shape,dtype=np.uint8),然后使用 PIL 加载图像,并将其作为参数传递给函数

cat_p = Image.open("Path...")  # Using PIL Now
his_cat_p = RGB_TO_HSI(cat_p)  # Passing the JPEG image into the function
his_cat_p = Image.fromarray(his_cat_p)  # Converting the result back from an array (return hsi),into JPEG format
his_cat_p.show()  # Black image appears

这个结果是一个黑色的图像,我不太确定为什么!

解决方法

函数 Image.fromarray 仅支持具有典型范围的有限 modes。如果只是想将数据正确渲染为图像,也许最好从 HSI 转换回 RGB 值,然后输出它。类似的东西,

cat_hsi = RGB_TO_HSI(cat)
result = modify(cat_hsi)  # I guess you want to operate on hsi instead of rgb
result_rgb = HSI_TO_RGB(result)
img = Image.fromarray(result_rgb,mode='RGB')
img.show()

此外,我对代码进行了一些修改,使其在我的机器上运行。

  • 确保将形状为 (X,Y,3) 的 RGB 数组传递给函数
  • calc_hue 函数中明确处理可能出现的零除情况。
import numpy as np
from numba import njit  # code gets significantly faster
from matplotlib import pyplot as plt
from PIL import Image


def RGB_TO_HSI(img):
    rgb = np.float32(img) / 255

    red = rgb[:,:,0]
    green = rgb[:,1]
    blue = rgb[:,2]

    def calc_intensity(red,green,blue):
        intensity = (red + green + blue + 0.001) / 3
        return intensity

    def calc_saturation(red,blue):
        minimum = np.minimum(np.minimum(red,green),blue)
        saturation = 1 - (minimum / calc_intensity(red,blue))
        return saturation

    @njit  # use numba to accelerate
    def calc_hue(red,blue):
        hue = np.copy(red)
        for i in range(0,blue.shape[0]):
            for j in range(0,blue.shape[1]):
                denominator = np.sqrt(
                    (red[i][j] - green[i][j]) ** 2 + (red[i][j] - blue[i][j]) * (green[i][j] - blue[i][j])
                )
                if abs(denominator) < 1e-10:  # exliciply handle the possible zero-division cases
                    hue[i][j] = np.nan
                else:
                    if blue[i][j] <= green[i][j]:
                        hue[i][j] = np.arccos(0.5 * ((red[i][j] - green[i][j]) + (red[i][j] - blue[i][j])) / denominator)
                    else:
                        hue[i][j] = 2 * np.pi - np.arccos(0.5 * ((red[i][j] - green[i][j]) + (red[i][j] - blue[i][j])) / denominator)
        return hue

    # Merge channels into picture and return image
    hsi = np.zeros(img.shape)  # instead of having 3 channels,one for each color (RGB),here we have a channel; for "hue",another for "saturation" and another for "intensity"
    hsi[:,0],hsi[:,1],2] = calc_hue(red,blue),calc_saturation(red,calc_intensity(red,blue)
    return hsi

cat = np.array(Image.open("test.png"))
hsi_cat = RGB_TO_HSI(cat[:,:3])  # sometims images are in RGBA format
plt.imshow(hsi_cat)
plt.show()

numba 很神奇吧?)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?