Reputation: 17258
I would like to disort some images the same way standard CAPTCHA disorts fonts. How would I achieve it in python? What libraries/algorithms I should use? Any proof-of-concept?
DISCLAIMER: I was googling for some time before I asked this question but I couldn't find any satisfying answer. I'm new to the field so I can't provide any code proving my 'research effort'...
Upvotes: 3
Views: 2969
Reputation: 115
Distorting an image means shuffling of an pixel with any of its neighbouring pixel.
If algorithm shuffle a far pixel, distortion is high, and if a nearby pixel is shuffled distortion is low
I had worked on a similar problem few days ago, I've used PIL for this.
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')
The following expression is the key here, you can modify or create any similar expression by doing little mathematics, although this may also suit you as it is.
x_shift, y_shift = ( int(abs(math.sin(x)*width/delta_x)) ,
int(abs(math.tan(math.sin(y)))*height/delta_y))
I have a sample:
Input image
Output Image
I hope this helps.
Upvotes: 2
Reputation: 4511
You can adapt the code of django-simple-captcha, there's a function captcha_image
in https://raw.github.com/mbi/django-simple-captcha/master/captcha/views.py that you can adapt easily.
Upvotes: 0
Reputation: 20317
I think you are looking for PyCaptcha http://svn.navi.cx/misc/trunk/pycaptcha/
The actual code to distort is here: http://svn.navi.cx/misc/trunk/pycaptcha/Captcha/Visual/Distortions.py
The work is done by PIL's transform function, like this:
image.transform(image.size, Image.MESH, mesh, self.filtering)
The rest of the code is there essentially to generate the mesh that is used.
Upvotes: 7
Reputation: 1326
put simple: you have an image, which is a 2D array, each array element represents a pixel. Distorting an image means, that you put some pixel value also to neighboring places where it has not been before.
To give you something like an example, I modified an example from the matplotlib
; I relocate the regular x/y to an irregular spacing, thus, distorting the image. For captcha looks, you have to come up with some more creative remapping than I did.
More professional would obviously be to just remap the values to the array to keep the regular spaced data.
So some fun is still left for you to play around (; Hope this helped you out as a starter.
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()
Upvotes: 2