def show_difference(pic_file_path, actual, difference): the_image = cv2.imread(pic_file_path, 0) the_image = Image.resize_keeping_ratio_by_height(the_image) # Display.image(the_image) actual_number_indexs, actual_digits, actual_number_ragions = actual if difference: identified_number_ragions = identify_wrong_number(actual_number_ragions, difference, False) # identified_number_ragions = identify_wrong_number(actual_number_ragions, difference) else: identified_number_ragions = actual_number_ragions all_number_ragion = join_number_ragions(actual_number_indexs, identified_number_ragions) all_number_ragion = numpy_helper.transfer_values_quickly(all_number_ragion,{1:255}) # all_number_ragion = Image.colorize(all_number_ragion) # Display.image(all_number_ragion) if difference: wrong_number_ragions = generate_wrong_number_ragions(difference) wrong_number_ragion = join_number_ragions(actual_number_indexs, wrong_number_ragions) wrong_number_ragion = Image.resize_keeping_ratio_by_height(wrong_number_ragion, all_number_ragion.shape[0]) wrong_number_ragion = numpy_helper.transfer_values_quickly(wrong_number_ragion,{1:255}) # Display.image(Ragions.join((all_number_ragion, wrong_number_ragion), 1)) # Display.ragions([the_image, all_number_ragion, wrong_number_ragion]) Display.images([Ragions.join((all_number_ragion, wrong_number_ragion),1), the_image]) else: Display.images([all_number_ragion, the_image])
def save_different_number(image_index, difference, number_ragions): def gen_file_path(digit_index, real_digit, cal_digit): return '../resource/svm_wrong_digits/pic' + str(image_index).zfill(2) + \ '_no'+str(digit_index).zfill(2)+'_real'+str(real_digit)+'_cal'+str(cal_digit) + '.dataset' for digit_index, real_digit, cal_digit in difference: file_path = gen_file_path(digit_index, real_digit, cal_digit) Image.save_to_txt(number_ragions[digit_index], file_path) print 'save file: '+ file_path
def resize_and_save_file(interpolation_item): interpolation_value, interpolation_name = interpolation_item result_file_path = os.path.join( save_path, str(the_digit) + "_" + interpolation_name + "_" + os.path.basename(ragion_file_path) ) resized_ragion = main_sudoku.resize_to_cell_size(issue_ragion, interpolation_value) Image.save_to_txt(resized_ragion, result_file_path) result_file_path.pl() return result_file_path
def save_dataset(gray_image, file_name): from picture_sudoku.helpers.common import Resource file_path = Resource.get_path('test',file_name) # file_path = '../../resource/test/' + file_name transfered_image = numpy_helper.transfer_values_quickly(gray_image,{255:1}) print(file_path+" has been saved!") return Image.save_to_txt(transfered_image,file_path)
def resize_to_cell_size(the_ragion, interpolation = cv2.INTER_AREA): # the_ragion.shape.pl() heighted_ragion = Image.resize_keeping_ratio_by_fixed_length(the_ragion, IMG_SIZE, interpolation) # heighted_ragion.shape.pl() standard_ragion = Ragion.fill(heighted_ragion,(IMG_SIZE,IMG_SIZE)) # standard_ragion.shape.pl() return standard_ragion
def generate_first_rect(the_ragion): ragion_height, ragion_width = the_ragion.shape centroid = Image.centroid(the_ragion) single_width = int(round(ragion_width*0.16)) single_height = int(round(ragion_height*0.16)) # (single_width, single_height).ppl() return Rect.cal_center_rect(centroid, single_width, single_width, single_height, single_height)
def identify_wrong_number(number_ragions, difference, show_actual=True): all_number_images = generate_number_images() identified_number_ragions = number_ragions[:] for index,_,actual in difference: height, width = number_ragions[index].shape if show_actual: number_ragions[index] = Image.resize_keeping_ratio_by_height(all_number_images[actual], height) height, width = number_ragions[index].shape identified_number_ragions[index] = Ragion.fill(number_ragions[index], (height+2, width+2), 1) return identified_number_ragions
def find_max_contour(threshed_image, filter_func = None, accuracy_percent_with_perimeter=0.0001): contours = Image.find_contours( threshed_image, filter_func, accuracy_percent_with_perimeter) # from picture_sudoku.cv2_helpers.display import Display # Display.contours(threshed_image, contours) if len(contours) == 0: return None contour_area_arr = [cv2.contourArea(i) for i in contours] max_contour = contours[contour_area_arr.index(max(contour_area_arr))] return max_contour
def adjust_one(the_ragion): # the_ragion = cv2.GaussianBlur(the_ragion, ksize=(5,5), sigmaX=0) # blockSize = the_ragion.shape[1]/2 # if blockSize % 2 == 0: # blockSize += 1 # thresholded_ragion = cv2.adaptiveThreshold(the_ragion,WHITE, # cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV, blockSize=blockSize, C=2) # thresholded_ragion = Image.threshold_white_with_mean_percent(the_ragion, 0.70) threshold_value = Ragion.cal_threshold_value(the_ragion, square_ragion, 0.70) thresholded_ragion = Image.threshold_white(the_ragion, threshold_value) return thresholded_ragion
def test_generate_supplement_number_ragion(file_name, simple_svm, supplement_svm): file_path = os.path.join(data_file_helper.SUPPLEMENT_TRAINING_PATH, file_name) the_ragion = Image.load_from_txt(file_path) the_number_matrix = numpy.matrix(the_ragion.reshape(1, FULL_SIZE)) # simple_svm.dag_classify(the_number_matrix).must_equal( # extract_cal_digit(file_path), # failure_msg="simple file path: {0}".format(file_path)) supplement_svm.dag_classify(the_number_matrix).must_equal( extract_real_digit(file_path), failure_msg="supplement file path: {0}".format(file_path) )
def digit_recognize(): mb = MultipleSvm.load_variables(Smo, RESULT_PATH) # file_path = '../resource/svm_wrong_digits/pic04_no17_real8_cal3.dataset' file_path = '../resource/svm_wrong_digits/pic04_no33_real8_cal3.dataset' # file_path = '../resource/svm_wrong_digits/pic15_no19_real5_cal6_1.dataset' # file_path = '../resource/svm_wrong_digits/pic15_no19_real5_cal6.dataset' number_ragion = numpy.mat(Image.read_from_number_file(file_path)) transfered_ragion = numpy_helper.transfer_1to255(number_ragion) # adjusted_ragion = main_sudoku.adjust_number_ragion(transfered_ragion) adjusted_ragion = adjust_number_ragion2(transfered_ragion) # adjusted_ragion = transfered_ragion Display.ragions([transfered_ragion, adjusted_ragion]) adjusted_ragion = numpy_helper.transfer_255to1(adjusted_ragion) number_matrix = main_sudoku.transfer_to_digit_matrix(adjusted_ragion) mb.dag_classify(number_matrix).ppl()
def extract_square_from_contour(contour): the_image = Image.generate_mask(Contour.get_shape(contour)) # Display.contours(the_image, [contour]) cv2.drawContours(the_image, [contour], -1, 255, 1) # Display.image(the_image) # lines = PolarLines.find_suitable_lines(the_image) square_ragion = the_image vertical_lines = find_vertical_lines(square_ragion) border_line_count = 2 if len(vertical_lines) > border_line_count: raise SudokuError("The count of vertical border lines is larger than {0}".format(border_line_count)) horizontal_lines = find_horizontal_lines(square_ragion) if len(horizontal_lines) > border_line_count: raise SudokuError("The count of horizontal border lines is larger than {0}".format(border_line_count)) Display.polar_lines(square_ragion, vertical_lines + horizontal_lines) # Display.polar_lines(square_ragion, horizontal_lines) intersections = main_analyzer.find_intersections(vertical_lines, horizontal_lines) # intersections.ppl() Points.to_contour(intersections).ppl()
def generate_standard_supplement_number_ragions( ragion_file_path, the_digit, save_path=data_file_helper.SUPPLEMENT_TRAINING_PATH ): issue_ragion = Image.load_from_txt(ragion_file_path) # os.path.basename(ragion_file_path).pl() # ragion_file_path.pl() resize_interpolation_arr = ( (cv2.INTER_AREA, "INTER_AREA"), (cv2.INTER_LINEAR, "INTER_LINEAR"), (cv2.INTER_CUBIC, "INTER_CUBIC"), ) def resize_and_save_file(interpolation_item): interpolation_value, interpolation_name = interpolation_item result_file_path = os.path.join( save_path, str(the_digit) + "_" + interpolation_name + "_" + os.path.basename(ragion_file_path) ) resized_ragion = main_sudoku.resize_to_cell_size(issue_ragion, interpolation_value) Image.save_to_txt(resized_ragion, result_file_path) result_file_path.pl() return result_file_path return map(resize_and_save_file, resize_interpolation_arr)
def extract_square_from_contour(contour): ''' it will extract square from the contour which could have many noise points. ''' the_image = Image.generate_mask(Contour.get_shape(contour)) # Display.contours(the_image, [contour]) cv2.drawContours(the_image, [contour], -1, 255 ,1) # Display.image(the_image) # lines = PolarLines.find_suitable_lines(the_image) square_ragion = the_image vertical_lines = find_vertical_lines(square_ragion) horizontal_lines = find_horizontal_lines(square_ragion) # flag_test() # Display.polar_lines(square_ragion, vertical_lines+horizontal_lines) border_line_count = 2 if len(vertical_lines) > border_line_count: logger.info("The count of vertical border lines is larger than {0}" .format(border_line_count)) vertical_lines = [vertical_lines[0],vertical_lines[-1]] if len(horizontal_lines) > border_line_count: logger.info("The count of horizontal border lines is larger than {0}" .format(border_line_count)) horizontal_lines = [horizontal_lines[0],horizontal_lines[-1]] # flag_test() # Display.polar_lines(square_ragion, vertical_lines+horizontal_lines) intersections = find_intersections(vertical_lines, horizontal_lines) # intersections.ppl() square_contour = Points.to_contour(intersections) # order the points square_contour = Points.to_contour(Quadrilateral.vertices(square_contour)) # 'test'.pl() # Display.contours(the_image,[square_contour]) return square_contour
with test("get clear number ragion"): som_svm = MultipleSvm.load_variables(Smo, data_file_helper.SUPPLEMENT_RESULT_PATH) file_path = Resource.get_test_path("sample_15_null_38_image.jpg") the_ragion = cv2.imread(file_path, 0) # the_ragion.mean().ppl() # the_ragion.ppl() # thresholded_ragion = Image.threshold_white_with_mean_percent(the_ragion, 0.8) # thresholded_ragion.ppl() # Display.image(thresholded_ragion) file_path = Resource.get_test_path("sample_15_square.jpg") square_ragion = cv2.imread(file_path, 0) # square_ragion.mean().ppl() threshold_value = Ragion.cal_threshold_value(the_ragion, square_ragion, 0.69) thresholded_ragion = Image.threshold_white(the_ragion, threshold_value) # thresholded_ragion = cv2.adaptiveThreshold(the_ragion, 255, # cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV, blockSize=7, C=2) cell_rect = nonzero_rect.analyze_from_center(thresholded_ragion) if cell_rect: cell_ragion = Rect.get_ragion(cell_rect, thresholded_ragion) cell_rect.pl() # Display.image(cell_ragion) file_path = Resource.get_test_path("sample_19_07_05_image.jpg") the_ragion = cv2.imread(file_path, 0) # the_ragion.mean().ppl() file_path = Resource.get_test_path("sample_19_square.jpg") square_ragion = cv2.imread(file_path, 0) # square_ragion.mean().ppl()
if __name__ == "__main__": from minitest import * import data_file_helper from picture_sudoku.helpers import numpy_helper from picture_sudoku.cv2_helpers.display import Display from picture_sudoku.cv2_helpers.image import Image from picture_sudoku.helpers.common import Resource from picture_sudoku import main_sudoku def show_number_matrix(number_matrix): binary_number_image = number_matrix.reshape((data_file_helper.IMG_SIZE, data_file_helper.IMG_SIZE)) number_image = numpy_helper.transfer_values_quickly(binary_number_image, {1: 255}) number_image = numpy.array(number_image, dtype=numpy.uint8) # Image.save_to_txt(number_image,'test1.dataset') Display.image(number_image) """ how to use training, please see the generator.py""" with test(MultipleSvm.dag_classify): dataset_matrix_hash = data_file_helper.get_dataset_matrix_hash(data_file_helper.FONT_TRAINING_PATH, (9,)) mb = MultipleSvm.load_variables(Smo, data_file_helper.FONT_RESULT_PATH) mb.dag_classify(dataset_matrix_hash[9][0]).must_equal(9) with test("special number"): file_name = "sample_18_01_26_resized.dataset" issue_ragion = Image.load_from_txt(Resource.get_path("test", file_name)) transfered_ragion = main_sudoku.transfer_to_digit_matrix(issue_ragion) mb = MultipleSvm.load_variables(Smo, data_file_helper.FONT_RESULT_PATH) mb.dag_classify(transfered_ragion).must_equal(1) # Display.binary_image(main_sudoku.resize_to_cell_size(issue_ragion))
def generate_number(index): file_path = font_training_path+"/"+str(index)+suffix_file_name return Image.load_from_txt(file_path)
import cv2 from picture_sudoku.cv2_helpers.image import Image from picture_sudoku.cv2_helpers.display import Display from picture_sudoku.helpers.common import Resource if __name__ == '__main__': from minitest import * with test("show freeman"): the_pic_path = Resource.get_path('test/pic16_no05_real8_cal6.dataset') the_image = Image.load_from_txt(the_pic_path) # contours,not_use = cv2.findContours(the_image.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) # # Display.contours(the_image, contours) # contours.ppl() cv2.CHAIN_APPROX_NONE.pl() cv2.CHAIN_APPROX_SIMPLE.pl() contours,not_use = cv2.findContours(the_image.copy(),cv2.RETR_LIST,0) # Display.contours(the_image, contours) contours.ppl()
def save_dataset(gray_image, file_path): transfered_image = numpy_helper.transfer_values_quickly(gray_image,{255:1}) return Image.save_to_txt(transfered_image,file_path)
def center_rect_enlarge_search(the_ragion): ''' it has been deprecated, since it will take more time and cannot get the whole rect in some case. ''' ragion_height, ragion_width = the_ragion.shape centroid = Image.centroid(the_ragion) single_width = int(round(ragion_width*0.18)) single_height = int(round(ragion_height*0.18)) # (single_width, single_height).ppl() left_x, top_y, edge_width, edge_height = \ Rect.cal_center_rect(centroid, single_width, single_width, single_height, single_height) right_x = left_x + edge_width - 1 bottom_y = top_y + edge_height - 1 # (left_x, top_y, edge_width, edge_height).ppl() top_nonzero = True bottom_nonzero = True left_nonzero = True right_nonzero = True while(top_nonzero or bottom_nonzero or left_nonzero or right_nonzero): # (left_x, top_y, right_x, bottom_y).ppl() # (left_nonzero, top_nonzero, right_nonzero, bottom_nonzero).ppl() # cur_rect = Rect.create(left_x, top_y, right_x, bottom_y) # Display.rect(the_ragion, cur_rect) if top_nonzero: top_nonzero = Rect.has_nonzero((left_x, top_y, right_x-left_x+1, 1),the_ragion) if top_nonzero: top_y -= 1 if top_y <= 0: top_nonzero = False top_y = -1 if bottom_nonzero: bottom_nonzero = Rect.has_nonzero((left_x, bottom_y, right_x-left_x+1, 1),the_ragion) if bottom_nonzero: bottom_y += 1 if bottom_y >= ragion_height-1: bottom_nonzero = False bottom_y = ragion_height if left_nonzero: left_nonzero = Rect.has_nonzero((left_x, top_y, 1, bottom_y-top_y+1),the_ragion) if left_nonzero: left_x -= 1 if left_x <= 0: left_nonzero = False left_x = -1 if right_nonzero: right_nonzero = Rect.has_nonzero((right_x, top_y, 1, bottom_y-top_y+1),the_ragion) if right_nonzero: right_x += 1 if right_x >= ragion_width-1: right_nonzero = False right_x = ragion_width final_top = top_y + 1 final_bottom = bottom_y - 1 final_left = left_x + 1 final_right = right_x - 1 return Rect.create(final_left, final_top, final_right, final_bottom)
all_names = filter(lambda name: name.startswith(PERFORM_PREFIX), globals()) for index, name in enumerate(all_names): window_name = name[len(PERFORM_PREFIX):] method = globals()[name] show_window(the_image, window_name, index, perform_func=method) control_name = filter(lambda name: name.startswith(CONTROL_NAME), globals())[0] show_window(the_image, control_name, len(all_names), perform_func=None, control_func=globals()[control_name]) cv2.waitKey(0) cv2.destroyAllWindows() def draw_text(the_image, the_text): cv2.putText(the_image, the_text, (20,20), cv2.FONT_HERSHEY_PLAIN, 1.0, (0,255,0)) if __name__ == '__main__': from minitest import * image_path = './original.jpg' color_image = cv2.imread(image_path) gray_image = cv2.imread(image_path, 0) color_image = Image.resize_keeping_ratio_by_height(color_image) gray_image = Image.resize_keeping_ratio_by_height(gray_image) with test("blurring"): # show_simple_blurring(color_image) show_all(color_image) pass
the_line = numpy.array([ 340, 0.06] ) PolarLines.adjust_theta_when_rho_0_and_near_180(the_line).must_close( the_line) # the_image = Image.generate_mask((800,600)) # Display.polar_lines(the_image, [the_line]) with test("show line degree"): # 2,3,5 same, 1,4 same line1 = PolarLines.create_from_rho_and_degree(10, 178) line2 = PolarLines.create_from_rho_and_degree(10, -2) line3 = PolarLines.create_from_rho_and_degree(-10, -182) line4 = PolarLines.create_from_rho_and_degree(-10, -2) line5 = PolarLines.create_from_rho_and_degree(10, 358) the_image = Image.generate_mask((800,600)) # # # Display.polar_lines(the_image, [line2,line3, line4]) # Display.polar_lines(the_image, [line1, line2]) # Display.polar_lines(the_image, [line2,]) lines = [numpy.array([ 1. , -0.12217298]), numpy.array([ 1. , 3.01941967]), numpy.array([ 3. , 3.00196624]), numpy.array([ 5. , 3.00196624]), numpy.array([ 7. , 3.00196624])] # Display.polar_lines(the_image, lines[:1]) # Display.polar_lines(the_image, lines[:1])
inject(numpy.allclose, 'must_close') with test("Ragion.fill"): the_ragion = numpy.ones((3,4)) Ragion.fill(the_ragion, (6,6)).must_close( numpy.array( [[ 0., 0., 0., 0., 0., 0.], [ 0., 1., 1., 1., 1., 0.], [ 0., 1., 1., 1., 1., 0.], [ 0., 1., 1., 1., 1., 0.], [ 0., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 0.]])) with test(Ragion.review_classified_number_ragion_for_8): the_pic_path = '../../resource/test/pic17_no08_real6_cal8.dataset' the_ragion = Image.load_from_txt(the_pic_path) Ragion.review_classified_number_ragion_for_8(the_ragion, 8).must_equal(6) the_pic_path = '../../resource/test/pic16_no05_real8_cal6.dataset' the_ragion = Image.load_from_txt(the_pic_path) Ragion.review_classified_number_ragion_for_8(the_ragion, 8).must_equal(8) # Display.binary_image(the_ragion) # save file: ../resource/svm_wrong_digits/pic16_no10_real8_cal6.dataset # save file: ../resource/svm_wrong_digits/pic16_no20_real8_cal6.dataset pass with test("Ragions.fill_to_same_size"): ragions = (numpy.ones((3,2)), numpy.ones((2,1)), numpy.ones((2,4))) Ragions.fill_to_same_size(ragions).must_close( [numpy.array([[ 0., 1., 1., 0.],
final_left = left_x + 1 final_right = right_x - 1 return Rect.create(final_left, final_top, final_right, final_bottom) if __name__ == '__main__': from minitest import * from picture_sudoku.cv2_helpers.display import Display from picture_sudoku.helpers import numpy_helper from picture_sudoku.helpers.common import Resource inject(numpy.allclose, 'must_close') test_image_path = '../../resource/test/' image_14_07_path = test_image_path+'sample_14_07.dataset' image_14_07 = Image.load_from_txt(image_14_07_path) image_14_07_255 = numpy_helper.transfer_values_quickly(image_14_07, {1:255}) with test(analyze_from_center): rect_14_07 = analyze_from_center(image_14_07) rect_14_07.must_equal((15, 11, 26, 39)) # Display.binary_rect(image_14_07, rect_14_07) # Image.save_to_txt(Rect.get_ragion(rect_14_07, image_14_07), # test_image_path+'sample_14_07_no.dataset') image_01_03_path = test_image_path+'sample_01_03.dataset' image_01_03 = Image.load_from_txt(image_01_03_path) rect_01_03 = analyze_from_center(image_01_03) rect_01_03.must_equal((27, 26, 12, 17)) # Display.binary_rect(image_01_03, rect_01_03)