python-3.x 如何在NumPy中创建包含所有RGB颜色的平滑图像?

ma8fv8wu  于 2023-06-07  发布在  Python
关注(0)|答案(1)|浏览(201)

我想在NumPy中创建一个包含每种RGB颜色的未压缩图像。
我在这里使用24位颜色深度。RGB颜色包含三个通道:红色、绿色和蓝色,每个通道可以具有256个强度,因此RGB颜色是3字节的序列,并且RGB颜色的总数是(2^8)^3 = 2^24 = 16777216。
因此,包含每种RGB颜色一次的图像将具有16777216个像素。16777216的平方根是2^12 = 4096,因此我想要一个分辨率为4096 x4096的图像。
这样的未压缩图像将精确地具有16777216*3/1048576= 48 MiB的大小。因为图像上传大小限制为2 MiB,所以我只能上传压缩版本。
以下是我到目前为止得到的:

它不平滑,因为存在高度为16像素的水平条带。
我的代码:

import cv2
import numpy as np

byte = range(256)
colors = np.array(np.meshgrid(byte, byte, byte)).T.reshape(-1,3)
striped = colors.reshape((4096, 4096, 3))
img = np.zeros((4096, 4096, 3), dtype=np.uint8)
for i in range(4096):
    img[i] = cv2.rotate(striped[i].reshape((16, 256, 3)), cv2.ROTATE_90_CLOCKWISE).reshape((-1, 3))

new_img = np.zeros((4096, 4096, 3), dtype=np.uint8)
rot90 = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
for i in range(4096):
    new_img[i] = cv2.rotate(rot90[i].reshape((256, 16, 3)), cv2.ROTATE_90_CLOCKWISE).reshape((-1, 3))
new_img = np.rot90(new_img)
cv2.imwrite('D:/BGR_colors.png', striped, (cv2.IMWRITE_PNG_COMPRESSION, 0))
cv2.imwrite('D:/BGR_colors_new.png', img, (cv2.IMWRITE_PNG_COMPRESSION, 0))
cv2.imwrite('D:/BGR_colors_new1.png', new_img, (cv2.IMWRITE_PNG_COMPRESSION, 0))
cv2.imwrite('D:/BGR_colors_compressed.png', striped, (cv2.IMWRITE_PNG_COMPRESSION, 9))
cv2.imwrite('D:/BGR_colors_new_compressed.png', img, (cv2.IMWRITE_PNG_COMPRESSION, 9))
cv2.imwrite('D:/BGR_colors_new1_compressed.png', new_img, (cv2.IMWRITE_PNG_COMPRESSION, 9))

因此,我首先使用笛卡尔积生成所有RGB颜色,并将其重塑为4096 x4096图像。
结果:

它并不平滑,它有许多小的条带,水平方向上有16个256像素的片段看起来非常相似,垂直方向上有256个16像素的条带。
有4096个大小为256 x16的矩形。我想通过消除矩形来使图像平滑。
我想去掉矩形,取每行256个像素的16组中每一组的第一个像素,把它们放在一起,然后取每组的第二个像素,依此类推。类似地,这应该发生在每列中的256组16个像素上。
我只成功地消除了水平波段,我已经尝试了许多方法来消除垂直波段,但结果只会变得更糟:

如何摆脱垂直带,如何以最少的步骤并仅使用NumPy方法获得最终结果?

lkaoscv7

lkaoscv71#

事实证明,我可以得到与我的部分预期图像相同的结果,只需对它进行排序。我只需要通过在np.sort函数调用中指定axis=1来对2D数组按列排序。这将使数组水平排序。

import cv2
import numpy as np

byte = range(256)
colors = np.array(np.meshgrid(byte, byte, byte), dtype=np.uint8).T.reshape(-1,3)
striped = colors.reshape((4096, 4096, 3))
img = np.sort(striped, axis=1)

img

但不幸的是,我现在相信我最初打算不可能的事情。
我尝试了多种方法,但都没有成功。我很努力,但找不到解决办法。
对原始图像逐行排序:
np.sort(striped, axis=0)

对图像进行两次排序(第一次按列排序,然后按行排序)
np.sort(img, axis=0)

结果似乎只包含灰色,洋红色和绿色的阴影,但它实际上包含蓝色和黄色的阴影,它真的包含所有的颜色,但不知何故只有两个曲调是突出的。我在它里面看不到蓝色,所以我的色觉阻止了我感知这样的图像。

更新

我已经设法通过调整大小和应用高斯模糊来平滑图像:

smoothed = cv2.resize(img, (1024, 1024), interpolation=cv2.INTER_CUBIC)
smoothed = cv2.GaussianBlur(smoothed, (15, 15), cv2.BORDER_DEFAULT)

这就像我最初想要的,除了它显然不包含所有RGB颜色。

相关问题