暫無描述

extract.py 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import cv2
  2. from django.core.management.base import BaseCommand
  3. from django.template.loader import render_to_string
  4. from ...xword import extract_crossword_grid, draw_grid
  5. class Command(BaseCommand):
  6. help = "Extracts a clean crossword image from a photograph."
  7. def add_arguments(self, parser):
  8. parser.add_argument('input_file_name')
  9. parser.add_argument('--debug', action='store_true')
  10. parser.add_argument('--remove-colours', action='store_true')
  11. parser.add_argument('--colour-removal-threshold', type=int, default=48)
  12. parser.add_argument('--gaussian-blur-size', type=int, default=11)
  13. parser.add_argument('--adaptive-threshold-block-size', type=int, default=11)
  14. parser.add_argument('--adaptive-threshold-mean-adjustment', type=int, default=2)
  15. parser.add_argument('--not-square', action='store_true')
  16. parser.add_argument('--num-dilations', type=int, default=1)
  17. parser.add_argument('--contour-erosion-kernel-size', type=int, default=5)
  18. parser.add_argument('--contour-erosion-iterations', type=int, default=5)
  19. parser.add_argument('--line-detector-element-size', type=int, default=51)
  20. parser.add_argument('--sampling-block-size-ratio', type=float, default=0.25)
  21. parser.add_argument('--sampling-threshold-quantile', type=float, default=0.3)
  22. parser.add_argument('--sampling-threshold', type=int)
  23. parser.add_argument('--grid-line-thickness', type=int, default=4)
  24. parser.add_argument('--grid-square-size', type=int, default=64)
  25. parser.add_argument('--grid-border-size', type=int, default=20)
  26. group = parser.add_mutually_exclusive_group()
  27. group.add_argument('--out')
  28. group.add_argument('--html')
  29. def handle(self, *args, **options):
  30. warnings, grid, num_rows, num_cols, block_img = extract_crossword_grid(
  31. options['input_file_name'],
  32. callback=debug_callback if options['debug'] else None,
  33. remove_colours=options['remove_colours'],
  34. colour_removal_threshold=options['colour_removal_threshold'],
  35. gaussian_blur_size=options['gaussian_blur_size'],
  36. adaptive_threshold_block_size=options['adaptive_threshold_block_size'],
  37. adaptive_threshold_mean_adjustment=options['adaptive_threshold_mean_adjustment'],
  38. square=not options['not_square'],
  39. num_dilations=options['num_dilations'],
  40. contour_erosion_kernel_size=options['contour_erosion_kernel_size'],
  41. contour_erosion_iterations=options['contour_erosion_iterations'],
  42. line_detector_element_size=options['line_detector_element_size'],
  43. sampling_block_size_ratio=options['sampling_block_size_ratio'],
  44. sampling_threshold_quantile=options['sampling_threshold_quantile'],
  45. sampling_threshold=options['sampling_threshold']
  46. )
  47. if options['debug']:
  48. debug_callback('square', block_img)
  49. for warning in warnings:
  50. print('WARNING: ' + warning)
  51. if options['html'] is not None:
  52. html = render_to_string('home/grid.html', {
  53. 'grid': grid,
  54. 'num_rows': num_rows,
  55. 'num_cols': num_cols,
  56. })
  57. with open(options['html'], 'w') as f:
  58. f.write(html)
  59. else:
  60. image = draw_grid(
  61. grid,
  62. num_rows,
  63. num_cols,
  64. grid_line_thickness=options['grid_line_thickness'],
  65. grid_square_size=options['grid_square_size'],
  66. grid_border_size=options['grid_border_size']
  67. )
  68. if options['debug'] or (options['out'] is None):
  69. debug_callback('output', image)
  70. if options['out'] is not None:
  71. _, png = cv2.imencode('.png', image)
  72. with open(options['out'], 'wb') as f:
  73. f.write(png.tobytes())
  74. if options['debug'] or (options['out'] is None):
  75. while cv2.waitKey() & 0xFF != ord('q'):
  76. pass
  77. cv2.destroyAllWindows()
  78. def debug_callback(name, image):
  79. cv2.namedWindow(name, cv2.WINDOW_NORMAL)
  80. cv2.imshow(name, image)