arrays - 如何连接三个二维数组,它们各自的数组中包含色调、饱和度和强度值,并将其显示为图像?
问题描述
我是图像处理和 python 的新手。正如您从我的代码中看到的那样,我设法通过使用我找到的不同公式将我的 RGB 图像转换为 HSI。
我将色调、饱和度和强度的值存储在三个不同的数组中。这也在下面的代码中。如何连接这三个数组并将连接的图像显示为图像?
import math
from PIL import Image
img = Image.open("D:\\Texture analysis\\trees-clolorful-aerial-view-wallpaper.jpg")
rgb_img = img.convert('RGB')
row, col = img.size
print(row, col)
i = j = 0
satValue = 0
inValue = 0
hueValue = 0
squareValue = 0
hueArray = [[0 for x in range(row)] for y in range(col)]
satArray = [[0 for x in range(row)] for y in range(col)]
inArray = [[0 for x in range(row)] for y in range(col)]
division = 0
denominator = 0
numerator = 0
radAngle = 0
degAngle = 0
product = 0
sqr = 0
count = 0
uCount = 0
while i < row:
j = 0
while j < col:
red, green, blue = rgb_img.getpixel((i, j))
hRed = sRed = iRed = red
hGreen = sGreen = iGreen = green
hBlue = sBlue = iBlue = blue
# =========================Saturation Calculation==============================
if sRed == 0 and sGreen == 0 and sBlue == 0:
satValue = 0
satArray[i][j] = 0
else:
if (sRed < sGreen) and (sRed < sBlue):
satValue = 1 - (((3) * (sRed)) / (sRed + sGreen + sBlue))
satArray[i][j] = satValue
# print(satValue)
elif (sGreen < sRed) and (sGreen < sBlue):
satValue = 1 - (((3) * (sGreen)) / (sRed + sGreen + sBlue))
satArray[i][j] = satValue
# print(satValue)
else:
satValue = 1 - (((3) * (sBlue)) / (sRed + sGreen + sBlue))
satArray[i][j] = satValue
# print(satValue)
# =============================================================================
# ==========================Intensity Calculation==============================
inValue = (iRed + iGreen + iBlue) / 3
inArray[i][j] = inValue
count += 1
print(inValue, count)
# =============================================================================
# =============================Hue Calculation=================================
product = (hRed - hBlue) * (hGreen - hBlue)
sqr = (hRed - hGreen) * (hRed - hGreen)
denominator = math.sqrt(sqr + product)
if denominator != 0:
numerator = ((hRed - hGreen) + (hRed - hBlue)) / 2
division = numerator / denominator
radAngle = math.acos(division)
degAngle = math.degrees(radAngle)
if hBlue <= hGreen:
hueValue = degAngle
hueArray[i][j] = hueValue
elif hBlue > hGreen:
hueValue = 360 - degAngle
hueArray[i][j] = hueValue
elif denominator == 0:
hueValue = 0
hueArray[i][j] = hueValue
#print(hueValue, count)
# =============================================================================
j += 1
i += 1 print(i, j)
PS。将来你也会看到很多我的业余代码:D
解决方案
现在我回到电脑前,我可以看到出了什么问题。你可能试过这个:
#!/usr/bin/env python3
from PIL import Image
img = Image.open('start.png')
hsvimg = img.convert('HSV')
hsvimg.save('result.png')
如果你这样做,你实际上会收到一条错误消息:
OSError: cannot write mode HSV as PNG
因为,PNG 图像始终处于 sRGB 色彩空间中,因此它正确地拒绝写入您的 HSV 图像。但问题是,色彩空间转换确实有效,图像中的值实际上是您想要的 HSV 值。您可以通过以下方式检查:
img.getpixel((X,Y))
和
hsvimg.getpixel((X,Y))
X
你喜欢的Y
任何随机坐标在哪里。您将看到后者始终是前者 RGB 颜色的正确 HSV 表示。
我不确定您总体上要做什么,所以我无法给出正确的建议,但您可以做的一件事是“咬牙切齿”并告诉 PIL/Pillow 图像是 RGB,即使您知道它是单纯疱疹病毒。所以如果你这样做:
hsvimg = img.convert('HSV')
hsvimg.mode='RGB' # Tell PIL image is RGB
hsvimg.save('result.png')
它会保存图像,但它和所有其他查看器会将您的色调显示为蓝色,将您的饱和度显示为绿色,将您的值显示为蓝色。
我猜你还有其他处理要做,这只是你处理的一个中间方面,所以它可能无关紧要,你可以继续进行处理并在最后转换回来并保存为 sRGB PNG文件而不需要说谎。
在回答您的实际问题时,您可以使用 PIL/Pillow 拆分和合并这样的频道:
# Split and recombine with PIL
r,g,b = img.split()
merged = Image.merge(mode='RGB',bands=(r,g,b)))
或者,如果您更喜欢 Numpy,它通常更快:
# Open image as Numpy array
img = np.array(Image.open('start.png'))
# Split into 3 channels/arrays/bands
r = img[:, :, 0]
g = img[:, :, 1]
b = img[:, :, 2]
# Recombine to single image
merged = np.dstack((r, g, b))
推荐阅读
- c# - JsonConvert.SerializeObject 读取结构,但不读取值
- sql - MSSQL 服务器中如何计算非聚集索引的 index_id?
- ms-access - 防止数据在 Access 表中更改
- mysql - 如何在 MYSQL 表中找到两个不同日期之间的数据,例如(29-05-2021 到 08-06-2021)
- java - 在 Apache Camel XML 中将 DOM 转换为 XML
- javascript - 如何使用 JavaScript 和 AJAX 根据邮政编码自动填充城市和州?
- forms - 使用 Java webstart 从带有参数的表单调用 Oracle 12c 报表
- kotlin - 使用协程实现后应用程序变慢
- python - 如何合并具有相同字段的数据框行?
- javascript - 如何将 json 数据从 ruby 控制器传递到 javascript (Rails 6.1)?