[英]Resizing a 48bit PNG retaining its 48bits, without dropping it to a 24bit file
I'm trying to resize the following 48bit PNG from 1242 x 375 to 256 x 256 but retain its 48 bits. 我正在尝试将以下48位PNG的大小从1242 x 375调整为256 x 256,但保留其48位。
This PNG Ground Truth Image is available for download here 此PNG地面真相图像可从此处下载
I was wondering if there is a way to code it so that the 48bits is retained ? 我想知道是否有办法对其进行编码以保留48位?
I have tried a few different libraries, however the resultant file becomes a 24bit PNG. 我尝试了几个不同的库,但结果文件变为24位PNG。
# Resize 48bit PNG file and maintain 48bit PNG when saving to file
from PIL import Image
from numpngw import write_png
import cv2
import scipy
import imageio
import skimage
PNG_Location_Filepath = "..\\..\\000000_10.png"
out = "output_images\\"
#The Pillow way
im = Image.open(PNG_Location_Filepath)
PIL_imResized = im.resize((256,256), Image.ANTIALIAS)
libraryname = "Pillow"
savedfilename = out + libraryname + '.png'
PIL_imResized.save(savedfilename)
#The numpngw way
im = cv2.imread(PNG_Location_Filepath, cv2.IMREAD_UNCHANGED)
cv2_imResized = cv2.resize(im, (256,256), interpolation=cv2.INTER_AREA)
libraryname = "numpngw"
savedfilename = out + libraryname + '.png'
write_png(savedfilename, cv2_imResized)
#The Scipy way / ImageIOSkimage way
#im = scipy.misc.imread(PNG_Location_Filepath,mode='RGB')
im = imageio.imread(PNG_Location_Filepath)
#Scipy_imResized = scipy.misc.imresize(im, [256, 256])
Skimage_imResized = skimage.transform.resize(im, (256, 256))
libraryname = "ImageIoSkimage"
savedfilename = out + libraryname + '.png'
#scipy.misc.imsave(savedfilename, Scipy_imResized)
imageio.imwrite(savedfilename, Skimage_imResized)
# `imread` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
# Use ``imageio.imread`` instead
# `imresize` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
# Use ``skimage.transform.resize`` instead
# `imsave` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0
# Use ``imageio.imwrite`` instead.
I also tried this code, but received an error message 我也试过这段代码,但收到了错误信息
import cv2
import imageio
imageio.plugins.freeimage.download()
PNG_Location_Filepath = "..\\..\\000000_10.png"
Resized_Location_Filepath = "..\\..\\000000_10_resized.png"
imageio.plugins.freeimage.FreeimagePngFormat.Reader._open
(PNG_Location_Filepath)
img_in_imageio = imageio.imread(PNG_Location_Filepath, format='PNG-FI')
Resized_Image = cv2.resize(img_in_imageio, (256,256))
Saved_Filename = Resized_Location_Filepath
imageio.imwrite(Saved_Filename, Resized_Image, format='PNG-FI')
Error: 错误:
Traceback (most recent call last): File "c:\.vscode\extensions\ms-python.python-2019.6.24221\pythonFiles\ptvsd_launcher.py", line 43, in <module> main(ptvsdArgs) File "c:\.vscode\extensions\ms-python.python-2019.6.24221\pythonFiles\lib\python\ptvsd\__main__.py", line 434, in main
run()
File "c:\.vscode\extensions\ms-python.python-2019.6.24221\pythonFiles\lib\python\ptvsd\__main__.py", line 312, in run_file
runpy.run_path(target, run_name='__main__')
File "C:\AppData\Local\Programs\Python\Python37\lib\runpy.py", line 263, in run_path
pkg_name=pkg_name, script_name=fname)
File "C:\AppData\Local\Programs\Python\Python37\lib\runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "C:\AppData\Local\Programs\Python\Python37\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "c:\Documents\DeepLearning\Learning\Code\Sandpit\Resize48bitKeeping48bit.py", line 10, in <module>
img_in_imageio = imageio.plugins.freeimage.FreeimagePngFormat.Reader._open(PNG_Location_Filepath)
File "C:\AppData\Local\Programs\Python\Python37\lib\site-packages\freeimage.py", line 221, in _open
return FreeimageFormat.Reader._open(self, flags)
File "C:\AppData\Local\Programs\Python\Python37\lib\site-packages\imageio\plugins\freeimage.py", line 81, in _open
self._bm = fi.create_bitmap(self.request.filename, self.format.fif, flags)
AttributeError: 'str' object has no attribute 'request'
So I tried this code 所以我尝试了这段代码
import cv2
import imageio
imageio.plugins.freeimage.download()
PNG_Location_Filepath = "..\\..\\000000_10.png"
Resized_Location_Filepath = "..\\..\\000000_10_resized.png"
img_in_imageio = imageio.imread(PNG_Location_Filepath, format='PNG-FI')
#img_in_imageio.resize((256,256,3))
Resized_Image = cv2.resize(img_in_imageio, (256,256))
Saved_Filename = Resized_Location_Filepath
imageio.imwrite(Saved_Filename, img_in_imageio, format='PNG-FI')
And this copied the file, but it didn't resize it 这复制了文件,但没有调整大小
I am expecting the file format at uint48 to be maintained, however the output file seems to be 24bits 我希望维护uint48的文件格式,但输出文件似乎是24位
You can use imageio
with freeimage
library using format='PNG-FI'
in imageio.imread
/ imageoio.imwrite
. 您可以在
imageio.imread
/ imageoio.imwrite
使用format='PNG-FI'
将imageio
与freeimage
库结合使用。
Based on information in source code of freeimage.py in imageio
to install freeimage
library you can use imageio
: 根据imageio中
imageio
源代码中的信息安装freeimage
库,你可以使用imageio
:
in command line (on Linux it works even without full path) 在命令行中(在Linux上它即使没有完整路径也可以工作)
imageio_download_bin freeimage
using python code 使用python代码
import imageio imageio.plugins.freeimage.download()
Probably if you install library ( .dll
/ .so
) directly from FreeImage webpage then it will also work. 可能如果你直接从FreeImage网页安装库(
.dll
/ .so
)那么它也可以工作。
Image has to be copied ( img.copy()
). 必须复制图像(
img.copy()
)。 Because making image smaller it removed pixels with the biggest values so I work with part of image and make its bigger. 因为使图像变小,所以删除了具有最大值的像素,因此我使用部分图像并使其更大。
# read 48bit color
img = imageio.imread("..\\..\\000000_10.png", format='PNG-FI')
# max values in image
print('shape:', img.shape)
print('max R:', img[:,:,0].max())
print('max G:', img[:,:,1].max())
print('max B:', img[:,:,2].max())
print('---')
# cut-off part of image (with)
img = img.copy()
img = img[370:375,1020:1025,:]
img = img.copy()
img.resize((256,256,3))
print('shape:', img.shape)
print('max R:', img[:,:,0].max())
print('max G:', img[:,:,1].max())
print('max B:', img[:,:,2].max())
print('---')
# find X,Y for first max red value
print('max X:', img[:,:,0].max(axis=0).argmax())
print('max Y:', img[:,:,0].max(axis=1).argmax())
print(' flat:', img[:,:,0].argmax())
print('---')
# find X,Y for all max red values
max_r = img[:,:,0].max()
for y, row in enumerate(img[:,:,0]):
for x, it in enumerate(row):
if it == max_r:
print('value/x/y:', max_r, x, y)
# write 48bit color
imageio.imwrite('output_48bit.png', img, format='PNG-FI')
Output: 输出:
shape: (375, 1242, 3)
max R: 40827
max G: 36674
max B: 1
---
shape: (256, 256, 3)
max R: 40827
max G: 36506
max B: 1
---
max X: 14
max Y: 0
flat: 14
---
value/x/y: 40827 14 0
In Linux I can use program `file in command line to check if file use 48bit color (16bits per color) 在Linux中,我可以在命令行中使用程序`文件来检查文件是否使用48位颜色(每种颜色16位)
$ file 000000_10.png
000000_10.png: PNG image data, 1242 x 375, 16-bit/color RGB, non-interlaced
$ file output_48bit.png
output_48bit.png: PNG image data, 256 x 256, 16-bit/color RGB, non-interlaced
If you have RGBA
then it will use 64bit color. 如果你有
RGBA
那么它将使用64位颜色。
Example from imageio
issues: Unable to properly read multi-channel 16-bit png files imageio
问题示例: 无法正确读取多通道16位png文件
import imageio
import numpy as np
img_out = np.zeros((256, 256, 4), dtype=np.uint16)
color_grad = np.reshape(np.arange(2**16), (256,-1))
img_out[:, :, 0] = color_grad
img_out[:, :, 1] = np.rot90(color_grad, 1)
img_out[:, :, 2] = np.rot90(color_grad, 2)
img_out[:, :, 3] = np.rot90(color_grad, 3)
print('Write unique values: R={}, G={}, B={}, A={}'.format(
len(set(img_out[:, :, 0].flatten().tolist())),
len(set(img_out[:, :, 1].flatten().tolist())),
len(set(img_out[:, :, 2].flatten().tolist())),
len(set(img_out[:, :, 3].flatten().tolist()))))
imageio.imwrite('64bit_imageio.png', img_out, format='PNG-FI')
img_in_imageio = imageio.imread('64bit_imageio.png', format='PNG-FI')
print('imageio PNG unique values: R={}, G={}, B={}, A={}'.format(
len(set(img_in_imageio[:, :, 0].flatten().tolist())),
len(set(img_in_imageio[:, :, 1].flatten().tolist())),
len(set(img_in_imageio[:, :, 2].flatten().tolist())),
len(set(img_in_imageio[:, :, 3].flatten().tolist()))))
Output: 输出:
Write unique values: R=65536, G=65536, B=65536, A=65536
imageio PNG unique values: R=65536, G=65536, B=65536, A=65536
output_48bit.png: PNG image data, 5 x 5, 16-bit/color RGB, non-interlaced
EDIT: Your last code with more readable names for variables (lower_case_names) and few free lines to make it also more readable. 编辑:您的最后一个代码具有更易读的变量名称(lower_case_names)和少量自由行,使其更具可读性。
In original code you had mess so finally you wrote original image instead of resized one. 在原始代码中你弄得很乱,所以最后你写了原始图像而不是调整大小的图像。
import cv2
import imageio
# need it only once
#imageio.plugins.freeimage.download()
input_filename = "..\\..\\000000_10.png"
output_filename = "..\\..\\000000_10_resized.png"
input_image = imageio.imread(input_filename, format='PNG-FI')
output_image = cv2.resize(input_image, (256, 256))
imageio.imwrite(output_filename, output_image, format='PNG-FI')
# Resize 48bit PNG file and maintain 48bit PNG when saving to file WORKING
import cv2
import imageio
imageio.plugins.freeimage.download()
PNG_Location_Filepath = "..\\..\\000000_10.png"
Resized_Location_Filepath = "..\\..\\000000_10_resized.png"
img_in_imageio = imageio.imread(PNG_Location_Filepath, format='PNG-FI')
Resized_Image = cv2.resize(img_in_imageio, (256,256))
Saved_Filename = Resized_Location_Filepath
imageio.imwrite(Saved_Filename, Resized_Image, format='PNG-FI')
#This works to resize the image, keeping 48bits
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.