Python CAPTCHA般的图像失真

时间:2013-09-30 10:03:53

标签: python image-processing python-imaging-library captcha

我想以标准CAPTCHA禁用字体的方式来删除一些图像。我如何在python中实现它?我应该使用哪些库/算法?任何概念验证?

免责声明:在我提出这个问题之前,谷歌搜索了一段时间,但我找不到任何令人满意的答案。我是新手,所以我不能提供任何证明我'研究工作'的代码......

4 个答案:

答案 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))

我有一个样本: 输入图片enter image description here 输出图像enter image description here

我希望这会有所帮助。

答案 3 :(得分:0)

您可以调整django-simple-captcha的代码,https://raw.github.com/mbi/django-simple-captcha/master/captcha/views.py中有一个功能captcha_image,您可以轻松调整。