首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不使用OpenCV库的情况下读取Python中的多通道16位/通道图像?

如何在不使用OpenCV库的情况下读取Python中的多通道16位/通道图像?
EN

Stack Overflow用户
提问于 2018-04-01 15:19:20
回答 2查看 2.5K关注 0票数 2

您可以从这里下载一个多通道16位png文件(如下所示)。我已经尝试了多个Python包来读取这个多通道16位/通道映像。但是没有一个工作,如果他们做了,他们以某种方式转换图像(缩放等)。我试过使用imageioPIL.Imagescipy.ndimage.imread和其他几种。似乎它们都能正确地读取单通道16位pngs,但将多通道图像转换为8位/通道。例如,是一个GitHub问题,表明imageio不能读取多通道16位图像.枕头的另一个问题(这里)似乎也是如此。

所以我想知道,没有人知道如何在不正确使用OpenCV包的情况下读取Python中的多通道16位png文件?请随意提供解决方案,从其他软件包,我没有提到任何有关这里。

EN

回答 2

Stack Overflow用户

发布于 2018-04-01 15:50:41

选项1-使用ImageMagick拆分成通道

您可以在命令行使用ImageMagick (它安装在大多数Linux发行版上,并可用于macOS和macOS)。

例如,这将将您的16位3通道PNG分离成它的组成通道,然后您可以在枕头中单独处理:

代码语言:javascript
运行
复制
magick input.png -separate channel-$d.png

现在有三个独立的频道:

代码语言:javascript
运行
复制
-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

它们都是16位的单通道图像,枕头可以打开:

代码语言:javascript
运行
复制
magick identify channel-*

样本输出

代码语言:javascript
运行
复制
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

如果使用的是ImageMagick v6,请将magick替换为convert,将magick identify替换为普通identify

选项2-使用NetPBM拆分成通道

作为ImageMagick,的另一种选择,您可以使用重量更轻的NetPBM工具来做同样的事情:

代码语言:javascript
运行
复制
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

然后枕头可以打开PAM文件。

选项3-使用PyVips

作为另一种选择,您可以使用极其快速、内存效率高的pyvips来处理图像.下面是来自文档的一个示例:

  • 从每一侧切出100个像素
  • 用双线性插值将图像缩小10%
  • 用卷积锐化,并重新保存图像.

以下是代码:

代码语言:javascript
运行
复制
#!/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")

其结果与输入图像相似,为16位:

代码语言:javascript
运行
复制
identify result.png
result.png PNG 360x360 360x360+0+0 16-bit sRGB 2900B 0.000u 0:00.000

正如你所看到的,它仍然是16位,每边修剪100 10会使600 10变成400 10,然后10%的减少会使其变为360 10。

选项4-转换为TIFF并使用PyLibTiff

如果文件数量有问题,第四种选择可能是使用ImageMagick将图像转换为TIFF。

代码语言:javascript
运行
复制
convert input.png output.tif

它们保留16位分辨率,然后用PyLibTiff处理它们,如这里所示。

选项5-作为ImageSequence处理的多图像TIFF

第五种选择是将PNG文件拆分到它们的组成通道中,并将它们存储为一个多图像TIFF,即序列中的第一个图像是红色,第二个是绿色,第三个是蓝色。这意味着文件数量没有增加,而且每个文件可以存储3个以上的通道--您在评论中提到了5个通道:

代码语言:javascript
运行
复制
convert input.png -separate multiimage.tif

检查现在有3个图像,每个16位,但都在同一个文件中:

代码语言:javascript
运行
复制
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

然后将它们作为图像序列处理:

代码语言:javascript
运行
复制
from PIL import Image, ImageSequence

im = Image.open("multiimage.tif")

index = 1
for frame in ImageSequence.Iterator(im):
    print(index)
    index = index + 1
票数 4
EN

Stack Overflow用户

发布于 2021-05-22 16:32:48

我也遇到了同样的问题,我发现imageio可以完成这个任务:

代码语言:javascript
运行
复制
img = imageio.imread('path/to/img', format='PNG-FI')

使用此选项,您可以读写多通道16位png图像(默认情况下,imageio使用PNG-PIL作为读取png文件的格式)。这适用于png图像,但在处理其他图像类型时,更改format可能会有所帮助(这里是可用的imageio格式的完整列表)。

要使用这种格式,您可能需要安装FreeImage插件,如文档所示。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49599539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档