Skip to content

Instantly share code, notes, and snippets.

@nagos
Created November 15, 2017 09:55
Show Gist options
  • Save nagos/d6b8e71ccf8cc23133f746970fd06861 to your computer and use it in GitHub Desktop.
Save nagos/d6b8e71ccf8cc23133f746970fd06861 to your computer and use it in GitHub Desktop.
Распознавание капчи на нейронных сетях
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Распознавание Captcha"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
]
}
],
"source": [
"from keras.models import Sequential\n",
"from keras.layers import Conv2D, MaxPooling2D\n",
"from keras.layers import Activation, Dropout, Flatten, Dense\n",
"from keras.preprocessing.image import load_img, img_to_array\n",
"from keras.models import load_model\n",
"import PIL\n",
"import matplotlib.pyplot as plt\n",
"import numpy\n",
"from matplotlib.pyplot import figure, imshow, axis\n",
"from captcha.image import ImageCaptcha\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Загрузка моделей"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"space_model = load_model('model_space.h5')\n",
"digit_model = load_model('model_digit.h5')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# dimensions of our images.\n",
"img_width, img_height = 55, 100\n",
"digit_width = 50\n",
"w_size = 5\n",
"w_offset = 20"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_part_x(img, i):\n",
" i = numpy.round(i)\n",
" r = img.crop((i, 0, i+img_width, img_height))\n",
" x = numpy.asarray(r, dtype='float32') / 255\n",
" x = numpy.expand_dims(x, axis=0)\n",
" return x\n",
"def get_part(img, i):\n",
" x = get_part_x(img, i*img_width)\n",
" return x\n",
"def draw_box(img, x, v):\n",
" draw = PIL.ImageDraw.Draw(img)\n",
" color = numpy.random.randint(0, 255, 3)\n",
" draw.polygon([\n",
" (x, 5), \n",
" (x+img_width, 5), \n",
" (x+img_width, img_height-5), \n",
" (x, img_height-5)\n",
" ], \n",
" outline=(color[0], color[1], color[2], 0))\n",
" draw.text((x+5, 5), \"%d\" % v, fill=(0,0,0,128))\n",
"def calc_value(x):\n",
" return numpy.argmax(x)\n",
"def show_img(img):\n",
" imshow(numpy.asarray(img, dtype='float32') / 255) "
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# объеденить квадраты, которые пересекаются на img_width/2\n",
"def merge_boxes(boxes):\n",
" ret = []\n",
" x = -1\n",
" x1 = -1\n",
" for b in boxes:\n",
" if (x==-1):\n",
" x = b\n",
" x1 = b\n",
" elif (b-x > digit_width/2):\n",
" ret.append((x+x1)/2)\n",
" x = b\n",
" x1 = b\n",
" else:\n",
" x1 = b\n",
" if (x!=-1):\n",
" ret.append((x+x1)/2)\n",
" return ret"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# найти кандидатов\n",
"def find_boxes(img):\n",
" boxes = []\n",
" for i in range(3*5-1):\n",
" x = get_part(img, i/4)\n",
" p = space_model.predict(x)\n",
" if(calc_value(p)):\n",
" v = i/4*img_width\n",
" boxes.append(v)\n",
" return boxes"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"image = ImageCaptcha(width=digit_width*5, height=100, font_sizes=[80], fonts=[\"/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-M.ttf\"])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Digits: 168\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x7f4d223616a0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"digits = numpy.random.randint(0, 9, 3)\n",
"img = image.generate_image(\" %d%d%d\" % (digits[0], digits[1], digits[2]))\n",
"print(\"Digits: %d%d%d\" % (digits[0], digits[1], digits[2]))\n",
"\n",
"img_out2 = img.copy()\n",
"boxes = find_boxes(img)\n",
"# Объеденить квадраты и распознать\n",
"boxes_filtered = merge_boxes(boxes)\n",
"for b in boxes_filtered:\n",
" x = get_part_x(img, b)\n",
" v = calc_value(digit_model.predict(x))\n",
" draw_box(img_out2, b, v)\n",
"show_img(img_out2)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_captcha():\n",
" digits = numpy.random.randint(0, 9, 3)\n",
" img = image.generate_image(\" %d%d%d\" % (digits[0], digits[1], digits[2]))\n",
" img_out = img.copy()\n",
" boxes = find_boxes(img)\n",
" boxes_filtered = merge_boxes(boxes)\n",
" decoded = []\n",
" for b in boxes_filtered:\n",
" x = get_part_x(img, b)\n",
" v = calc_value(digit_model.predict(x))\n",
" decoded.append(v)\n",
" draw_box(img_out, b, v)\n",
" return digits.tolist(), decoded, img_out"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"error [8, 6, 6] [5, 6]\n",
"error [0, 8, 6] [0, 8, 6, 3]\n",
"Errors: 0.20%\n"
]
}
],
"source": [
"e = 0\n",
"n = 1000\n",
"for i in range(n):\n",
" d, p, img = get_captcha()\n",
" if(d!=p):\n",
" print(\"error\", d, p)\n",
" img.save(\"errors/error_%d.png\" % e)\n",
" e += 1\n",
"print(\"Errors: %.2f%%\" % (e/n*100))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment