diff options
author | RaNaN <Mast3rRaNaN@hotmail.de> | 2009-09-04 22:54:33 +0200 |
---|---|---|
committer | RaNaN <Mast3rRaNaN@hotmail.de> | 2009-09-04 22:54:33 +0200 |
commit | 5a7d201ab8a07184cb38e0b5022441da899b4ad4 (patch) | |
tree | 0a6862e584a775ce64a67846623404d3f17bf320 /module | |
parent | Removed tag v0.2 (diff) | |
download | pyload-5a7d201ab8a07184cb38e0b5022441da899b4ad4.tar.xz |
pyLoad 0.2.1v0.2.1
Diffstat (limited to 'module')
-rw-r--r-- | module/captcha/GigasizeCom.py | 15 | ||||
-rw-r--r-- | module/captcha/MegauploadCom.py | 14 | ||||
-rw-r--r-- | module/captcha/NetloadIn.py | 25 | ||||
-rw-r--r-- | module/captcha/ShareonlineBiz.py | 61 | ||||
-rw-r--r-- | module/captcha/__init__.py | 0 | ||||
-rw-r--r-- | module/captcha/captcha.py | 292 |
6 files changed, 407 insertions, 0 deletions
diff --git a/module/captcha/GigasizeCom.py b/module/captcha/GigasizeCom.py new file mode 100644 index 000000000..136092181 --- /dev/null +++ b/module/captcha/GigasizeCom.py @@ -0,0 +1,15 @@ +from captcha import OCR + +class GigasizeCom(OCR): + def __init__(self): + OCR.__init__(self) + + def get_captcha(self, image): + self.load_image(image) + self.threshold(2.8) + self.run_gocr() + return self.result_captcha + +if __name__ == '__main__': + ocr = GigasizeCom() + print ocr.get_captcha('gigasize-com/7.jpg') diff --git a/module/captcha/MegauploadCom.py b/module/captcha/MegauploadCom.py new file mode 100644 index 000000000..40939c792 --- /dev/null +++ b/module/captcha/MegauploadCom.py @@ -0,0 +1,14 @@ +from captcha import OCR + +class MegauploadCom(OCR): + def __init__(self): + OCR.__init__(self) + + def get_captcha(self, image): + self.load_image(image) + self.threshold(2.8) + self.run_tesser() + return self.result_captcha + +if __name__ == '__main__': + ocr = MegauploadCom() diff --git a/module/captcha/NetloadIn.py b/module/captcha/NetloadIn.py new file mode 100644 index 000000000..9799a6a2b --- /dev/null +++ b/module/captcha/NetloadIn.py @@ -0,0 +1,25 @@ +from captcha import OCR + +class NetloadIn(OCR): + def __init__(self): + OCR.__init__(self) + + def get_captcha(self, image): + self.load_image(image) + self.to_greyscale() + self.clean(3) + self.clean(3) + self.run_tesser() + + self.correct({ + ("$", "g"): "5", + }) + + return self.result_captcha + +if __name__ == '__main__': + import urllib + ocr = NetloadIn() + urllib.urlretrieve("http://netload.in/share/includes/captcha.php", "captcha.png") + + print ocr.get_captcha('captcha.png') diff --git a/module/captcha/ShareonlineBiz.py b/module/captcha/ShareonlineBiz.py new file mode 100644 index 000000000..91124f181 --- /dev/null +++ b/module/captcha/ShareonlineBiz.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +#Copyright (C) 2009 kingzero, RaNaN +# +#This program is free software; you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation; either version 3 of the License, +#or (at your option) any later version. +# +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +#See the GNU General Public License for more details. +# +#You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. +# +### +from captcha import OCR + +class ShareonlineBiz(OCR): + def __init__(self): + OCR.__init__(self) + + def get_captcha(self, image): + self.load_image(image) + self.to_greyscale() + self.image = self.image.resize((160, 50)) + self.pixels = self.image.load() + self.threshold(1.85) + #self.eval_black_white(240) + #self.derotate_by_average() + + letters = self.split_captcha_letters() + + final = "" + for letter in letters: + self.image = letter + self.run_tesser() + final += self.result_captcha + + #replace common errors + final = self.correct({ + "A": "4", + "‘5": "3", + ("‘1", "T"): "7", + ("‘L", "B", "'L"): "2", + "b": "6", + ("I", "X"): "1" + }, final) + + return final + + #tesseract at 60% + +if __name__ == '__main__': + import urllib + ocr = ShareonlineBiz() + urllib.urlretrieve("http://www.share-online.biz/captcha.php", "captcha.jpeg") + print ocr.get_captcha('captcha.jpeg') diff --git a/module/captcha/__init__.py b/module/captcha/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/module/captcha/__init__.py diff --git a/module/captcha/captcha.py b/module/captcha/captcha.py new file mode 100644 index 000000000..ffb165dbf --- /dev/null +++ b/module/captcha/captcha.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +#Copyright (C) 2009 kingzero, RaNaN +# +#This program is free software; you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation; either version 3 of the License, +#or (at your option) any later version. +# +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +#See the GNU General Public License for more details. +# +#You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. +# +### +import logging +import subprocess +import tempfile +import threading + +import Image + +class RunThread(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + + def e(self, command, inputdata=None): + """execute command """ + self.command = command + self.inputdata = inputdata + self.result = "" + self.start() + self.join(10) + return self.result + + def run(self): + """Run a command and return standard output""" + pipe = subprocess.PIPE + popen = subprocess.Popen(self.command, stdout=pipe, stderr=pipe) + outputdata, errdata = popen.communicate(self.inputdata) + assert (popen.returncode == 0), \ + "Error running: %s\n\n%s" % (self.command, errdata) + self.result = outputdata + +class OCR(object): + def __init__(self): + self.logger = logging.getLogger("log") + + def load_image(self, image): + self.image = Image.open(image) + self.pixels = self.image.load() + self.result_captcha = '' + + def unload(self): + """delete all tmp images""" + pass + + def threshold(self, value): + self.image = self.image.point(lambda a: a * value + 10) + + def run(self, command, inputdata=None): + """Run a command and return standard output""" + # OLD METHOD + # pipe = subprocess.PIPE + # popen = subprocess.Popen(command, stdout=pipe, stderr=pipe) + # outputdata, errdata = popen.communicate(inputdata) + # assert (popen.returncode == 0), \ + # "Error running: %s\n\n%s" % (command, errdata) + # return outputdata + + thread = RunThread() + result = thread.e(command, inputdata) + return result + + def run_gocr(self): + tmp = tempfile.NamedTemporaryFile(suffix=".jpg") + self.image.save(tmp) + self.result_captcha = self.run(['gocr', tmp.name]).replace("\n", "") + + def run_tesser(self): + self.logger.debug("create tmp tif") + tmp = tempfile.NamedTemporaryFile(suffix=".tif") + self.logger.debug("create tmp txt") + tmpTxt = tempfile.NamedTemporaryFile(suffix=".txt") + self.logger.debug("save tiff") + self.image.save(tmp.name, 'TIFF') + self.logger.debug("run tesseract") + self.run(['tesseract', tmp.name, tmpTxt.name.replace(".txt", "")]) + self.logger.debug("run cat") + self.result_captcha = self.run(['cat', tmpTxt.name]).replace("\n", "") + + def get_captcha(self): + raise NotImplementedError + + def to_greyscale(self): + if self.image.mode != 'L': + self.image = self.image.convert('L') + + self.pixels = self.image.load() + + def eval_black_white(self, limit): + self.pixels = self.image.load() + w, h = self.image.size + for x in xrange(w): + for y in xrange(h): + if self.pixels[x, y] > limit: + self.pixels[x, y] = 255 + else: + self.pixels[x, y] = 0 + + def clean(self, allowed): + pixels = self.pixels + + w, h = self.image.size + + for x in xrange(w): + for y in xrange(h): + if pixels[x, y] == 255: continue + # no point in processing white pixels since we only want to remove black pixel + count = 0 + + try: + if pixels[x-1, y-1] != 255: count += 1 + if pixels[x-1, y] != 255: count += 1 + if pixels[x-1, y + 1] != 255: count += 1 + if pixels[x, y + 1] != 255: count += 1 + if pixels[x + 1, y + 1] != 255: count += 1 + if pixels[x + 1, y] != 255: count += 1 + if pixels[x + 1, y-1] != 255: count += 1 + if pixels[x, y-1] != 255: count += 1 + except: + pass + + # not enough neighbors are dark pixels so mark this pixel + # to be changed to white + if count < allowed: + pixels[x, y] = 1 + + # second pass: this time set all 1's to 255 (white) + for x in xrange(w): + for y in xrange(h): + if pixels[x, y] == 1: pixels[x, y] = 255 + + self.pixels = pixels + + def derotate_by_average(self): + """rotate by checking each angle and guess most suitable""" + + w, h = self.image.size + pixels = self.pixels + + for x in xrange(w): + for y in xrange(h): + if pixels[x, y] == 0: + pixels[x, y] = 155 + + highest = {} + counts = {} + + for angle in range(-45, 45): + + tmpimage = self.image.rotate(angle) + + pixels = tmpimage.load() + + w, h = self.image.size + + for x in xrange(w): + for y in xrange(h): + if pixels[x, y] == 0: + pixels[x, y] = 255 + + + count = {} + + for x in xrange(w): + count[x] = 0 + for y in xrange(h): + if pixels[x, y] == 155: + count[x] += 1 + + sum = 0 + cnt = 0 + + for x in count.values(): + if x != 0: + sum += x + cnt += 1 + + avg = sum / cnt + counts[angle] = cnt + highest[angle] = 0 + for x in count.values(): + if x > highest[angle]: + highest[angle] = x + + highest[angle] = highest[angle] - avg + + hkey = 0 + hvalue = 0 + + for key, value in highest.iteritems(): + if value > hvalue: + hkey = key + hvalue = value + + self.image = self.image.rotate(hkey) + pixels = self.image.load() + + for x in xrange(w): + for y in xrange(h): + if pixels[x, y] == 0: + pixels[x, y] = 255 + + if pixels[x, y] == 155: + pixels[x, y] = 0 + + self.pixels = pixels + + def split_captcha_letters(self): + captcha = self.image + started = False + letters = [] + width, height = captcha.size + bottomY, topY = 0, height + pixels = captcha.load() + + for x in xrange(width): + black_pixel_in_col = False + for y in xrange(height): + if pixels[x, y] != 255: + if started == False: + started = True + firstX = x + lastX = x + + if y > bottomY: bottomY = y + if y < topY: topY = y + if x > lastX: lastX = x + + black_pixel_in_col = True + + if black_pixel_in_col == False and started == True: + rect = (firstX, topY, lastX, bottomY) + new_captcha = captcha.crop(rect) + + w, h = new_captcha.size + if w > 5 and h > 5: + letters.append(new_captcha) + + started = False + bottomY, topY = 0, height + + return letters + + def correct(self, values, var=None): + + if var: + result = var + else: + result = self.result_captcha + + for key, item in values.iteritems(): + + if key.__class__ == str: + result = result.replace(key, item) + else: + for expr in key: + result = result.replace(expr, item) + + if var: + return result + else: + self.result_captcha = result + + +if __name__ == '__main__': + ocr = OCR() + ocr.load_image("B.jpg") + ocr.to_greyscale() + ocr.eval_black_white(140) + ocr.derotate_by_avergage() + ocr.run_gocr() + print "GOCR", ocr.result_captcha + ocr.run_tesser() + print "Tesseract", ocr.result_captcha + ocr.image.save("derotated.jpg") + |