RGB图像到灰度图像

Rgb image to the grayscale image

提问人:Дмитрий Киселев 提问时间:11/16/2023 最后编辑:eyllanescДмитрий Киселев 更新时间:11/19/2023 访问量:55

问:

我有一张RGB格式的激光束图像。我想通过将图像转换为灰度来获得图像的亮度。

但事实证明这不是我的计划。中心应该是最亮的地方,但结果却很暗 帮助,谁知道呢

enter image description here

enter image description here

from PIL import Image
import math

image = Image.open("/content/TiSa_fs_vert_1.jpg")
image = image.convert ('RGB')
width, height = image.size
y = 450

brightness_values = []

# Loop through the horizontal line
for x in range(width):
    pixelRGB = image.getpixel((x, y))
    R, G, B = pixelRGB
    #brightness = math.sqrt(R**2 + G**2 + B**2)
    brightness = (R + G + B)//3
    brightness_values.append(brightness)

print(brightness_values)
Python 图像 RGB 灰度

评论

0赞 white 11/16/2023
使用另一种模式可能会取得更大的成功,例如 (只有一个通道,已经是灰度)或(3 个通道,色相、饱和度、值)。基本上,您的渐变从 HSV 色调分量 0(红色)到 225(深蓝色)左右。有关模式的更多信息,请参阅此处LHSV
1赞 Colas 11/16/2023
这似乎始于一个错误的假设:“中心应该是最明亮的地方”。纯红色、纯绿色和纯蓝色(255 0 0、0 255 0、0 0 255)似乎都出现在您的第一张照片中,并且根据您的公式,亮度均为 85。
0赞 Mark Setchell 11/19/2023
目前尚不清楚您的 2 张图片代表什么。你为什么有两个?哪一个最接近传感器的原始数据,哪个已经处理过?如何?

答:

0赞 OM222O 11/16/2023 #1

你很幸运,因为你使用的是激光,它将是单色的,很容易从颜色通道中分离出来

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import cv2

img = np.array(Image.open("laser.jpg"))

plt.figure()
plt.imshow(img)
plt.show()
# Since the laser is red, you can just take out the red channel from the RGB
# Color channels are 0=Red, 1=Green, 2=Blue
r=img[:,:,0]
plt.figure()
plt.imshow(r, cmap='grey') 
plt.show()

# To plot only the brightest portion of your selected channel, you can do:
threshold= r.max()*0.9
# set areas of the image that are below the threshold to be 0
r[np.where(r<threshold)]=0
# set areas of the image that are at or above the threshold to be 1
r[np.where(r>=threshold)]=1

plt.figure()
plt.imshow(r, cmap='grey')
plt.show()

# To clean up the image a bit more
cleaned_up = cv2.dilate(r,np.ones((3,3), dtype=np.uint8),iterations = 5)
plt.figure()
plt.imshow(cleaned_up, cmap='grey')
plt.show()

# Simplistic method to calculate center
# (you should probably apply some smoothing to the calculated brightness along each axis)
x_sum = cleaned_up.sum(axis=0)
y_sum = cleaned_up.sum(axis=1)
center = (x_sum.max(), y_sum.max())
plt.figure()
plt.plot(np.arange(x_sum.shape[0]),x_sum)
plt.plot(y_sum,np.arange(y_sum.shape[0]))
plt.show()

plt.figure()
plt.imshow(cleaned_up, cmap='grey')
plt.plot(center[0],center[1], 'ro')
plt.show()

# Using image moments to find the centroid
moments = cv2.moments(cleaned_up)
centroid = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
plt.figure()
plt.imshow(cleaned_up, cmap='grey')
plt.plot(centroid[0],centroid[1], 'ro')
plt.show()

老实说,这两种找到中心的方法都效果很好,并产生非常相似的结果,但我更喜欢使用图像矩的质心方法,因为它在我眼中看起来更居中,但请随意选择最适合您的方法

评论

0赞 Дмитрий Киселев 11/18/2023
感谢您的回复!他们帮了大忙。一位在Matlab工作的朋友建议我把图片转换成索引图片+先使用“喷气式”色彩图,然后再转换成灰度(在Matlab中是rgb2ind)这在Python中可以做到吗?
0赞 Дмитрий Киселев 11/18/2023
如果你使用这个解决方案并沿 x 轴和 y 轴绘制强度,那么图形就有一个平台,也就是说,它看起来更像是一个超高斯。但最有可能的是它应该像高斯一样
0赞 OM222O 11/18/2023
问题源于这样一个事实,即我服用的是纯红色,但您的激光不太可能是纯红色。您可以计算 R、G 和 B 通道的加权平均值(正常灰度是,这就是为什么它显示图像中心为“黑暗”的原因,因为那里没有太多绿色。 除非您提供有关激光的确切波长和预期的“中心”位置的更多详细信息,否则我无能为力。0.299 ∙ Red + 0.587 ∙ Green + 0.114 ∙ Blue
0赞 OM222O 11/18/2023
我也不确定什么是“索引图像”,但任何语言都可以进行任何图像处理,您只需要知道需要使用的公式和算法即可。
0赞 OM222O 11/19/2023
@ДмитрийКиселев 老实说,绿色和蓝色通道在您感兴趣的区域几乎为 0,所以我之前的评论效果不太好,但一些阈值有很大帮助,请参阅更新的代码并让我知道它是否解决了您的问题。