main.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import argparse
  2. import codecs
  3. import logging
  4. import os
  5. import sys
  6. import yaml
  7. from qtpy import QtWidgets
  8. from labelme import __appname__
  9. from labelme import __version__
  10. from labelme.app import MainWindow
  11. from labelme.config import get_config
  12. from labelme.logger import logger
  13. from labelme.utils import newIcon
  14. def main():
  15. _main()
  16. # try:
  17. # _main()
  18. # except Exception as e:
  19. # logger.error(e)
  20. def _main():
  21. parser = argparse.ArgumentParser()
  22. parser.add_argument(
  23. '--version', '-V', action='store_true', help='show version'
  24. )
  25. parser.add_argument(
  26. '--reset-config', action='store_true', help='reset qt config'
  27. )
  28. parser.add_argument(
  29. '--logger-level',
  30. default='info',
  31. choices=['debug', 'info', 'warning', 'fatal', 'error'],
  32. help='logger level',
  33. )
  34. parser.add_argument('filename', nargs='?', help='image or label filename')
  35. parser.add_argument(
  36. '--output',
  37. '-O',
  38. '-o',
  39. help='output file or directory (if it ends with .json it is '
  40. 'recognized as file, else as directory)'
  41. )
  42. default_config_file = os.path.join(os.path.expanduser('~'), '.labelmerc')
  43. parser.add_argument(
  44. '--config',
  45. dest='config_file',
  46. help='config file (default: %s)' % default_config_file,
  47. default=default_config_file,
  48. )
  49. # config for the gui
  50. parser.add_argument(
  51. '--nodata',
  52. dest='store_data',
  53. action='store_false',
  54. help='stop storing image data to JSON file',
  55. default=argparse.SUPPRESS,
  56. )
  57. parser.add_argument(
  58. '--autosave',
  59. dest='auto_save',
  60. action='store_true',
  61. help='auto save',
  62. default=argparse.SUPPRESS,
  63. )
  64. parser.add_argument(
  65. '--nosortlabels',
  66. dest='sort_labels',
  67. action='store_false',
  68. help='stop sorting labels',
  69. default=argparse.SUPPRESS,
  70. )
  71. parser.add_argument(
  72. '--flags',
  73. help='comma separated list of flags OR file containing flags',
  74. default=argparse.SUPPRESS,
  75. )
  76. parser.add_argument(
  77. '--labelflags',
  78. dest='label_flags',
  79. help='yaml string of label specific flags OR file containing json string of label specific flags (ex. {human:[male,female],dog:[big],__all__:[occluded]} )',
  80. default=argparse.SUPPRESS,
  81. )
  82. parser.add_argument(
  83. '--labels',
  84. help='comma separated list of labels OR file containing labels',
  85. default=argparse.SUPPRESS,
  86. )
  87. parser.add_argument(
  88. '--validatelabel',
  89. dest='validate_label',
  90. choices=['exact', 'instance'],
  91. help='label validation types',
  92. default=argparse.SUPPRESS,
  93. )
  94. parser.add_argument(
  95. '--keep-prev',
  96. action='store_true',
  97. help='keep annotation of previous frame',
  98. default=argparse.SUPPRESS,
  99. )
  100. parser.add_argument(
  101. '--epsilon',
  102. type=float,
  103. help='epsilon to find nearest vertex on canvas',
  104. default=argparse.SUPPRESS,
  105. )
  106. args = parser.parse_args()
  107. if args.version:
  108. print('{0} {1}'.format(__appname__, __version__))
  109. sys.exit(0)
  110. logger.setLevel(getattr(logging, args.logger_level.upper()))
  111. if hasattr(args, 'flags'):
  112. if os.path.isfile(args.flags):
  113. with codecs.open(args.flags, 'r', encoding='utf-8') as f:
  114. args.flags = [l.strip() for l in f if l.strip()]
  115. else:
  116. args.flags = [l for l in args.flags.split(',') if l]
  117. if hasattr(args, 'labels'):
  118. if os.path.isfile(args.labels):
  119. with codecs.open(args.labels, 'r', encoding='utf-8') as f:
  120. args.labels = [l.strip() for l in f if l.strip()]
  121. else:
  122. args.labels = [l for l in args.labels.split(',') if l]
  123. if hasattr(args, 'label_flags'):
  124. if os.path.isfile(args.label_flags):
  125. with codecs.open(args.label_flags, 'r', encoding='utf-8') as f:
  126. args.label_flags = yaml.load(f)
  127. else:
  128. args.label_flags = yaml.load(args.label_flags)
  129. # Add not overlapping labels from label flags
  130. if not hasattr(args, 'labels'):
  131. args.labels = []
  132. for label in args.label_flags.keys():
  133. if label != "__all__" and label not in args.labels:
  134. args.labels.append(label)
  135. config_from_args = args.__dict__
  136. config_from_args.pop('version')
  137. reset_config = config_from_args.pop('reset_config')
  138. filename = config_from_args.pop('filename')
  139. output = config_from_args.pop('output')
  140. config_file = config_from_args.pop('config_file')
  141. config = get_config(config_from_args, config_file)
  142. if not config['labels'] and config['validate_label']:
  143. logger.error('--labels must be specified with --validatelabel or '
  144. 'validate_label: true in the config file '
  145. '(ex. ~/.labelmerc).')
  146. sys.exit(1)
  147. output_file = None
  148. output_dir = None
  149. if output is not None:
  150. if output.endswith('.json'):
  151. output_file = output
  152. else:
  153. output_dir = output
  154. app = QtWidgets.QApplication(sys.argv)
  155. app.setApplicationName(__appname__)
  156. app.setWindowIcon(newIcon('icon'))
  157. win = MainWindow(
  158. config=config,
  159. filename=filename,
  160. output_file=output_file,
  161. output_dir=output_dir,
  162. )
  163. if reset_config:
  164. logger.info('Resetting Qt config: %s' % win.settings.fileName())
  165. win.settings.clear()
  166. sys.exit(0)
  167. win.show()
  168. win.raise_()
  169. sys.exit(app.exec_())
  170. # this main block is required to generate executable by pyinstaller
  171. if __name__ == '__main__':
  172. main()