我想以标准CAPTCHA禁用字体的方式来删除一些图像。我如何在python中实现它?我应该使用哪些库/算法?任何概念验证?
免责声明:在我提出这个问题之前,谷歌搜索了一段时间,但我找不到任何令人满意的答案。我是新手,所以我不能提供任何证明我'研究工作'的代码......答案 0 :(得分:7)
我认为您正在寻找PyCaptcha http://svn.navi.cx/misc/trunk/pycaptcha/
要扭曲的实际代码在这里:http://svn.navi.cx/misc/trunk/pycaptcha/Captcha/Visual/Distortions.py
工作由PIL的转换功能完成,如下所示:
image.transform(image.size, Image.MESH, mesh, self.filtering)
其余的代码基本上是生成使用的网格。
答案 1 :(得分:2)
简单说明:你有一个图像,它是一个2D数组,每个数组元素代表一个像素。扭曲图像意味着您将一些像素值也放在以前没有的相邻位置。
为了给你一个类似的例子,我修改了matplotlib
中的一个例子;我将常规x / y重新定位到不规则的间距,从而扭曲图像。对于验证码外观,你必须提出一些比我更有创意的重新映射。
更专业的显然是将值重新映射到数组以保持常规间隔数据。
所以仍然有一些乐趣可供你玩耍(;希望这有助于你作为首发。
import pylab as P
import numpy as N
# http://matplotlib.org/examples/images_contours_and_fields
# /pcolormesh_levels.html
dx, dy = 0.05, 0.05
y, x = N.mgrid[slice(1, 5 + dy, dy),
slice(1, 5 + dx, dx)]
z = N.sin(x) ** 10 + N.cos(10 + y * x) * N.cos(x)
#distort from regular pixels to something else...
x1 = N.exp(x)
y1 = N.sqrt(y)
P.figure()
P.pcolormesh(x,y,z)
P.figure()
P.pcolormesh(x1,y1,z)
P.show()
答案 2 :(得分:1)
扭曲图像意味着将像素与其任何相邻像素混合。
如果算法对远像素进行混洗,则失真很高,如果附近的像素被混洗,则失真很低
我几天前曾遇到过类似的问题,我已经使用了PIL。
import math
from PIL import Image
img = Image.open('image.jpg') #open a image
width ,height = img.size
img_data = img.load() #loading it, for fast operation
output = Image.new('RGB',img.size,"gray") #New image for putput
output_img = output.load() #loading this also, for fast operation
pix=[0, 0]
delta_x = 40 #you can lower the delta for high distortion
delta_y = 90 #or you can higher the delta for low distortion
for x in range(width):
for y in range(height):
#following expression calculates the snuffling
x_shift, y_shift = ( int(abs(math.sin(x)*width/delta_x)) ,
int(abs(math.tan(math.sin(y)))*height/delta_y))
#checking bounds
if x + x_shift < width:
pix[0] = x + x_shift
else:
pix[0] = x
if y + y_shift < height :
pix[1] = y + y_shift
else:
pix[1] = y
# do the shuffling
output_img[x,y] = img_data[tuple(pix)]
#Saving the image
output.save('output.jpeg')
以下表达式是这里的关键,你可以通过做一些小数学修改或创建任何类似的表达式,虽然这也可能适合你。
x_shift, y_shift = ( int(abs(math.sin(x)*width/delta_x)) ,
int(abs(math.tan(math.sin(y)))*height/delta_y))
我有一个样本: 输入图片 输出图像
我希望这会有所帮助。
答案 3 :(得分:0)
您可以调整django-simple-captcha的代码,https://raw.github.com/mbi/django-simple-captcha/master/captcha/views.py中有一个功能captcha_image
,您可以轻松调整。