【问题标题】:Convert a Picture to RGB Dots Image (Half Toning Like Effect)将图片转换为 RGB 点图像(半色调效果)
【发布时间】:2018-05-15 04:33:21
【问题描述】:

我试图向学生展示 RGB 颜色模型如何创建特定颜色(或者让他们相信它确实如此)。所以我想拍照并将每个像素转换为 RGB 表示,这样当您放大时,您看到的不是单个彩色像素,而是 RGB 颜色。

我已经这样做了,但是由于一些非常明显的原因,转换后的图片要么被洗掉了,要么比原来的更暗(这是一个小不便,但我认为如果我能让它更像原创)。

这里有两张“缩小”的图片:

这里是“中等缩放”,开始显示转换后的图片中的 RGB 伪影:

这是一张放大到可以清楚地看到各个像素 RGB 方块的图片:

您会注意到像素周围的恒定颜色;那是图片的平均RGB。我把它放在那里以便您可以看到单个像素(否则您只会看到红色/绿色/蓝色阴影的行/列)。如果我完全去掉那个空间,图像会更暗,如果我用白色替换它,那么图像看起来会变淡(缩小时)。

我知道为什么以这种方式显示会导致颜色变暗:“纯红色”会带有完全黑色的蓝色和绿色。从某种意义上说,如果我要拍一张全红的照片,它的亮度基本上是原图的 1/3。

所以我的问题是:

1:是否有任何可用的工具已经可以做到这一点(或类似的东西)?

2:关于如何使转换后的图像更接近原始图像的任何想法?

对于第二个问题,我当然可以增加每个“RGB 像素”(每个正方形中的三个水平条纹)的亮度,但是增加多少呢?我当然不能只将 RGB 整数乘以 3(显然是对我上面所说的补偿)。我想知道是否有一些方法可以调整我的背景颜色来补偿我?还是只是需要为每张图片摆弄一些东西?

【问题讨论】:

  • 它不禁看起来褪色/变暗,因为您将只显示原始光强度的 1/3。在强度达到 255 之前,乘以 3 是一个不错的策略。
  • 您是否考虑过简单地在 LCD 屏幕或平板电脑上使用放大镜?
  • 这是个好主意。 (我的意思是这样解释RGB。)
  • 对于它的价值,在关于 RGB 值的简短讲座后,我确实与学生一起尝试过。当他们放大却发现那些看起来像国旗的小方块时,发出了很多的呜呜声。我认为这是一个很好的钩子。一些学生确实询问了为什么缩小的图像看起来像现在这样。请注意,这不是一门编程课程,所以我试图解释他们所看到的(以及它与原始图像的关系),但显然没有详细说明这是怎么回事完成。
  • @RingØ 是 Ray Wise,来自 STNG 剧集Who Watches the Watchers

标签: image-processing colors image-effects


【解决方案1】:

您认为可以通过将所有值乘以 3 来保持亮度是正确的。只有一个小问题:图像中的 RGB 值使用伽马校正,因此强度不是线性的。您需要对这些值进行去伽玛,相乘,然后再次伽玛校正它们。

您还需要丢失每个像素周围的边框。这些边框占据了最终图像的 7/16,这实在是无法弥补。我尝试将每隔一个像素旋转 90 度,虽然它给出了明确的锯齿形图案,但它确实明确了像素边界的位置。

当您在图像查看器中缩小时,您也可能会看到 Gamma 问题。许多观众在调整大小时不会费心进行伽马校正。有关深入解释,请参阅Gamma error in picture scaling,并使用最后提供的测试图像。完全放弃缩放并简单地退出监视器可能会更好。

这是一些 Python 代码和从结果图像中截取的部分。

from PIL import Image
im = Image.open(filename)
im2 = Image.new('RGB', (im.size[0]*3, im.size[1]*3))
ld1 = im.load()
ld2 = im2.load()
for y in range(im.size[1]):
    for x in range(im.size[0]):
        rgb = ld1[x,y]
        rgb = [(c/255)**2.2 for c in rgb]
        rgb = [min(1.0,c*3) for c in rgb]
        rgb = tuple(int(255*(c**(1/2.2))) for c in rgb)
        x2 = x*3
        y2 = y*3
        if (x+y) & 1:
            for x3 in range(x2, x2+3):
                ld2[x3,y2] = (rgb[0],0,0)
                ld2[x3,y2+1] = (0,rgb[1],0)
                ld2[x3,y2+2] = (0,0,rgb[2])
        else:
            for y3 in range(y2, y2+3):
                ld2[x2,y3] = (rgb[0],0,0)
                ld2[x2+1,y3] = (0,rgb[1],0)
                ld2[x2+2,y3] = (0,0,rgb[2])

【讨论】:

  • 很好的答案和关于交替像素以解决边界问题的建议非常好。
【解决方案2】:

不要在这上面浪费太多时间。如果其中一张的信息较少,则无法使两张图片看起来相同。您仍然拥有您的计算机,它会在缩小时以奇怪的方式对您的图像进行二次采样。

只需在课堂上放一个放大镜,这样他们就可以在手机或其他屏幕上看到自己,或者以不同的放大倍数显示屏幕图片。

如果您想坚持使用软件,请将图像的分辨率提高三倍,不要使用空行和空列,或者至少将它们设为黑色以增加对比度并将 RGB 分量缩放到全范围。

【讨论】:

  • 这是正确的答案。一个放大镜。孩子们这样做也会更有趣,而不是看你提前准备的任何图像。
  • 如今许多手机的分辨率都很高,以至于您可能需要显微镜而不是放大镜。不过,桌面显示器应该可以很好地工作。
  • @CrisLuengo 那是真的(关于预先准备好的图像),但是我实际上让他们下载了他们选择的图片,然后通过这个“过滤器”运行它以查看他们的自己的 带有 RGB 方块的图像。
  • 还为在缩小时指出子采样而竖起大拇指。我认为它在缩放级别上更强大一些,您可以清楚地看到 RGB 方块(非常小,但肯定存在),但您可以看到一些细节。
  • 实际上,“像素化”图片中的信息并不比原始图片中的信息少(特别是因为我使用的是 PNG 压缩——如果你使用 JPEG 肯定会更少,这很讽刺,因为 JPEG 文件结束了比 PNG 大很多)。了解我如何生成“像素化”图像后,您可以完全从“像素化”图像中恢复原件(同样因为我使用 PNG 来生成“像素化”图像)。
【解决方案3】:

为什么不保留放大的图像作为背景?这将使两个图像在缩小时看起来相同,而 RGB 条在放大时将保持清晰可见。

如果不是,则使用整个图像的平均颜色以保持相似的强度,但会保留洗涤效果。

中间选项是在图像上应用强大的低通滤波器以平滑所有细节并将其用作背景,但我认为与第一种方法相比没有真正的优势。

【讨论】:

    猜你喜欢
    • 2011-03-02
    • 2018-08-26
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    相关资源
    最近更新 更多