将全彩图像转换为三色图像以进行电子墨水显示

问题描述 投票:0回答:4

我希望能够自动将全彩色图像转换为三色(黑色/红色/白色)以用于电子墨水显示屏(Waveshare 7.5")。现在我只是让屏幕处理它,但是正如预期的那样,复杂的图像被冲掉了。

我可以应用任何算法或过滤器来使事情更加明显吗?

现在我正在使用Python,但如果有必要,我也不反对其他语言/环境。

好形象:

Good image

洗掉的图像:

washed out

python image-processing raspberry-pi dithering e-ink
4个回答
2
投票

您可以制作自己的调色板,其中包含 3 种可接受的颜色,如下所示:

magick xc:red xc:white xc:black +append palette.gif

然后您可以将其应用到您的图像中,如下所示:

magick input.png +dither -remap palette.gif result.png

enter image description here

如果您想将其直接发送到帧缓冲区并且它支持 RB888,您可以尝试运行如下命令:

magick input.png +dither -remap palette.gif -depth 8 RGB:/dev/fb0

2
投票

只是在 Mark Setchell 的答案中添加一点。对于打印,您最好对 3 种颜色进行抖动处理。 所以这是使用 Imagemagick 7 进行抖动和不抖动的图像。如果使用 Imagemagick 6,请将 magick 替换为 Convert。

输入:

enter image description here

创建 3 个调色板:

magick xc:red xc:white xc:black +append palette.gif

带抖动(默认为 Floyd-Steinberg):

magick input.png -remap palette.gif result.png

[![在此处输入图像描述][2]][2]

无抖动

magick input.png -dither none -remap palette.gif result2.png

[![在此处输入图像描述][3]][3]

如果你想要Python,那么你可以尝试Python Wand。它基于 Imagemagick。

补充:

要将红色和黑色分成两个图像,每个图像用黑色表示,其余的用白色表示,您可以执行以下操作并在注释中根据需要另存为 BMP。 (您可以根据需要从上方抖动或不抖动来执行此操作)

magick result.png -color-threshold "red-red" -negate red.bmp
magick result.png -color-threshold "black-black" -negate black.bmp

红色:

enter image description here

黑色:

enter image description here


2
投票

只是在马克和弗雷德的答案中添加一些内容。我在 Raspberry Pi 上使用 ImageMagick,这是版本 < 7 and uses "convert". Some of the commands Fred had suggested didn't work for that version. Here's what I did to resize, remap and dither, and split the image into white-and-black and white-and-red sub-images.

# Create palette with red, white and black colors
convert xc:red xc:white xc:black +append palette.gif

# Resize input file into size suitable for ePaper Display - 264x176
# Converting to BMP.
# Note, if working with JPG, it is a lossy
# format and subsequently remapping and working with it results
# in the color palette getting overwritten - we just convert to BMP
# and work with that instead
convert $1 -resize 264x176^ -gravity center -extent 264x176 resized.bmp

# Remap the resized image into the colors of the palette using
# Floyd Steinberg dithering (default)
# Resulting image will have only 3 colors - red, white and black
convert resized.bmp -remap palette.gif result.bmp


# Replace all the red pixels with white - this
# isolates the white and black pixels - i.e the "black"
# part of image to be rendered on the ePaper Display
convert -fill white -opaque red result.bmp result_black.bmp 

# Similarly, Replace all the black pixels with white - this
# isolates the white and red pixels - i.e the "red"
# part of image to be rendered on the ePaper Display
convert -fill white -opaque black result.bmp result_red.bmp

我还使用 Python Wand 实现了它,这是 ImageMagick 上的 Python 层

# This function takes as input a filename for an image
# It resizes the image into the dimensions supported by the ePaper Display
# It then remaps the image into a tri-color scheme using a palette (affinity)
# for remapping, and the Floyd Steinberg algorithm for dithering
# It then splits the image into two component parts:
# a white and black image (with the red pixels removed)
# a white and red image (with the black pixels removed)
# It then converts these into PIL Images and returns them
# The PIL Images can be used by the ePaper library to display
def getImagesToDisplay(filename):
    print(filename)
    red_image = None
    black_image = None
    try:
        with WandImage(filename=filename) as img:
            img.resize(264, 176)
            with WandImage() as palette:
                with WandImage(width = 1, height = 1, pseudo ="xc:red") as red:
                    palette.sequence.append(red)
                with WandImage(width = 1, height = 1, pseudo ="xc:black") as black:
                    palette.sequence.append(black)
                with WandImage(width = 1, height = 1, pseudo ="xc:white") as white:
                    palette.sequence.append(white)
                palette.concat()
                img.remap(affinity=palette, method='floyd_steinberg')
                
                red = img.clone()
                black = img.clone()
                red.opaque_paint(target='black', fill='white')
                # This is not nececessary - making the white and red image
                # white and black instead - left here FYI
                # red.opaque_paint(target='red', fill='black')
        
                black.opaque_paint(target='red', fill='white')
                
                red_image = Image.open(io.BytesIO(red.make_blob("bmp")))
                black_image = Image.open(io.BytesIO(black.make_blob("bmp")))
    except Exception as ex:
        print ('traceback.format_exc():\n%s',traceback.format_exc())

    return (red_image, black_image)

这是我在 Hackster 上的项目的文章(包括完整的源代码链接) - https://www.hackster.io/sridhar-rajagopal/photostax-digital-epaper-photo-frame-84d4ed

我已将马克和弗雷德归功于那里 - 谢谢!

Example conversion of photograph to tri-color Floyd-Steinberg dithered image


1
投票

您似乎正在为每个像素选择最接近的颜色。 看看“抖动算法”是否更适合您的目的。 一般来说,抖动算法在确定如何为给定像素着色时会考虑相邻像素。

编辑:就 PIL(Python 图像库)而言,
抖动到任意一组三种颜色似乎并不简单

,至少从 2012 年开始是这样。

© www.soinside.com 2019 - 2024. All rights reserved.