def decode(image, threshold=True): image = image.astype(np.uint8) # threshold if threshold: _, image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) image = crop_letter(image.astype(np.uint8)) # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] if "_upper" in letter: letter = letter[0:1] if letter in classifier.FONT_MAP: return classifier.FONT_MAP[letter] return letter
def solve_captcha(image_file, model_data): (model, graph, lb) = model_data letter_images = preprocess_image(image_file) if not letter_images: return "" # Create an output image and a list to hold our predicted letters predictions = [] # loop over the letters for letter_image in letter_images : # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(letter_image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) with graph.as_default(): # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # Print the captcha's text captcha_text = "".join(predictions) return captcha_text
def prediction(lb, model_made): captcha_image_files = list(paths.list_images("generated_captcha_images")) captcha_image_files = np.random.choice(captcha_image_files, size=(10, ), replace=False) for image_file in captcha_image_files: image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image = cv2.copyMakeBorder(image, 20, 20, 20, 20, cv2.BORDER_REPLICATE) thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = contours[0] if imutils.is_cv2() else contours[1] letter_image_regions = [] for contour in contours: (x, y, w, h) = cv2.boundingRect(contour) if w / h > 1.25: half_width = int(w / 2) letter_image_regions.append((x, y, half_width, h)) letter_image_regions.append((x + half_width, y, half_width, h)) else: letter_image_regions.append((x, y, w, h)) if len(letter_image_regions) != 4: continue letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) output = cv2.merge([image] * 3) predictions = [] for letter_bounding_box in letter_image_regions: x, y, w, h = letter_bounding_box letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2] letter_image = resize_to_fit(letter_image, 20, 20) letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) prediction = model_made.predict(letter_image) letter = lb.inverse_transform(prediction)[0] predictions.append(letter) cv2.rectangle(output, (x - 2, y - 2), (x + w + 4, y + h + 4), (0, 255, 0), 1) cv2.putText(output, letter, (x - 5, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 255, 0), 2) captcha_text = "".join(predictions) print("CAPTCHA text is: {}".format(captcha_text)) plt.imshow(output, cmap='gray', interpolation='bicubic') plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis plt.show()
def load_data( img_rows, img_cols, ): IMAGES_FOLDER = "dataset" MODEL_LABELS_FILENAME = "model_labels.dat" # Resize trainging data = [] labels = [] # loop over the input images for image_file in paths.list_images(IMAGES_FOLDER): image = cv2.imread(image_file) # # Resize the letter so it fits in a 80x80 pixel box image = resize_to_fit(image, img_rows, img_cols) # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-2] # Add the letter image and it's label to our training data data.append(image) labels.append(label) # scale the raw pixel intensities to the range [0, 1] (this improves training) data = np.array(data, dtype="float") / 255.0 labels = np.array(labels) # Split the training data into separate train and test sets (X_train, X_valid, Y_train, Y_valid) = train_test_split(data, labels, test_size=0.25, random_state=0) # Convert the labels (letters) into one-hot encodings that Keras can work with lb = LabelBinarizer().fit(Y_train) Y_train = lb.transform(Y_train) Y_valid = lb.transform(Y_valid) # Save the label. Useful when predicting with open(MODEL_LABELS_FILENAME, "wb") as f: pickle.dump(lb, f) return X_train, Y_train, X_valid, Y_valid
def solve(image_file): image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image = cv2.copyMakeBorder(image, 20, 20, 20, 20, cv2.BORDER_REPLICATE) thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = contours[0] if imutils.is_cv2() else contours[1] letter_image_regions = [] for contour in contours: (x, y, w, h) = cv2.boundingRect(contour) if w / h > 1.25: half_width = int(w / 2) letter_image_regions.append((x, y, half_width, h)) letter_image_regions.append((x + half_width, y, half_width, h)) else: letter_image_regions.append((x, y, w, h)) letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) output = cv2.merge([image] * 3) predictions = [] for letter_bounding_box in letter_image_regions: x, y, w, h = letter_bounding_box letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2] letter_image = resize_to_fit(letter_image, 20, 20) letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) prediction = model.predict(letter_image) print (prediction) letter = lb.inverse_transform(prediction)[0] predictions.append(letter) cv2.rectangle(output, (x - 2, y - 2), (x + w + 4, y + h + 4), (0, 255, 0), 1) cv2.putText(output, letter, (x - 5, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 255, 0), 2) captcha_text = "".join(predictions) #print("CAPTCHA text is: {}".format(captcha_text)) #cv2.imshow("Output", output) cv2.waitKey() return (captcha_text)
def solve_captcha(image_file): preprocess_image(image_file) with open(MODEL_LABELS_FILENAME, "rb") as f: lb = pickle.load(f) model = load_model(MODEL_FILENAME) image = cv2.imread("transformed.png", cv2.IMREAD_GRAYSCALE) thresh = cv2.threshold(image, 200, 255, cv2.THRESH_TRUNC | cv2.THRESH_OTSU)[1] thresh = cv2.adaptiveThreshold(thresh, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 3) letter_image_regions = [] img_h, img_w = image.shape grid_w = 20 # crop width img_h = 40 padding = 11 for w in range(6): bbox = (padding + w * grid_w, 7, padding + (w + 1) * (grid_w), img_h - 2) letter_image_regions.append(bbox) if len(letter_image_regions) != 6: return "" letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) predictions = [] for letter_bounding_box in letter_image_regions: x, y, w, h = letter_bounding_box letter_image = thresh[y:h, x - 1:w + 1] letter_image = resize_to_fit(letter_image, 20, 20) letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) prediction = model.predict(letter_image) letter = lb.inverse_transform(prediction)[0] predictions.append(letter) return "".join(predictions)
def tensor(): try: tensor = np.load("tensor.npy") labels = np.load("labels.npy") except: data = [] labels = [] for image_file in paths.list_images("extracted_letter_images"): image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image = resize_to_fit(image, 20, 20) image = np.expand_dims(image, axis=2) label = image_file.split(os.path.sep)[-2] data.append(image) labels.append(label) tensor = np.array(data, dtype="float") / 255.0 labels = np.array(labels) return tensor, labels
def get_accuracy(image_characters, model, lb): """ Tests a model on a few defined training sets from the greedy segmenter :returns overallaccuracy plot, character_accuracy plot """ result = "" for row in range(image_characters.shape[0]): for col in range(image_characters.shape[1]): image = image_characters[row][col].astype(np.uint8) image = crop_letter(image.astype(np.uint8)) # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] if "_upper" in letter: letter = letter[0:1] if letter in classifier.FONT_MAP: letter = classifier.FONT_MAP[letter] result += letter print(len(result)) print(len(EXPECTED)) letter_match = {} total_matched = 0 for character in range(len(EXPECTED)): if EXPECTED[character] not in letter_match: letter_match[EXPECTED[character]] = 0 if EXPECTED[character] == result[character]: total_matched += 1 letter_match[EXPECTED[character]] = letter_match[EXPECTED[character]] + 1 return float(total_matched) / float(len(EXPECTED)), letter_match
def ocr_image_to_label(text='0000'): download_images_to_folder(text=text,images_folder='temp') captcha_image_files = list(paths.list_images('temp')) # loop over the image paths # for image_file in captcha_image_files: image_file = 'temp/'+text+'.jpeg' img = Image.open(image_file) img = two_value(img) clearNoise(img, 0, 3, 1) letter_image_regions = letter_split(img) # [letter_image_regions[i].save(str(i+1))+'.jpeg' for i in range(4)] [letter_image_regions[i].save(str(i + 1) + '.jpeg') for i in range(4)] predictions = [] # loop over the lektters for i in range(4): # Grab the coordinates of the letter in the image # x, y, w, h = letter_bounding_box # Extract the letter from the original image with a 2-pixel margin around the edge # letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2] letter_bounding_box = cv2.imread(str(i + 1) + '.jpeg') letter_bounding_box = cv2.cvtColor(letter_bounding_box, cv2.COLOR_BGR2GRAY) letter_image = resize_to_fit(letter_bounding_box, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # Print the captcha's text captcha_text = "".join(predictions) return captcha_text
def load_data(): # initialize the data and labels data = [] labels = [] # loop over the input images for image_file in paths.list_images(LETTER_IMAGES_FOLDER): # Load the image and convert it to grayscale image = cv2.imread(image_file) if type(image) == type(None): print(f"{image_file} returned None from cv2.imread") os.remove(image_file) continue image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Resize the letter so it fits in a 20x20 pixel box image = resize_to_fit(image, 20, 20) # Add a third channel dimension to the image to make Keras happy image = np.expand_dims(image, axis=2) # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-2] # Add the letter image and it's label to our training data data.append(image) labels.append(label) # scale the raw pixel intensities to the range [0, 1] (this improves training) data = np.array(data, dtype="float") / 255.0 labels = np.array(labels) n_samples = len(data) data = data.reshape((n_samples, -1)) # .squeeze() to remove unwanted dimension https://stackoverflow.com/a/25453912/5140672 return data.squeeze(), labels
def resizeImage(image_file): global current current = current + 1 print("[INFO] processing image {}/{}".format(current, row)) image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image = resize_to_fit(image, 20, 20) label = image_file.split(os.path.sep)[-2] save_path = os.path.join(LETTER_IMAGES_FOLDER_YZH, label) filename = image_file.split(os.path.sep)[-1] full_save_path = os.path.join(save_path, filename) # print(save_path) if not os.path.exists(save_path): os.makedirs(save_path) cv2.imwrite(full_save_path, image)
# characteristic before cropping w = 22 #left, upper, right, lower = 14, 27, 38, 60 left, upper, right, lower = 5, 25, 45, 65 # loop over the letters for i in range(5): # Extract the letter from the original image with a 2-pixel margin around the edge letter_image = image[upper:lower, left:right] #cv2.imshow("letter_image", letter_image) #cv2.waitKey() # Re-size the letter image to 50x40 pixels to match training data letter_image = resize_to_fit(letter_image, 40, 40) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # draw the prediction on the output image cv2.rectangle(output, (left, upper), (right, lower), (0, 255, 0), 1) cv2.putText(output, letter, (left - 5, upper - 5),
for sze_crp in size_crops: LETTER_IMAGES_FOLDER = ''.join((letters_dir,'/',str(sze_crp),'/')) # initialize the data and labels data = [] labels = [] # loop over the input images for image_file in paths.list_images(LETTER_IMAGES_FOLDER): # Load the image and convert it to grayscale image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Resize the letter so it fits in a 28x28 pixel box image = resize_to_fit(image, 28, 28) # Add a third channel dimension to the image to make Keras happy image = np.expand_dims(image, axis=2) # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-2] # Add the letter image and it's label to our training data data.append(image) labels.append(label) # scale the raw pixel intensities to the range [0, 1] (this improves training) data = np.array(data, dtype="float") / 255.0 labels = np.array(labels)
# In[8]: LETTER_IMAGES_FOLDER = letters_train_dir # initialize the data and labels data_l_train = [] labels_l_train = [] # loop over the input images for image_file in paths.list_images(LETTER_IMAGES_FOLDER): # Load the image and convert it to grayscale image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Resize the letter so it fits in a 28x28 pixel box image = resize_to_fit(image, 32, 32) # Add a third channel dimension to the image to make Keras happy image = np.expand_dims(image, axis=2) # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-1].split('.')[-2].split('-')[1] # Add the letter image and it's label to our training data data_l_train.append(image) labels_l_train.append(label) # In[9]: LETTER_IMAGES_FOLDER = letters_test_dir
# Create a list to hold output images and our predicted letters predictions = [] outputs = [] # loop over the lektters for letter_bounding_box in letter_image_regions: output = cv2.merge([gray] * 3) # Grab the coordinates of the letter in the image x, y, w, h = letter_bounding_box # Extract the letter from the original image with a 2-pixel margin around the edge letter_image = gray[y - 2:y + h + 2, x - 2:x + w + 2] # Re-size the letter image to 20x20 pixels to match training data letter_image = helpers.resize_to_fit(letter_image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # draw the prediction on the output image cv2.rectangle(output, (x - 2, y - 2), (x + w + 4, y + h + 4), (0, 255, 0), 1)
f for f in os.listdir(predict_image_directory) if f.lower().endswith(('.png', '.jpg', '.jpeg')) ] list_images_labels = [] for f in files_: data = [] real_age = i # img = image.load_img(os.path.join(predict_image_directory, f), target_size=(img_width, img_height)) image = cv2.imread(os.path.join(predict_image_directory, f)) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) image = resize_to_fit(image, image_size, image_size) #image = np.expand_dims(image, axis=2) #image = image / 255.0 #data = np.array(data, dtype="float") / 255.0 # x = image.img_to_array(img) image = np.expand_dims(image, axis=2) image = np.expand_dims(image, axis=0) value = model.predict_classes(image) #print(value) #list_images_labels.append((f, real_age, value[0]))
def Solve(img_str): # Load the image and convert it to grayscale nparr = np.fromstring(img_str, np.uint8) image = cv2.imdecode(nparr, cv2.IMREAD_COLOR) # cv2.IMREAD_COLOR in OpenCV 3.1 image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Add some extra padding around the image image = cv2.copyMakeBorder(image, 20, 20, 20, 20, cv2.BORDER_CONSTANT, value=(255, 255, 255)) # threshold the image (convert it to pure black and white) thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] # find the contours (continuous blobs of pixels) the image contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Hack for compatibility with different OpenCV versions contours = contours[0] letter_image_regions = [] # Now we can loop through each of the four contours and extract the letter # inside of each one for contour in contours: # Get the rectangle that contains the contour (x, y, w, h) = cv2.boundingRect(contour) # Compare the width and height of the contour to detect letters that # are conjoined into one chunk if w / h > 1.7: # This contour is too wide to be a single letter! # Split it in half into two letter regions! return (False) else: # This is a normal letter by itself letter_image_regions.append((x, y, w, h)) # If we found more or less than 4 letters in the captcha, our letter extraction # didn't work correcly.Skip rather than wating 5 seconds if len(letter_image_regions) != 5: return (False) # Sort the detected letter images based on the x coordinate to make sure # we are processing them from left-to-right so we match the right image # with the right letter letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) # Create an output image and a list to hold our predicted letters predictions = [] # loop over the lektters for letter_bounding_box in letter_image_regions: # Grab the coordinates of the letter in the image x, y, w, h = letter_bounding_box # Extract the letter from the original image with a 2-pixel margin around the edge letter_image = image[y - 6:y + h + 6, x - 2:x + w + 2] # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(letter_image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # Print the captcha's text captcha_text = "".join(predictions) return (captcha_text)
if len(single_letter_image) != 4: continue # Sort the letters w r t x coordinate, not to make mistakes when comparing the label single_letter_image = sorted(single_letter_image, key=lambda x: x[0]) # Save each letter separately output = cv2.merge([grayscale_image] * 3) predictions = [] for letter_bounding_box in single_letter_image: x, y, w, h = letter_bounding_box extracted_letter_image = grayscale_image[y - 2:y + h + 2, x - 2:x + w + 2] # resize to 20x20 because it's the dimension of the input extracted_letter_image = resize_to_fit(extracted_letter_image, 20, 20) # we also need a 4d tensor extracted_letter_image = np.expand_dims(extracted_letter_image, axis=2) extracted_letter_image = np.expand_dims(extracted_letter_image, axis=0) prediction = model.predict(extracted_letter_image) # remember we used a label binarizer... letter = lb.inverse_transform(prediction)[0] predictions.append(letter) cv2.rectangle(output, (x - 2, y - 2), (x + w + 4, y + h + 4), (0, 255, 0), 1) cv2.putText(output, letter, (x - 5, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 255, 0), 2) # Print result captcha_text = "".join(predictions) if captcha_correct_text != format(captcha_text):
letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) # Create an output image and a list to hold our predicted letters output = cv2.merge([image] * 3) predictions = [] # loop over the lektters for letter_bounding_box in letter_image_regions: # Grab the coordinates of the letter in the image x, y, w, h = letter_bounding_box # Extract the letter from the original image with a 2-pixel margin around the edge letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2] # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(letter_image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # draw the prediction on the output image cv2.rectangle(output, (x - 2, y - 2), (x + w + 4, y + h + 4), (0, 255, 0), 1) cv2.putText(output, letter, (x - 5, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 255, 0), 2)
MODEL_FILENAME = "captcha_model.hdf5" MODEL_LABELS_FILENAME = "model_labels.dat" # initialize the data and labels data = [] labels = [] # loop over the input images for image_file in paths.list_images( LETTER_IMAGES_FOLDER): #paths将该文件夹下的文件名变成列表 # Load the image and convert it to grayscale image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #颜色空间转换函数,将BGR格式转换成灰度图片 # Resize the letter so it fits in a 30x30 pixel box image = resize_to_fit(image, 30, 30) # Add a third channel dimension to the image to make Keras happy#这个happy也太秀了 image = np.expand_dims(image, axis=2) # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-2] #os.path.sep路径分隔符,一般是"/" # Add the letter image and it's label to our training data data.append(image) #print(data) labels.append(label) #print(labels) # scale the raw pixel intensities to the range [0, 1] (this improves training) data = np.array(data, dtype="float") / 255.0
from keras.layers.core import Flatten, Dense from keras.preprocessing.image import ImageDataGenerator from helpers import resize_to_fit SINGLE_LETTERS_FOLDER = "extracted_letter_images" MODEL_FILENAME = "captcha_model.hdf5" MODEL_LABELS_FILENAME = "model_labels.dat" data = [] labels = [] for image_file in paths.list_images(SINGLE_LETTERS_FOLDER): image = cv2.imread(image_file) grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # set dimension for all images grayscale_image = resize_to_fit(grayscale_image, 20, 20) # need a third channel to work with keras grayscale_image = np.expand_dims(grayscale_image, axis=2) # add letter of image to labels label = image_file.split(os.path.sep)[-2] data.append(grayscale_image) labels.append(label) # try scaling to improve training, float have higher precision data = np.array(data, dtype="float") / 255.0 labels = np.array(labels) (X_train, X_test, Y_train, Y_test) = train_test_split(data, labels, test_size=0.25,
LETTER_IMAGES_FOLDER = "extracted_letter_images" MODEL_FILENAME = "captcha_model.hdf5" MODEL_LABELS_FILENAME = "model_labels.dat" # initialize the data and labels data = [] labels = [] # loop over the input images for image_file in paths.list_images(LETTER_IMAGES_FOLDER): # Load the image and convert it to grayscale image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Resize the letter so it fits in a 20x20 pixel box image = resize_to_fit(image, 20, 20) # Add a third channel dimension to the image to make Keras happy image = np.expand_dims(image, axis=2) # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-2] # Add the letter image and it's label to our training data data.append(image) labels.append(label) # scale the raw pixel intensities to the range [0, 1] (this improves training) data = np.array(data, dtype="float") / 255.0 labels = np.array(labels)
def textpredict(image_file): # loop over the image paths # image_file = "" # Load the image and convert it to grayscale image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Add some extra padding around the image image = cv2.copyMakeBorder(image, 20, 20, 20, 20, cv2.BORDER_REPLICATE) # threshold the image (convert it to pure black and white) thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] # find the contours (continuous blobs of pixels) the image contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Hack for compatibility with different OpenCV versions # contours = contours[0] if imutils.is_cv2() else contours[1] contours = contours[1] if imutils.is_cv3() else contours[0] letter_image_regions = [] # Now we can loop through each of the four contours and extract the letter # inside of each one for contour in contours: # Get the rectangle that contains the contour (x, y, w, h) = cv2.boundingRect(contour) # Compare the width and height of the contour to detect letters that # are conjoined into one chunk if w / h > 1.25: # This contour is too wide to be a single letter! # Split it in half into two letter regions! half_width = int(w / 2) letter_image_regions.append((x, y, half_width, h)) letter_image_regions.append((x + half_width, y, half_width, h)) else: # This is a normal letter by itself letter_image_regions.append((x, y, w, h)) # Sort the detected letter images based on the x coordinate to make sure # we are processing them from left-to-right so we match the right image # with the right letter letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) # Create an output image and a list to hold our predicted letters predictions = [] # loop over the lektters for letter_bounding_box in letter_image_regions: # Grab the coordinates of the letter in the image x, y, w, h = letter_bounding_box # Extract the letter from the original image with a 2-pixel margin around the edge letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2] # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(letter_image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # Print the captcha's text captcha_text = "".join(predictions) return captcha_text
MODEL_FILENAME = "stanford_models/model_large_renamed_test_6epoch.hdf5" MODEL_LABELS_FILENAME = "stanford_models/model_large_renamed_test_6epoch.dat" # initialize the data and labels data = [] labels = [] # loop over the input images for image_file in paths.list_images(LETTER_IMAGES_FOLDER): # Load the image and convert it to grayscale image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Resize the letter so it fits in a 40x40 pixel box image = resize_to_fit(image, 40, 40) # Add a third channel dimension to the image to make Keras happy image = np.expand_dims(image, axis=2) # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-2] # Add the letter image and it's label to our training data data.append(image) labels.append(label) # scale the raw pixel intensities to the range [0, 1] (this improves training) data = np.array(data, dtype="float") / 255.0 labels = np.array(labels)
def decaptcha(filenames): numChars = [] codes = [] m = 0 preprocessing = 0 testing = 0 tic = tm.perf_counter() model = load_model('final_model.hdf5') toc = tm.perf_counter() print(toc - tic) print(type(model)) temp1 = 0 temp2 = 0 temp3 = 0 temp4 = 0 j = 0 for i in filenames: tic = tm.perf_counter() img = cv2.imread(i) img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) img[img == img[0, 0]] = 255 kernel = np.ones((7, 7), np.uint8) kernel1 = np.ones((4, 4), np.uint8) img_d1 = cv2.dilate(img, kernel, iterations=1) img = cv2.cvtColor(img_d1, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(img, (5, 5), 0) ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) img = cv2.bitwise_not(th3) if j == 0: cv2.imshow("imagee", img) cv2.waitKey(0) cv2.destroyAllWindow() j = j + 1 toc3 = tm.perf_counter() cols = np.sum(img, axis=0) rows = np.sum(img, axis=1) cnt = 0 flag = 0 thres = 255 * 5 tmp = 0 start = [] end = [] for i in range(len(cols)): if cols[i] > thres and flag == 0: flag = 1 tmp = i if cols[i] <= thres and flag == 1: if (i - tmp) > 5: start.append(tmp) end.append(i) flag = 0 char = np.zeros((len(start), 140, 140)) toc4 = tm.perf_counter() for i in range(len(start)): l = end[i] - start[i] char[i][:, 75 - (l // 2):75 + l - (l // 2)] = img[5:-5, start[i]:end[i]] toc5 = tm.perf_counter() resized = np.zeros((len(start), 30, 30)) for i in range(len(start)): char[i] = 255 * np.ones((140, 140)) - char[i] resized[i] = resize_to_fit(char[i], 30, 30) toc1 = tm.perf_counter() temp1 = temp1 + (toc3 - tic) temp2 = temp2 + (toc4 - toc3) temp3 = temp3 + (toc5 - toc4) temp4 = temp4 + (toc1 - toc5) preprocessing = preprocessing + (toc1 - tic) resized = resized[..., np.newaxis] y_out = model.predict(resized) label = "" for i in range(len(start)): label = label + chr( ord('A') + np.where(y_out[i] == np.amax(y_out[i]))[0][0]) numChars.append(len(start)) codes.append(label) m = m + 1 toc2 = tm.perf_counter() testing = testing + (toc2 - toc1) print(temp1) print(temp2) print(temp3) print(temp4) print(preprocessing) print(testing) return (numChars, codes)
MODEL_FILENAME = "captcha_model.hdf5" MODEL_LABELS_FILENAME = "model_labels.dat" # initialize the data and labels data = [] labels = [] # loop over the input images for image_file in paths.list_images(LETTER_IMAGES_FOLDER): # Load the image and convert it to grayscale image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Resize the letter so it fits in a 20x20 pixel box image = resize_to_fit(image, 20, 20) # Add a third channel dimension to the image to make Keras happy image = np.expand_dims(image, axis=2) # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-2] # Add the letter image and it's label to our training data data.append(image) labels.append(label) # scale the raw pixel intensities to the range [0, 1] (this improves training) data = np.array(data, dtype="float") / 255.0 labels = np.array(labels)
def template_match_char(char_image, threshold, debug): logging.info("[BEGIN] Executing TEMPLATE MATCHING") # read character image image = cv2.imread(char_image) # convert to gray scale image character_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if debug: cv2.imshow("Char Gray", character_image) # threshold the image, convert it to black/white thresh, im_bw = cv2.threshold(character_image, threshold, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) im_bw = cv2.bitwise_not(im_bw) # resize to fit then crop crop_image = helpers.crop_letter(im_bw) if debug: cv2.imshow("Chara Cropped", crop_image) resized_image = helpers.resize_to_fit(crop_image.astype(np.uint8), 20, 20) if debug: cv2.imshow("Char Resized", resized_image) # directory full of texts -- to check if it's match files = glob.glob('../neural_network/images/**.ttf/**/*.png') text_dict = {} for file in files: text_dict[file] = {"path":file, "stats":None, "accuracy":None} # reads templates for i in text_dict: logging.debug("Matching? " + i) template_image = cv2.imread(i) template_image_gray = cv2.cvtColor(template_image, cv2.COLOR_BGR2GRAY) # convert to grayscale and to black and white _, template_bw = cv2.threshold(template_image_gray, threshold, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # template_bw = cv2.bitwise_not(template_bw) # resize to fit then crop tm_crop_image = helpers.crop_letter(template_bw) tm_resized_image = helpers.resize_to_fit(tm_crop_image.astype(np.uint8), 20, 20) result = cv2.matchTemplate(tm_resized_image, resized_image, cv2.TM_CCOEFF_NORMED) (minValue, maxValue, minLocation, maxLocation) = cv2.minMaxLoc(result) # (x, y) = minLocation # cv2.rectangle(character_image, (x, y), (x + template_image.shape[0], y + template_image.shape[1]), (0, 255, 0), 2) # cv2.imshow("Source", character_image) text_dict[i]["stats"] = (minValue, maxValue, minLocation, maxLocation) text_dict[i]["accuracy"] = float(maxValue) logging.debug("Result Accuracy: minValue({0}) maxValue({1}) File({2}) ".format(minValue, maxValue, i)) logging.debug("-----") # highest_value = {"path":None, "stats":None, "accuracy":0} # logging.info(highest_value["accuracy"]) # for i in text_dict: # val = text_dict[i]["accuracy"] # if int(val) > int(highest_value["accuracy"]): # logging.info(text_dict[i]) # highest_value = text_dict[i] # logging.info(highest_value) sorted_dict = sorted(text_dict, key=lambda x: (text_dict[x]['accuracy']), reverse=True) for i in sorted_dict: logging.debug("{0} - {1}".format(text_dict[i]['accuracy'], i)) logging.info("Best Accuracy Result: {0} : {1} [File name: {2}]".format(text_dict[sorted_dict[0]]["accuracy"], os.path.basename(sorted_dict[0]), sorted_dict[0])) logging.info("Next Best 3 Accuracy Result...") for i in range(1, 4): logging.info("Accuracy Result #{0}: {1} : {2} [File name: {3}]".format(i+1, text_dict[sorted_dict[i]]["accuracy"], os.path.basename(sorted_dict[i]), sorted_dict[i])) logging.info("[END] Finished TEMPLATE MATCHING")
if w / h > 1: # 1 - best value so far (hyperparam) half_width = int(w / 2) char_image_regions.append((x, y, half_width, h)) char_image_regions.append((x + half_width, y, half_width, h)) else: char_image_regions.append((x, y, w, h)) char_image_regions = sorted(char_image_regions, key=lambda x: x[0]) predictions = [] for char_bounding_box in char_image_regions: x, y, w, h = char_bounding_box char_image = image[y:y + h, x:x + w] char_image = resize_to_fit(char_image, 20, 20) char_image = np.expand_dims(char_image, axis=2) char_image = np.expand_dims(char_image, axis=0) prediction = model.predict(char_image) char = lb.inverse_transform(prediction)[0] predictions.append(char) captcha_text = "".join(predictions) print(f"ACTUAL : {captcha_correct_text}") print(f"CAPTCHA: {captcha_text}\n") if captcha_text == captcha_correct_text: num_correct += 1
def train_model(): LETTER_IMAGES_FOLDER = "extracted_letter_images" MODEL_FILENAME = "captcha_model.hdf5" MODEL_LABELS_FILENAME = "model_labels.dat" # initialize the data and labels data = [] labels = [] # loop over the input images for image_file in paths.list_images(LETTER_IMAGES_FOLDER): # Load the image and convert it to grayscale image = cv2.imread( image_file) # image_file: 'extracted_letter_images/K/000566.png' image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Resize the letter so it fits in a 20x20 pixel box image = resize_to_fit(image, 20, 20) # Add a third channel dimension to the image to make Keras happy image = np.expand_dims( image, axis=2 ) # Before: image.shape: (20, 20). After: image.shape: (20, 20, 1). # Grab the name of the letter based on the folder it was in label = image_file.split(os.path.sep)[-2] # Add the letter image and its label to our training data data.append(image) labels.append(label) # scale the raw pixel intensities to the range [0, 1] (this improves training) data = np.array(data, dtype="float") / 255.0 # data.shape: (38744, 20, 20, 1) labels = np.array(labels) # Split the training data into separate train and test sets (X_train, X_test, Y_train, Y_test) = train_test_split(data, labels, test_size=0.25, random_state=0) # Convert the labels (letters) into one-hot encodings that Keras can work with lb = LabelBinarizer().fit( labels ) # lb = LabelBinarizer().fit(Y_train) # NOTE: 严格来说应该用labels,但其实用Y_train就已经能够覆盖到所有的字母和数字了 Y_train = lb.transform(Y_train) Y_test = lb.transform(Y_test) # Save the mapping from labels to one-hot encodings. # We'll need this later when we use the model to decode what its predictions mean with open(MODEL_LABELS_FILENAME, "wb") as f: pickle.dump(lb, f) # Build the neural network! model = Sequential() # First convolutional layer with max pooling model.add( Conv2D(20, (5, 5), padding="same", input_shape=(20, 20, 1), activation="relu")) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) # Second convolutional layer with max pooling model.add(Conv2D(50, (5, 5), padding="same", activation="relu")) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) # Hidden layer with 500 nodes model.add(Flatten()) model.add(Dense(500, activation="relu")) # Output layer with 32 nodes (one for each possible letter/number we predict) model.add(Dense(32, activation="softmax")) # Ask Keras to build the TensorFlow model behind the scenes model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"]) # Train the neural network model.fit(X_train, Y_train, validation_data=(X_test, Y_test), batch_size=32, epochs=10, verbose=1) # Save the trained model to disk model.save(MODEL_FILENAME)
def solve_captcha_from_file(image_file): MODEL_FILENAME = "captcha_model.hdf5" MODEL_LABELS_FILENAME = "model_labels.dat" NUM_LETTERS = 5 # Load up the model labels (so we can translate model predictions to actual letters) with open(MODEL_LABELS_FILENAME, "rb") as f: lb = pickle.load(f) # Load the trained neural network model = load_model(MODEL_FILENAME) # Load the image and convert it to grayscale image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Add some extra padding around the image image = cv2.copyMakeBorder(image, 20, 20, 20, 20, cv2.BORDER_REPLICATE) # threshold the image (convert it to pure black and white) thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] # find the contours (continuous blobs of pixels) the image contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Hack for compatibility with different OpenCV versions contours = contours[0] #if imutils.is_cv2() else contours[1] letter_image_regions = [] # Now we can loop through each of the four contours and extract the letter # inside of each one for contour in contours: # Get the rectangle that contains the contour (x, y, w, h) = cv2.boundingRect(contour) # Compare the width and height of the contour to detect letters that # are conjoined into one chunk if w / h > 1.25: # This contour is too wide to be a single letter! # Split it in half into two letter regions! half_width = int(w / 2) letter_image_regions.append((x, y, half_width, h)) letter_image_regions.append((x + half_width, y, half_width, h)) else: # This is a normal letter by itself letter_image_regions.append((x, y, w, h)) # If we found more or less than 4 letters in the captcha, our letter extraction # didn't work correcly. Skip the image instead of saving bad training data! if len(letter_image_regions) != NUM_LETTERS: return '-1' # Sort the detected letter images based on the x coordinate to make sure # we are processing them from left-to-right so we match the right image # with the right letter letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) # Create an output image and a list to hold our predicted letters output = cv2.merge([image] * 3) predictions = [] # loop over the letters for letter_bounding_box in letter_image_regions: # Grab the coordinates of the letter in the image x, y, w, h = letter_bounding_box # Extract the letter from the original image with a 2-pixel margin around the edge letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2] # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(letter_image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # Print the captcha's text captcha_text = "".join(predictions) return captcha_text
letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) # Create an output image and a list to hold our predicted letters output = cv2.merge([image] * 3) predictions = [] # loop over the lektters for letter_bounding_box in letter_image_regions: # Grab the coordinates of the letter in the image x, y, w, h = letter_bounding_box # Extract the letter from the original image with a 2-pixel margin around the edge letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2] # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(letter_image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # draw the prediction on the output image cv2.rectangle(output, (x - 2, y - 2), (x + w + 4, y + h + 4), (0, 255, 0), 1)
def Solve(model,lb,text): # Grab some random CAPTCHA images to test against. # In the real world, you'd replace this section with code to grab a real # CAPTCHA image from a live website. #captcha_image_files = list(paths.list_images(CAPTCHA_IMAGE_FOLDER)) #captcha_image_files = np.random.choice(captcha_image_files, size=(10,), replace=False) #image = io.imread("https://obis1.selcuk.edu.tr/CaptchaHandler.ashx") # loop over the image paths encoded_data = text.split(',')[1] nparr = np.fromstring(base64.b64decode(encoded_data), np.uint8) image = cv2.imdecode(nparr, cv2.IMREAD_COLOR) # Load the image and convert it to grayscale #image = cv2.imread(image_file) image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Add some extra padding around the image image = cv2.copyMakeBorder(image, 20, 20, 20, 20, cv2.BORDER_REPLICATE) # threshold the image (convert it to pure black and white) thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1] for i in range(len(thresh)): if i>51: thresh[i-1] = thresh[i] # find the contours (continuous blobs of pixels) the image contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Hack for compatibility with different OpenCV versions contours = contours[1] if imutils.is_cv3() else contours[0] letter_image_regions = [] # Now we can loop through each of the four contours and extract the letter # inside of each one for contour in contours: # Get the rectangle that contains the contour (x, y, w, h) = cv2.boundingRect(contour) # Compare the width and height of the contour to detect letters that # are conjoined into one chunk if w / h > 1.25: # This contour is too wide to be a single letter! # Split it in half into two letter regions! half_width = int(w / 2) letter_image_regions.append((x, y, half_width, h)) letter_image_regions.append((x + half_width, y, half_width, h)) else: # This is a normal letter by itself letter_image_regions.append((x, y, w, h)) # If we found more or less than 4 letters in the captcha, our letter extraction # didn't work correcly. Skip the image instead of saving bad training data! #print(len(letter_image_regions)) if len(letter_image_regions) != 4: return {"result":"-1"} # Sort the detected letter images based on the x coordinate to make sure # we are processing them from left-to-right so we match the right image # with the right letter letter_image_regions = sorted(letter_image_regions, key=lambda x: x[0]) # Create an output image and a list to hold our predicted letters output = cv2.merge([image] * 3) predictions = [] # loop over the lektters for letter_bounding_box in letter_image_regions: # Grab the coordinates of the letter in the image x, y, w, h = letter_bounding_box # Extract the letter from the original image with a 2-pixel margin around the edge letter_image = image[y - 2:y + h + 2, x - 2:x + w + 2] # Re-size the letter image to 20x20 pixels to match training data letter_image = resize_to_fit(letter_image, 20, 20) # Turn the single image into a 4d list of images to make Keras happy letter_image = np.expand_dims(letter_image, axis=2) letter_image = np.expand_dims(letter_image, axis=0) # Ask the neural network to make a prediction prediction = model.predict(letter_image) # Convert the one-hot-encoded prediction back to a normal letter letter = lb.inverse_transform(prediction)[0] predictions.append(letter) # draw the prediction on the output image cv2.rectangle(output, (x - 2, y - 2), (x + w + 4, y + h + 4), (0, 255, 0), 1) cv2.putText(output, letter, (x - 5, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.55, (0, 255, 0), 2) # Print the captcha's text captcha_text = "".join(predictions) return {"result":"{}".format(captcha_text)}