我有大量的图像(数十万),对于每一个,我需要说明它的右上角是否有水印。水印总是相同的并且处于相同的位置。它采用带有符号和一些文本的功能区的形式。我正在寻找简单快捷的方法,理想情况下,不使用SciPy(因为它在我正在使用的服务器上不可用 - 但它可以使用NumPy)
到目前为止,我已经尝试使用PIL和裁剪功能来隔离图像中应该有水印的区域,然后将直方图与RMS函数进行比较(参见http://snipplr.com/view/757/compare-two-pil-images-in-python/)。由于两个方向都存在很多错误,因此效果不佳。
任何想法都会非常感激。谢谢
答案 0 :(得分:12)
另一种可能性是使用机器学习。我的背景是自然语言处理(不是计算机视觉),但我尝试使用您的问题描述创建一个训练和测试集,它似乎工作(对看不见的数据100%准确)。
训练集包含带有水印的相同图像(正例),没有水印(反面例)。
测试集包含不在训练集中的图像。
如果有兴趣,可以使用example training and testing images尝试。
完整版可用as a gist。摘录如下:
import glob
from classify import MultinomialNB
from PIL import Image
TRAINING_POSITIVE = 'training-positive/*.jpg'
TRAINING_NEGATIVE = 'training-negative/*.jpg'
TEST_POSITIVE = 'test-positive/*.jpg'
TEST_NEGATIVE = 'test-negative/*.jpg'
# How many pixels to grab from the top-right of image.
CROP_WIDTH, CROP_HEIGHT = 100, 100
RESIZED = (16, 16)
def get_image_data(infile):
image = Image.open(infile)
width, height = image.size
# left upper right lower
box = width - CROP_WIDTH, 0, width, CROP_HEIGHT
region = image.crop(box)
resized = region.resize(RESIZED)
data = resized.getdata()
# Convert RGB to simple averaged value.
data = [sum(pixel) / 3 for pixel in data]
# Combine location and value.
values = []
for location, value in enumerate(data):
values.extend([location] * value)
return values
def main():
watermark = MultinomialNB()
# Training
count = 0
for infile in glob.glob(TRAINING_POSITIVE):
data = get_image_data(infile)
watermark.train((data, 'positive'))
count += 1
print 'Training', count
for infile in glob.glob(TRAINING_NEGATIVE):
data = get_image_data(infile)
watermark.train((data, 'negative'))
count += 1
print 'Training', count
# Testing
correct, total = 0, 0
for infile in glob.glob(TEST_POSITIVE):
data = get_image_data(infile)
prediction = watermark.classify(data)
if prediction.label == 'positive':
correct += 1
total += 1
print 'Testing ({0} / {1})'.format(correct, total)
for infile in glob.glob(TEST_NEGATIVE):
data = get_image_data(infile)
prediction = watermark.classify(data)
if prediction.label == 'negative':
correct += 1
total += 1
print 'Testing ({0} / {1})'.format(correct, total)
print 'Got', correct, 'out of', total, 'correct'
if __name__ == '__main__':
main()
Training 1
Training 2
Training 3
Training 4
Training 5
Training 6
Training 7
Training 8
Training 9
Training 10
Training 11
Training 12
Training 13
Training 14
Testing (1 / 1)
Testing (2 / 2)
Testing (3 / 3)
Testing (4 / 4)
Testing (5 / 5)
Testing (6 / 6)
Testing (7 / 7)
Testing (8 / 8)
Testing (9 / 9)
Testing (10 / 10)
Got 10 out of 10 correct
[Finished in 3.5s]
答案 1 :(得分:2)
水印的位置是否准确?如何将水印应用于背景图像?
我假设水印是部分加法或乘法函数。水印图像可能是这样计算的:
resultPixel = imagePixel + (watermarkPixel*mixinValue)
mixinValue将为0.0-1.0,因此您可以通过使用(1- mixinValue)乘数重新应用水印来完成混音。这应该会产生与水印匹配的像素。只需测试结果图像与原始水印的颜色。
testPixel = resultPixel + (watermarkPixel*(1-mixinValue))
assert testPixel == watermarkPixel
当然,加水印图像的压缩可能会导致testPixel出现一些差异。
答案 2 :(得分:1)
您始终可以使用restb.ai的Specialized Image Recognition API自动执行水印检测过程。
import requests url = "https://api.restb.ai/segmentation" querystring = {"client_key":"your-free-key-here","model_id":"re_logo","image_url":"http://demo.restb.ai/img/gallery/realestate/logos-watermarks/re_logo-1.jpg"} response = requests.request("GET", url, params=querystring) print(response.text)