我有一张扫描图像,在一些奇怪的(非灰色)背景上基本上是黑色的,比如绿色或黄色(想想旧纸)。
如何摆脱绿色/黄色并获得原始图像的灰色结构完整的灰色图片?即我希望在抗锯齿效果的字母周围保持灰色或灰色区域,但是我想把任何甚至是远程绿色/黄色变成纯白色的东西?
请注意,背景绝不是同质的;所以算法应该能够接受颜色和误差范围或颜色范围。
奖励积分:如何自动确定背景颜色?
我想将Python与影像库或ImageMagick一起使用。
注意:我知道像unpaper这样的软件包。我的问题是,它产生的B& W图像可能看起来很适合OCR软件但不适合人眼。
答案 0 :(得分:1)
我比C ++程序员更喜欢C ++,所以我不能给你一个代码示例。但是通用算法是这样的:
寻找背景颜色:
您可以制作图像的直方图。直方图应该有两个代表背景和前景色的峰。因为您知道背景具有更高的强度,所以您可以选择具有更高强度的峰值,即背景颜色。
现在你有了RGB背景(R_bg, G_bg, B_bg)
将背景设置为白色: 循环遍历所有像素并计算到背景的距离:
distance = sqrt((R_bg - R_pixel) ^ 2 + (G_bg - G_pixel) ^ 2 + (B_bg - B_pixel) ^ 2)
如果距离小于阈值,则将像素设置为白色。您可以尝试不同的阈值,直到获得良好的结果。
答案 1 :(得分: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')
答案 2 :(得分: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