Spaces:
Runtime error
Runtime error
| import cv2 | |
| from numpy import asarray as np_as_array | |
| from numpy import all as np_all | |
| class CaptchaProcessor: | |
| WHITE_RGB = (255, 255, 255) | |
| def __init__(self, data: bytes): | |
| self.img = cv2.imdecode( | |
| np_as_array(bytearray(data), dtype="uint8"), | |
| cv2.IMREAD_ANYCOLOR | |
| ) | |
| def threshold(self): | |
| self.img = cv2.threshold(self.img, 0, 255, cv2.THRESH_OTSU)[1] | |
| def convert_color_space(self, target_space: int): | |
| self.img = cv2.cvtColor(self.img, target_space) | |
| def get_background_color(self) -> tuple: | |
| return tuple(self.img[0, 0]) | |
| def resize(self, x: int, y: int): | |
| self.img = cv2.resize(self.img, (x, y)) | |
| def save(self, name: str): | |
| cv2.imwrite(name, self.img) | |
| def get_letters_color(self) -> tuple: | |
| colors = [] | |
| for y in range(self.img.shape[1]): | |
| for x in range(self.img.shape[0]): | |
| color = tuple(self.img[x, y]) | |
| if color != self.WHITE_RGB: colors.append(color) | |
| return max(set(colors), key=colors.count) | |
| def replace_color(self, target: tuple, to: tuple): | |
| self.img[np_all(self.img == target, axis=-1)] = to | |
| def replace_colors(self, exception: tuple, to: tuple): | |
| self.img[np_all(self.img != exception, axis=-1)] = to | |
| def increase_contrast(self, alpha: float, beta: float): | |
| self.img = cv2.convertScaleAbs(self.img, alpha=alpha, beta=beta) | |
| def increase_letters_size(self, add_pixels: int): | |
| pixels = [] | |
| for y in range(self.img.shape[1]): | |
| for x in range(self.img.shape[0]): | |
| if self.img[x, y] == 0: pixels.append((x, y)) | |
| for y, x in pixels: | |
| for i in range(1, add_pixels + 1): | |
| self.img[y + i, x] = 0 | |
| self.img[y - i, x] = 0 | |
| self.img[y, x + i] = 0 | |
| self.img[y, x - i] = 0 | |
| self.img[y + i, x] = 0 | |
| self.img[y - i, x] = 0 | |
| self.img[y, x + i] = 0 | |
| self.img[y, x - i] = 0 | |
| # Отдаление символов друг от друга | |
| # Может многократно повысить точность, но я так и не придумал правильную реализацию | |
| def distance_letters(self, cf: float): | |
| pixels = [] | |
| for y in range(self.img.shape[1]): | |
| for x in range(self.img.shape[0]): | |
| if self.img[x, y] == 0: pixels.append((x, y)) | |
| for y, x in pixels: | |
| self.img[y, x] = 255 | |
| center = self.img.shape[1] / 2 | |
| z = self.img.shape[1] / x | |
| if z >= 2: self.img[y, x - int((900 // x) * cf)] = 0 | |
| else: self.img[y, x + int((900 // x) * cf)] = 0 | |
| def slice_letters(self): | |
| contours, hierarchy = cv2.findContours(self.img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) | |
| letter_image_regions = [] | |
| letters = [] | |
| for idx, contour in enumerate(contours): | |
| if hierarchy[0][idx][3] != 0: continue | |
| (x, y, w, h) = cv2.boundingRect(contour) | |
| if w / h > 1.5: | |
| half_width = int(w / 2) | |
| letter_image_regions.append((idx, x, y, half_width, h)) | |
| letter_image_regions.append((idx, x + half_width, y, half_width, h)) | |
| else: | |
| letter_image_regions.append((idx, x, y, w, h)) | |
| letter_image_regions = sorted(letter_image_regions, key=lambda z: z[1]) | |
| for _, x, y, w, h in letter_image_regions: | |
| frame = self.img[y:y + h, x:x + w] | |
| if frame.shape[1] > 35: continue | |
| frame = cv2.resize(frame, (20, 40)) | |
| frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) | |
| letters.append(frame) | |
| return letters | |
| def show(self): | |
| cv2.imshow("Captcha Processor", self.img) | |
| cv2.waitKey(0) | |
| def from_file_name(cls, name: str): | |
| file = open(name, "rb") | |
| processor = cls(file.read()) | |
| file.close() | |
| return processor |