[英]How to read multi-channel 16-bit-per-channel images in Python without using OpenCV library?
You can download a multi-channel, 16-bit png file from here (shown below).您可以从此处下载多通道 16 位 png 文件(如下所示)。 I have tried multiple Python packages for reading this multi-channel 16-bit-per-channel image.
我尝试了多个 Python 包来读取这个多通道 16 位每通道图像。 But none work, and if they do somehow they transform the images (scaling etc).
但是没有任何效果,如果它们以某种方式进行,它们会转换图像(缩放等)。 I tried using
imageio
, PIL.Image
, scipy.ndimage.imread
and a couple more.我尝试使用
imageio
、 PIL.Image
、 scipy.ndimage.imread
等等。 It seems that they all can read single-channel 16-bit pngs properly but convert the multi-channel images into 8-bit-per-channel.似乎他们都可以正确读取单通道 16 位 png,但将多通道图像转换为每通道 8 位。 For instance, this is a GitHub issue thst indicates
imageio
cannot read multi-channel 16-bit images.例如,这是一个 GitHub 问题,表明
imageio
无法读取多通道16 位图像。 Another issue ( here ) for Pillow seems to say the same thing. Pillow 的另一个问题(这里)似乎也说同样的话。
So I wonder, does anyone know how can I read multi-channel, 16-bit png files in Python without using OpenCV package properly?所以我想知道,有谁知道如何在不正确使用 OpenCV 包的情况下在 Python 中读取多通道、16 位 png 文件? Feel free to offer solutions from other packages that I didn't mention anything about here.
随意提供我在这里没有提到的其他软件包的解决方案。
Option 1 - Split into channels with ImageMagick选项 1 - 使用 ImageMagick 分成多个通道
You could use ImageMagick (it is installed on most Linux distros and is available for macOS and Windows) at the command line.您可以在命令行中使用ImageMagick (它安装在大多数 Linux 发行版上,可用于 macOS 和 Windows)。
For example, this will separate your 16-bit 3-channel PNG into its constituent channels that you can then process individually in Pillow:例如,这会将您的 16 位 3 通道 PNG 分成其组成通道,然后您可以在 Pillow 中单独处理这些通道:
magick input.png -separate channel-$d.png
Now there are 3 separate channels:现在有 3 个独立的频道:
-rw-r--r-- 1 mark staff 2276 1 Apr 16:47 channel-2.png
-rw-r--r-- 1 mark staff 3389 1 Apr 16:47 channel-1.png
-rw-r--r-- 1 mark staff 2277 1 Apr 16:47 channel-0.png
and they are each 16-bit, single channel images that Pillow can open:它们都是 Pillow 可以打开的 16 位单通道图像:
magick identify channel-*
Sample Output样本输出
channel-0.png PNG 600x600 600x600+0+0 16-bit Grayscale Gray 2277B 0.000u 0:00.000
channel-1.png PNG 600x600 600x600+0+0 16-bit Grayscale Gray 3389B 0.000u 0:00.000
channel-2.png PNG 600x600 600x600+0+0 16-bit Grayscale Gray 2276B 0.000u 0:00.000
If you are using ImageMagick v6, replace magick
with convert
and replace magick identify
with plain identify
.如果您使用的是ImageMagick v6,请将
magick
替换为convert
并将magick identify
替换为普通的identify
。
Option 2 - Split into channels with NetPBM选项 2 - 使用 NetPBM 拆分为多个频道
As an alternative to ImageMagick , you could use the much lighter weight NetPBM tools to do the same thing:作为ImageMagick的替代方案,您可以使用重量更轻的 NetPBM 工具来做同样的事情:
pngtopam < rainbow.png | pamchannel - 0 -tupletype GRAYSCALE > channel-0.pam
pngtopam < rainbow.png | pamchannel - 1 -tupletype GRAYSCALE > channel-1.pam
pngtopam < rainbow.png | pamchannel - 2 -tupletype GRAYSCALE > channel-2.pam
Pillow can then open the PAM files. Pillow 然后可以打开 PAM 文件。
Option 3 - Use PyVips选项 3 - 使用 PyVips
As an alternative, you could use the extremely fast, memory-efficient pyvips
to process your images.作为替代方案,您可以使用速度极快、内存高效的
pyvips
来处理您的图像。 Here is an example from the documentation that:这是文档中的一个示例:
Here is the code:这是代码:
#!/usr/local/bin/python3
import sys
import pyvips
im = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
im = im.crop(100, 100, im.width - 200, im.height - 200)
im = im.reduce(1.0 / 0.9, 1.0 / 0.9, kernel='linear')
mask = pyvips.Image.new_from_array([[-1, -1, -1],
[-1, 16, -1],
[-1, -1, -1]], scale=8)
im = im.conv(mask, precision='integer')
im.write_to_file("result.png")
The result is 16-bit like the input image:结果与输入图像一样为 16 位:
identify result.png
result.png PNG 360x360 360x360+0+0 16-bit sRGB 2900B 0.000u 0:00.000
As you can see it is still 16-bit, and trimming 100px off each side results in 600px becoming 400px and then the 10% reduction makes that into 360px.如您所见,它仍然是 16 位,每边修剪 100 像素会导致 600 像素变为 400 像素,然后减少 10% 使其变为 360 像素。
Option 4 - Convert to TIFF and use PyLibTiff选项 4 - 转换为 TIFF 并使用 PyLibTiff
A fourth option, if the number of files is an issue, might be to convert your images to TIFF with ImageMagick第四个选项,如果文件数量是一个问题,可能是使用ImageMagick将您的图像转换为 TIFF
convert input.png output.tif
and they retain their 16-bit resolution, and you process them with PyLibTiff as shown here .他们保留自己的16位分辨率,你PyLibTiff处理它们如图所示这里。
Option 5 - Multi-image TIFF processed as ImageSequence选项 5 - 多图像 TIFF 处理为 ImageSequence
A fifth option, could be to split your PNG files into their constituent channel and store them as a multi-image TIFF, ie with Red as the first image in the sequence, green as the second and blue as the third.第五个选项可能是将您的 PNG 文件拆分为它们的组成通道并将它们存储为多图像 TIFF,即红色作为序列中的第一个图像,绿色作为第二个图像,蓝色作为第三个图像。 This means there is no increase in he number of files and also you can store more than 3 channels per file - you mentioned 5 channels somewhere in your comments:
这意味着文件数量不会增加,而且每个文件可以存储 3 个以上的频道 - 您在评论中提到了 5 个频道:
convert input.png -separate multiimage.tif
Check there are now 3 images, each 16-bit, but all in the same, single file:检查现在有 3 个图像,每个 16 位,但都在同一个文件中:
identify multiimage.tif
multiimage.tif[0] TIFF 600x600 600x600+0+0 16-bit Grayscale Gray 10870B 0.000u 0:00.000
multiimage.tif[1] TIFF 600x600 600x600+0+0 16-bit Grayscale Gray 10870B 0.000u 0:00.000
multiimage.tif[2] TIFF 600x600 600x600+0+0 16-bit Grayscale Gray 10870B 0.000u 0:00.000
Then process them as an image sequence:然后将它们作为图像序列处理:
from PIL import Image, ImageSequence
im = Image.open("multiimage.tif")
index = 1
for frame in ImageSequence.Iterator(im):
print(index)
index = index + 1
I had the same problem and I found out that imageio can do the job:我遇到了同样的问题,我发现 imageio 可以完成这项工作:
img = imageio.imread('path/to/img', format='PNG-FI')
With this option you can read and write multi-channel 16-bit png images (by default imageio uses PNG-PIL
as format for reading png files).使用此选项,您可以读取和写入多通道 16 位 png 图像(默认情况下 imageio 使用
PNG-PIL
作为读取 png 文件的格式)。 This works for png images, but changing the format
can probably help when dealing with other image types ( here a full list of available imageio formats).这适用于 png 图像,但在处理其他图像类型时更改
format
可能会有所帮助(这里是可用 imageio 格式的完整列表)。
To use this format you may need to install the FreeImage plugin as shown in the documentation .要使用这种格式,您可能需要安装 FreeImage 插件,如文档中所示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.