简体   繁体   English

如何使用misc.imread将图像切割成红色,绿色和蓝色通道

[英]How to slice an image into red, green and blue channels with misc.imread

I am trying to slice an image into RGB and I have a problem with plotting these images. 我正在尝试将图像切割成RGB,我在绘制这些图像时遇到问题。 I obtain all images from a certain folder with this function: 我使用此功能从某个文件夹中获取所有图像:

def get_images(path, image_type):
image_list = []
for filename in glob.glob(path + '/*'+ image_type):
    im=misc.imread(filename, mode='RGB')
    image_list.append(im)
return image_list

This function creates 4d array (30, 1536, 2048, 3) and I am quite sure that the first value represents number of images, second and third are dimensions and third are RGB values. 这个函数创建了4d数组(30,1536,2048,3),我很确定第一个值代表图像数量,第二个和第三个是维度,第三个是RGB值。

After I obtained all the images, I stored them as a numpy array 在我获得所有图像后,我将它们存储为numpy数组

image_list = get_images('C:\HDR\images', '.jpg')
temp = np.array(image_list)

After that I tried to use simple slicing on order to take specific colors from these images: 之后我尝试使用简单的切片来从这些图像中获取特定的颜色:

red_images = temp[:,:,:,0]
green_images = temp[:,:,:,1]
blue_images = temp[:,:,:,2]

When I print out the values, everything seems to be fine. 当我打印出值时,一切似乎都很好。

print(temp[11,125,311,:])
print(red_images[11,125,311])
print(green_images[11,125,311])
print(blue_images[11,125,311])

And I get the following: 我得到以下内容:

[105  97  76]
105
97
76

So far, everything seems to be fine, but the problem arises when I try to display the image. 到目前为止,一切似乎都很好,但是当我尝试显示图像时会出现问题。 I used matplotlib.pyplot.imshow to display it and I get the image like: 我使用matplotlib.pyplot.imshow来显示它,我得到的图像如下:

图像红色通道

Which is reasonable, because I choose red: 这是合理的,因为我选择红色:

 plt.imshow(temp[29,:,:,0])

But when I change it to different color channel, like this: 但当我将其更改为不同的颜色通道时,如下所示:

plt.imshow(temp[29,:,:,2])

I get the image like this: 我得到这样的图像:

图片错误频道

My question is simple. 我的问题很简单。 What is happening here? 这里发生了什么?

I think matplotlib is just treating each channel (ie, intensities) as a "heat map". 我认为matplotlib只是将每个通道(即强度)视为“热图”。

Pass a color map to the imshow function like so to tell it how you want it to color your image: 将颜色贴图传递给imshow函数,以便告诉它如何为图像着色:

plt.imshow(image_slice, cmap=plt.cm.gray)

Edit 编辑

@mrGreenBrown in response to your comment, I'm assuming that the misc.imread function you used is from scipy, ie, scipy.misc.imread . @mrGreenBrown响应你的评论,我假设你使用的misc.imread函数来自scipy,即scipy.misc.imread That function is no different from that of PIL . 该功能与PIL没有什么不同。 See scipy.misc.imread docs . 请参阅scipy.misc.imread docs Thanks to @dai for pointing this out. 感谢@dai指出这一点。

A single channel of any image is just intensities. 任何图像的单个通道都是强度。 It does not have color. 它没有颜色。 For an image expressed in RGB color space, color is obtained by "mixing" amounts (given by the respective channel's intensities) of red, green, and blue. 对于以RGB颜色空间表示的图像,通过“混合”红色,绿色和蓝色的量(由相应通道的强度给出)来获得颜色。 A single channel cannot express color . 单个通道无法表达颜色

What happened was Matplotlib by default displays the intensities as a heatmap, hence the "color". 发生的事情是默认情况下Matplotlib将强度显示为热图,因此显示“颜色”。

When you save a single channel as an image in a format say JPEG, the function merely duplicates the single channel 3 times so that the R, G, and B channels all contain the same intensities. 当您将单个通道保存为JPEG格式的图像时,该功能仅复制单个通道3次,以便R,G和B通道都包含相同的强度。 This is the typical behavior unless you save it in a format such as PGM which can handle single channel grayscale image. 这是典型的行为,除非您以PGM格式保存,可以处理单通道灰度图像。 When you try to visualize this image which has the same channel duplicated 3 times, because the contributions from red, green, and blue are the same at each pixel, the image appears as grey. 当您尝试将具有相同通道重复3次的此图像可视化时,由于红色,绿色和蓝色的贡献在每个像素处相同,因此图像显示为灰色。

Passing plt.cm.gray to the cmap argument simply tells imshow not to "color-code" the intensities. plt.cm.gray传递给cmap参数只是告诉imshow不要对颜色进行“颜色编码”。 So, brighter pixels (pixels approaching white) means there is "more" of that "color" at those locations. 因此,更亮的像素(接近白色的像素)意味着在那些位置存在“更多”的“颜色”。

If you want color, you have to make copies of the 3 channel image and set the other channels to have values of 0 . 如果需要颜色,则必须复制3通道图像,并将其他通道设置为0

For eg, to display a red channel as "red": 例如,要将红色通道显示为“红色”:

# Assuming I is numpy array with 3 channels in RGB order
I_red = image.copy()  # Duplicate image
I_red[:, :, 1] = 0    # Zero out contribution from green
I_red[:, :, 2] = 0    # Zero out contribution from blue

A related question from stackoverflow here . 这里来自stackoverflow的相关问题。

So, you want to show in different colors the different RGB channels of an image... 因此,您希望以不同的颜色显示图像的不同RGB通道...

import matplotlib.pyplot as plt
from matplotlib.cbook import get_sample_data

image = plt.imread(get_sample_data('grace_hopper.jpg'))

titles = ['Grace Hopper', 'Red channel', 'Green channel', 'Blue channel']
cmaps = [None, plt.cm.Reds_r, plt.cm.Greens_r, plt.cm.Blues_r]

fig, axes = plt.subplots(1, 4, figsize=(13,3))
objs = zip(axes, (image, *image.transpose(2,0,1)), titles, cmaps)

for ax, channel, title, cmap in objs:
    ax.imshow(channel, cmap=cmap)
    ax.set_title(title)
    ax.set_xticks(())
    ax.set_yticks(())

plt.savefig('RGB1.png')

在此输入图像描述 Note that when you have a dark room with a red pen on a dark table, if you turn on a red lamp you percept the pen as almost white... 请注意,当你在黑暗的桌子上有一个带红色笔的黑暗房间时,如果你打开一个红色的灯,你会认为笔几乎是白色的......

Another possibility is to create a different image for each color, with the pixel values for the other colors turned to zero. 另一种可能性是为每种颜色创建不同的图像,其他颜色的像素值变为零。 Starting from where we left we define a function to extract a channel into an otherwise black image 从我们离开的地方开始,我们定义了一个将通道提取为黑色图像的功能

...
from numpy import array, zeros_like
def channel(image, color):
    if color not in (0, 1, 2): return image
    c = image[..., color]
    z = zeros_like(c)
    return array([(c, z, z), (z, c, z), (z, z, c)][color]).transpose(1,2,0)

and finally use it... 最后用它......

colors = range(-1, 3)
fig, axes = plt.subplots(1, 4, figsize=(13,3))
objs = zip(axes, titles, colors)
for ax, title, color in objs:
    ax.imshow(channel(image, color))
    ax.set_title(title)
    ax.set_xticks(())
    ax.set_yticks(())

plt.savefig('RGB2.png')

在此输入图像描述 I can't tell which is the version that I like better, perhaps the 1st one is looking more realistic to me (maybe it looks less artificial ) but it's quite subjective... 我不知道哪个是我更喜欢的版本,也许第一个对我来说看起来更逼真 (也许它看起来不那么人为 )但它很主观......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用misc.imread从URL读取图像返回一个展平的数组而不是彩色图像 - Reading image from URL with misc.imread returning a flattened array instead of a colour image 如何从misc.imread()获得的ndarray中删除整个值列? - How do you delete an entire column of values from an ndarray obtained from misc.imread()? 如何在不使用PIL的情况下交换图像文件上的红色和绿色通道 - How To Swap The Red And Green Channels On An Image File Without PIL 使用Python计算红色,绿色和蓝色通道的总和 - Compute the sum of the red, green and blue channels using Python 屏蔽图像中红色和蓝色通道的矢量化方法 - Vectorized approach to masking red and blue channels in an image 如何在 Python 中查找图像的特定像素是否具有更高的红色、绿色或蓝色值 - How to find if a specific pixel of an image has a higher Red, Green, or Blue value in Python 如何使用 python 将全彩色图像转换为仅三色图像(红、蓝、绿)? - How do convert a full color image into just three color image (red, blue, green) using python? numpy.ones会在图像上生成红色,绿色,蓝色和黑色条 - numpy.ones results in red, green, blue, and black bars on image 使用 OpenCV 将 RGB 图像分离为红色和绿色蓝色分量,并使用这些进行操作 - Use OpenCV to separate the RGB image into red and green blue components and operate with these 是否使用列表或数组来存储红色绿色和蓝色通道的值-python opencv - whether to use list or an array for storing the values of red green and blue channels - python opencv
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM