0

我有一张扫描图像,基本上是黑色打印在一些奇怪的(非灰色)背景上,比如绿色或黄色(想想旧纸)。

我怎样才能摆脱绿色/黄色并接收与原始图像的灰色结构一样多的灰色图片?即我想保持字母周围的灰色以实现抗锯齿效果或灰色区域,但我想将任何甚至是远程绿色/黄色的东西变成纯白色?

请注意,背景绝不是同质的;所以算法应该能够接受颜色和误差范围或颜色范围。

加分:如何自动确定背景颜色?

我想将 Python 与 Imaging Library 或 ImageMagick 一起使用。

注意:我知道像unpaper这样的包。我对 unpaper 的问题是它生成的黑白图像可能对 OCR 软件看起来不错,但对人眼来说却不是。

4

3 回答 3

1

我更多的是 C++ 而不是 python 程序员,所以我不能给你一个代码示例。但一般算法是这样的:

查找背景颜色:您制作图像的直方图。直方图应该有两个峰代表背景和前景色。因为您知道背景具有更高的强度,所以您选择具有更高强度的峰,这就是背景颜色。现在你有了 RGB 背景(R_bg, G_bg, B_bg)

将背景设置为白色:循环遍历所有像素并计算到背景的距离:

distance = sqrt((R_bg - R_pixel) ^ 2 + (G_bg - G_pixel) ^ 2 + (B_bg - B_pixel) ^ 2)

如果距离小于阈值,则将像素设置为白色。您可以尝试不同的阈值,直到获得良好的结果。

于 2009-03-20T17:18:03.320 回答
1

我知道这个问题很老,但我正在玩 ImageMagick 试图做类似的事情,并想出了这个:

convert text.jpg -fill white -fuzz 50% +opaque black out.jpg

这将其转换为:

在此处输入图像描述

进入这个:

在此处输入图像描述

至于“平均”颜色,我使用了这个:

convert text.jpg -colors 2 -colorspace RGB -format %c histogram:info:-
 5894: ( 50, 49, 19) #323113 rgb(50,49,19)
19162: (186,187, 87) #BABB57 rgb(186,187,87)       <- THIS ONE !

这是这种颜色:

在此处输入图像描述

经过更多的实验,我可以得到这个:

在此处输入图像描述

使用这个:

convert text.jpg -fill black -fuzz 50% -opaque rgb\(50,50,10\) -fill white +opaque black out.jpg
于 2014-08-05T17:42:54.880 回答
1

不久前,我希望使任意背景颜色透明并开发了这个脚本。它采用图像中最流行的(背景)颜色并创建一个透明度与与背景颜色的距离成正比的 alpha 蒙版。获取 RGB 颜色空间距离对于大图像来说是一个昂贵的过程,所以我尝试使用 numpy 和快速整数 sqrt 逼近操作进行一些优化。首先转换为 HSV 可能是正确的方法。如果你还没有解决你的问题,我希望这会有所帮助:

from PIL import Image
import sys, time, numpy

fldr = r'C:\python_apps'
fp = fldr+'\\IMG_0377.jpg'

rz = 0  # 2 will halve the size of the image, etc..

# ----------------

im = Image.open(fp)

if rz:
    w,h = im.size
    im = im.resize((w/rz,h/rz))
    w,h = im.size

h = im.histogram()
rgb = r0,g0,b0 = [b.index(max(b)) for b in [ h[i*256:(i+1)*256] for i in range(3) ]]

def isqrt(n):
    xn = 1
    xn1 = (xn + n/xn)/2
    while abs(xn1 - xn) > 1:
        xn = xn1
        xn1 = (xn + n/xn)/2
    while xn1*xn1 > n:
        xn1 -= 1
    return xn1

vsqrt = numpy.vectorize(isqrt)

def dist(image):
    imarr = numpy.asarray(image, dtype=numpy.int32)  # dtype=numpy.int8
    d = (imarr[:,:,0]-r0)**2 + (imarr[:,:,1]-g0)**2 + (imarr[:,:,2]-b0)**2
    d = numpy.asarray((vsqrt(d)).clip(0,255), dtype=numpy.uint8)
    return Image.fromarray(d,'L')

im.putalpha(dist(im))
im.save(fldr+'\\test.png')
于 2009-05-30T20:50:00.320 回答