我正在尝试用python3创建一个图像系统,以便在web应用程序中使用。其思想是从磁盘加载一个图像,并在其中添加一些随机噪声。当我尝试这一点时,我得到的是一个完全随机的图像,与原作不相似:
import cv2
import numpy as np
from skimage.util import random_noise
from random import randint
from pathlib import Path
from PIL import Image
import io
image_files = [
{
'name': 'test1',
'file': 'test1.png'
},
{
'name': 'test2',
'file': 'test2.png'
}
]
def gen_image():
rand_image = randint(0, len(image_files)-1)
image_file = image_files[rand_image]['file']
image_name = image_files[rand_image]['name']
image_path = str(Path().absolute())+'/img/'+image_file
img = cv2.imread(image_path)
noise_img = random_noise(img, mode='s&p', amount=0.1)
img = Image.fromarray(noise_img, 'RGB')
fp = io.BytesIO()
img.save(fp, format="PNG")
content = fp.getvalue()
return content
gen_image()
我也尝试过使用pypng:
import png
# Added the following to gen_image()
content = png.from_array(noise_img, mode='L;1')
content.save('image.png')
我如何从磁盘加载一个png(带有alpha透明度),向它添加一些噪声,然后返回它,这样它就可以通过web服务器代码(flask、aiohttp等)显示了。你知道吗
正如makayla的回答所指出的,这使得它更好:noise_img = (noise_img*255).astype(np.uint8)
但是颜色仍然是错误的,并且没有透明度。你知道吗
更新后的函数如下:
def gen_image():
rand_image = randint(0, len(image_files)-1)
image_file = image_files[rand_image]['file']
image_name = image_files[rand_image]['name']
image_path = str(Path().absolute())+'/img/'+image_file
img = cv2.imread(image_path)
cv2.imshow('dst_rt', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# Problem exists somewhere below this line.
img = random_noise(img, mode='s&p', amount=0.1)
img = (img*255).astype(np.uint8)
img = Image.fromarray(img, 'RGB')
fp = io.BytesIO()
img.save(fp, format="png")
content = fp.getvalue()
return content
这将弹出一个预噪声图像并返回噪声图像。返回图像中存在RGB(和alpha)问题。你知道吗
我想问题是它应该是RGBA
,但是当我换成它时,我得到了ValueError: buffer is not large enough
鉴于所有的新信息,我更新了我的答案与一些调试问题的更多技巧。你知道吗
我发现了一个site here可以创建示例透明图像。我创建了一个64x64青色(R=0,G=255,B=255)的图像,透明层为0.5。我用这个来测试你的代码。你知道吗
我在图像中读取了两种比较方法:
im1 = cv2.imread(fileName)
和im2 = cv2.imread(fileName,cv2.IMREAD_UNCHANGED)
。np.shape(im1)
返回(64,64,3)
和np.shape(im2)
返回(64,64,4)
。这就是为什么需要该标志opencv中的默认imread设置将在透明图像中作为普通RGB图像读取。你知道吗但是,opencv读取为BGR而不是RGB,并且由于无法使用opencv保存,因此需要将其转换为正确的顺序,否则图像将具有相反的颜色。例如,当使用反转颜色查看我的青色图像时,显示如下:
您可以使用openCV的color conversion function像这样更改它
im = cv2.cvtColor(im, cv2.COLOR_BGRA2RGBA)
(Here是所有颜色转换代码的列表)。再次,如果需要,请仔细检查图像的大小,自从您将其转换为RGBA后,它仍应具有四个通道。你知道吗现在可以将噪波添加到图像中。正如您所知,这也会给您的alpha通道添加噪声,随机地使一些像素更透明,而另一些像素更不透明。来自skimage的random_noise function将图像转换为float并将其返回为float。这意味着图像值(通常是0到255之间的整数)将转换为0到1之间的十进制值。您的行
img = Image.fromarray(noise_img, 'RGB')
不知道如何处理浮点噪声img。这就是为什么当你保存它的时候,以及当我试图显示它的时候,图像都是乱七八糟的。你知道吗所以我把我的青色图像,加上噪音,然后把浮点数转换回8位。你知道吗
现在使用
img.show()
看起来像这样(屏幕截图):我使用了PIL库来保存我的图像,而不是openCV,所以它尽可能接近您的代码。你知道吗
我将图像加载到powerpoint中,以再次检查它在使用此方法保存图像时是否保持了透明度。以下是powerpoint中覆盖在红色圆圈上的已保存图像的屏幕截图:
相关问题 更多 >
编程相关推荐