Python 验证码式图像扭曲

3
我想以与标准CAPTCHA扭曲字体相同的方式扭曲一些图像。我该如何在Python中实现?我应该使用哪些库/算法?有任何概念证明吗?免责声明:在提出这个问题之前,我已经谷歌搜索了一段时间,但我找不到令人满意的答案。由于我是新手,无法提供任何代码证明我的“研究努力”...

完全自动的图灵测试(CAPTCHA)用于区分计算机和人类。如果您想扭曲图像,我建议尝试对图像数据进行非线性重映射;显然,在此过程中将丢失一些数据点。因此,任务就是创建一个合适的内核?例如,您可以在某些物理示例中找到的一些标量场中玩耍。这就是您想要的吗? - Faultier
2
我是一个简单的人。我完全不理解你的回答。我需要一些能够实现这个功能的代码。 - mnowotka
@AndrewScottEvans - 感谢您的非常宝贵的意见。 - mnowotka
4个回答

7

好的,我认为我们快要完成了。现在假设我有一个包含实际图像的 PIL 图像实例,我想扭曲它。我该怎么办?我在这里找不到任何入口点,在 Disortions.py 中有三个类,每个类都包含一个接受图像的渲染方法。我应该创建每个实例并通过三个“render”传递我的图像吗? - mnowotka
抱歉,问题有点傻,我需要使用SineWrap。我会尝试一下并告诉你结果如何。 - mnowotka

2

扭曲图像意味着将一个像素与其相邻像素中的任何一个进行混淆。

如果算法混淆了远离的像素,则扭曲程度较高,如果混淆了附近的像素,则扭曲程度较低。

我之前几天处理过类似的问题,我使用了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))

我有一个样例: 输入图片输入图片描述 输出图片输出图片描述 希望这可以帮到你。

2
简单来说,您有一张图片,它是一个二维数组,每个数组元素代表一个像素。扭曲图像意味着将某些像素值放置到以前没有出现过的邻近位置。
举个例子,我修改了从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()

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接