ImageLabeler.cpp 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497
  1. /*
  2. * ImageLabeler.cpp
  3. *
  4. * Created on: Oct 4, 2011
  5. * Author: Gapchich Vladislav
  6. */
  7. #include "ImageLabeler.h"
  8. #include "functions.h"
  9. #include <QApplication>
  10. #include <QFrame>
  11. #include <QMenuBar>
  12. #include <QMenu>
  13. #include <QAction>
  14. #include <QBoxLayout>
  15. #include <QGridLayout>
  16. #include <QPixmap>
  17. #include <QLabel>
  18. #include <QPushButton>
  19. #include <QButtonGroup>
  20. #include <QListWidget>
  21. #include <QListWidgetItem>
  22. #include <QFileDialog>
  23. #include <QColorDialog>
  24. #include <QDir>
  25. #include <QMessageBox>
  26. #include <QListIterator>
  27. #include <QDomDocument>
  28. #include <QFile>
  29. #include <QKeyEvent>
  30. #include <QDebug>
  31. ImageLabeler::ImageLabeler(QWidget *aParent) :
  32. QMainWindow(aParent)
  33. {
  34. /*
  35. * Variables
  36. */
  37. list_images_ = new QStringList();
  38. main_label_ = -1;
  39. pure_data_ = 0;
  40. //label_ID_ = -1;
  41. /* options */
  42. auto_color_generation_ = 0;
  43. /*
  44. * menu bar part begins
  45. */
  46. menu_bar_ = new QMenuBar(this);
  47. setMenuBar(menu_bar_);
  48. menu_file_ = new QMenu(menu_bar_);
  49. menu_file_->setTitle(tr("&File"));
  50. menu_edit_ = new QMenu(menu_bar_);
  51. menu_edit_->setTitle(tr("&Edit"));
  52. menu_help_ = new QMenu(menu_bar_);
  53. menu_help_->setTitle(tr("&Help"));
  54. action_open_images_ = new QAction(this);
  55. action_open_images_->setText(tr("&Load images"));
  56. action_open_labeled_image_ = new QAction(this);
  57. action_open_labeled_image_->setText(tr("&Open labeled image"));
  58. action_load_legend_ = new QAction(this);
  59. action_load_legend_->setText(tr("Load &legend"));
  60. action_save_labels_ = new QAction(this);
  61. action_save_labels_->setText(tr("&Save all info"));
  62. action_save_labels_->setEnabled(false);
  63. action_save_segmented_ = new QAction(this);
  64. action_save_segmented_->setText(tr("Save segmented &picture"));
  65. action_save_segmented_->setEnabled(false);
  66. action_save_legend_ = new QAction(this);
  67. action_save_legend_->setText(tr("Save &legend"));
  68. action_save_legend_->setEnabled(false);
  69. action_undo_ = new QAction(this);
  70. action_undo_->setText(tr("&Undo"));
  71. action_undo_->setEnabled(false);
  72. action_redo_ = new QAction(this);
  73. action_redo_->setText(tr("&Redo"));
  74. action_redo_->setEnabled(false);
  75. action_bound_box_tool_ = new QAction(this);
  76. action_bound_box_tool_->setText(tr("Bounding box tool"));
  77. action_bound_box_tool_->setEnabled(false);
  78. action_polygon_tool_ = new QAction(this);
  79. action_polygon_tool_->setText(tr("&Polygon tool"));
  80. action_polygon_tool_->setEnabled(false);
  81. action_tagging_tool_ = new QAction(this);
  82. action_tagging_tool_->setText(tr("&Tagging tool"));
  83. action_tagging_tool_->setEnabled(false);
  84. action_add_description_ = new QAction(this);
  85. action_add_description_->setText(tr("&Add image description"));
  86. action_add_description_->setEnabled(false);
  87. action_options_ = new QAction(this);
  88. action_options_->setText(tr("&Options"));
  89. action_help_content_ = new QAction(this);
  90. action_help_content_->setText(tr("&Help content"));
  91. action_help_content_->setEnabled(false);
  92. action_about_ = new QAction(this);
  93. action_about_->setText(tr("&About"));
  94. action_about_->setEnabled(false);
  95. /* ------------------ */
  96. action_quit_ = new QAction(this);
  97. action_quit_->setText(tr("&Quit"));
  98. menu_bar_->addAction(menu_file_->menuAction());
  99. menu_bar_->addAction(menu_edit_->menuAction());
  100. menu_bar_->addAction(menu_help_->menuAction());
  101. menu_file_->addAction(action_open_images_);
  102. menu_file_->addAction(action_open_labeled_image_);
  103. menu_file_->addAction(action_load_legend_);
  104. menu_file_->addAction(action_save_segmented_);
  105. menu_file_->addAction(action_save_legend_);
  106. menu_file_->addAction(action_save_labels_);
  107. menu_file_->addAction(action_quit_);
  108. menu_edit_->addAction(action_undo_);
  109. menu_edit_->addAction(action_redo_);
  110. menu_edit_->addAction(action_bound_box_tool_);
  111. menu_edit_->addAction(action_polygon_tool_);
  112. menu_edit_->addAction(action_tagging_tool_);
  113. menu_edit_->addAction(action_add_description_);
  114. menu_edit_->addAction(action_options_);
  115. menu_help_->addAction(action_help_content_);
  116. menu_help_->addAction(action_about_);
  117. /*
  118. * popup menu part begins
  119. */
  120. popup_area_list_ = new QMenu;
  121. action_delete_area_ = new QAction(this);
  122. action_delete_area_->setText(tr("&Delete area"));
  123. action_edit_area_ = new QAction(this);
  124. action_edit_area_->setText(tr("&Change area"));
  125. popup_area_list_->addAction(action_delete_area_);
  126. popup_area_list_->addAction(action_edit_area_);
  127. popup_label_list_ = new QMenu;
  128. action_set_color_ = new QAction(this);
  129. action_set_color_->setText(tr("Set &color"));
  130. action_toggle_priority_ = new QAction(this);
  131. action_toggle_priority_->setText(tr("Toggle &priority"));
  132. action_delete_label_ = new QAction(this);
  133. action_delete_label_->setText(tr("&Delete"));
  134. popup_label_list_->addAction(action_set_color_);
  135. popup_label_list_->addAction(action_toggle_priority_);
  136. popup_label_list_->addAction(action_delete_label_);
  137. /*
  138. * widgets part begins
  139. */
  140. central_widget_ = new QWidget(this);
  141. setCentralWidget(central_widget_);
  142. frame_toolbox_ = new QFrame(central_widget_);
  143. frame_toolbox_->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
  144. frame_toolbox_->setLineWidth(0);
  145. frame_toolbox_->setMidLineWidth(0);
  146. frame_center_ = new QFrame(central_widget_);
  147. //frame_image_->setFrameStyle(QFrame::Box | QFrame::Plain);
  148. //frame_image_->setLineWidth(1);
  149. frame_image_ = new QFrame(frame_center_);
  150. //frame_image_->setStyleSheet("QWidget {background: #888888;}");
  151. frame_image_->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
  152. frame_image_->setLineWidth(0);
  153. frame_image_->setMidLineWidth(0);
  154. frame_labelbox_ = new QFrame(central_widget_);
  155. frame_labelbox_->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
  156. frame_labelbox_->setLineWidth(0);
  157. frame_labelbox_->setMidLineWidth(0);
  158. image_ = new QPixmap(500, 500);
  159. image_->fill(QColor(Qt::white));
  160. //image_holder_ = new ImageHolder(frame_image_);
  161. image_holder_ = new ImageHolder(frame_image_);
  162. image_holder_->setPixmap(*image_);
  163. image_holder_->setStyleSheet("QLabel {background: #ffffff;}");
  164. image_holder_->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
  165. image_holder_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  166. image_holder_->setFocusPolicy(Qt::StrongFocus);
  167. image_holder_->setFocus();
  168. //image_holder_->setScaledContents(true);
  169. image_holder_->setFrameStyle(QFrame::Box | QFrame::Plain);
  170. image_holder_->setLineWidth(0);
  171. list_label_ = new QListWidget(central_widget_);
  172. list_label_->setContextMenuPolicy(Qt::CustomContextMenu);
  173. list_areas_ = new QListWidget(central_widget_);
  174. list_areas_->setContextMenuPolicy(Qt::CustomContextMenu);
  175. // addLabel(0, false, "BACKGROUND");
  176. // list_label_->item(0)->setFlags(Qt::ItemIsSelectable);
  177. //QListWidgetItem *background = list_label_->item(0);
  178. //qDebug() << background;
  179. //background->setFlags(Qt::ItemIsSelectable);
  180. label_toolbox_ = new QLabel(tr("Tool box"), frame_toolbox_);
  181. label_list_areas_ = new QLabel(tr("Selected areas"), central_widget_);
  182. /* buttons */
  183. button_bound_box_tool_ = new QPushButton(frame_toolbox_);
  184. button_bound_box_tool_->setText(tr("bbox"));
  185. button_bound_box_tool_->setEnabled(false);
  186. button_bound_box_tool_->setCheckable(true);
  187. button_polygon_tool_ = new QPushButton(frame_toolbox_);
  188. button_polygon_tool_->setText(tr("poly tool"));
  189. button_polygon_tool_->setEnabled(false);
  190. button_polygon_tool_->setCheckable(true);
  191. button_tagging_tool_ = new QPushButton(frame_toolbox_);
  192. button_tagging_tool_->setText(tr("tagging"));
  193. button_tagging_tool_->setEnabled(false);
  194. button_tagging_tool_->setCheckable(true);
  195. button_clear_selection_tool_ = new QPushButton(frame_toolbox_);
  196. button_clear_selection_tool_->setText(tr("clear selection"));
  197. button_clear_selection_tool_->setEnabled(false);
  198. button_generate_colors_ = new QPushButton(frame_toolbox_);
  199. button_generate_colors_->setText(tr("generate label colors"));
  200. button_generate_colors_->setEnabled(false);
  201. button_delete_all_labels_ = new QPushButton(frame_toolbox_);
  202. button_delete_all_labels_->setText(tr("delete all labels"));
  203. button_delete_all_labels_->setEnabled(false);
  204. group_tools_ = new QButtonGroup;
  205. group_tools_->addButton(button_bound_box_tool_);
  206. group_tools_->addButton(button_polygon_tool_);
  207. group_tools_->addButton(button_tagging_tool_);
  208. button_confirm_selection_ = new QPushButton(central_widget_);
  209. button_confirm_selection_->setText(tr("Confirm selection"));
  210. button_confirm_selection_->setEnabled(false);
  211. button_add_label_ = new QPushButton(frame_labelbox_);
  212. button_add_label_->setText(tr("Add label"));
  213. button_add_label_->setEnabled(false);
  214. button_remove_label_ = new QPushButton(frame_labelbox_);
  215. button_remove_label_->setText(tr("Remove label"));
  216. button_remove_label_->setEnabled(false);
  217. button_prev_image_ = new QPushButton(central_widget_);
  218. button_prev_image_->setText("←");
  219. button_next_image_ = new QPushButton(central_widget_);
  220. button_next_image_->setText("→");
  221. /*
  222. * layouts part begins
  223. */
  224. layout_main_ = new QHBoxLayout(central_widget_);
  225. layout_left_ = new QVBoxLayout();
  226. layout_toolbox_ = new QVBoxLayout();
  227. layout_center_ = new QVBoxLayout();
  228. layout_frame_image_ = new QVBoxLayout();
  229. layout_image_widget_ = new QGridLayout();
  230. layout_center_buttons_ = new QHBoxLayout();
  231. layout_right_ = new QVBoxLayout();
  232. layout_labelbox_ = new QVBoxLayout();
  233. layout_labelbox_buttons_ = new QHBoxLayout();
  234. layout_main_->addLayout(layout_left_);
  235. layout_main_->addLayout(layout_center_);
  236. layout_main_->addLayout(layout_right_);
  237. /* making the center part stretchable */
  238. layout_main_->setStretch(1, 1);
  239. /* left part */
  240. layout_left_->addWidget(frame_toolbox_);
  241. frame_toolbox_->setLayout(layout_toolbox_);
  242. layout_toolbox_->addWidget(label_toolbox_);
  243. layout_toolbox_->addWidget(button_bound_box_tool_);
  244. layout_toolbox_->addWidget(button_polygon_tool_);
  245. layout_toolbox_->addWidget(button_tagging_tool_);
  246. layout_toolbox_->addSpacing(10);
  247. layout_toolbox_->addWidget(button_clear_selection_tool_);
  248. layout_toolbox_->addWidget(button_delete_all_labels_);
  249. layout_toolbox_->addSpacing(10);
  250. layout_toolbox_->addWidget(button_generate_colors_);
  251. /* stretch is for making toolbox as small as it can be */
  252. layout_left_->addStretch(1);
  253. layout_left_->addWidget(button_confirm_selection_);
  254. /* central part */
  255. layout_center_->addWidget(frame_center_);
  256. frame_center_->setLayout(layout_frame_image_);
  257. //layout_frame_image_->addWidget(image_holder_);
  258. layout_frame_image_->setContentsMargins(0, 0, 0, 0);
  259. layout_frame_image_->addWidget(frame_image_);
  260. frame_image_->setLayout(layout_image_widget_);
  261. layout_image_widget_->setRowStretch(0, 1);
  262. layout_image_widget_->setColumnStretch(0, 1);
  263. layout_image_widget_->addWidget(image_holder_, 1, 1);
  264. layout_image_widget_->setRowStretch(2, 1);
  265. layout_image_widget_->setColumnStretch(2, 1);
  266. //layout_frame_image_->addStretch(1);
  267. layout_frame_image_->addLayout(layout_center_buttons_);
  268. layout_center_buttons_->addWidget(button_prev_image_);
  269. layout_center_buttons_->addWidget(button_next_image_);
  270. /* right part */
  271. layout_right_->addWidget(frame_labelbox_);
  272. frame_labelbox_->setFixedWidth(300);
  273. frame_labelbox_->setLayout(layout_labelbox_);
  274. layout_labelbox_->addLayout(layout_labelbox_buttons_);
  275. layout_labelbox_buttons_->addWidget(button_add_label_);
  276. layout_labelbox_buttons_->addWidget(button_remove_label_);
  277. layout_labelbox_->addWidget(list_label_);
  278. layout_labelbox_->addWidget(label_list_areas_);
  279. layout_labelbox_->addWidget(list_areas_);
  280. connect(
  281. action_quit_,
  282. SIGNAL(triggered()),
  283. this,
  284. SLOT(close())
  285. );
  286. connect(
  287. action_open_images_,
  288. SIGNAL(triggered()),
  289. this,
  290. SLOT(loadImages())
  291. );
  292. connect(
  293. action_open_labeled_image_,
  294. SIGNAL(triggered()),
  295. this,
  296. SLOT(loadInfo())
  297. );
  298. connect(
  299. action_load_legend_,
  300. SIGNAL(triggered()),
  301. this,
  302. SLOT(loadLegendFromFile())
  303. );
  304. connect(
  305. action_save_legend_,
  306. SIGNAL(triggered()),
  307. this,
  308. SLOT(saveLegend())
  309. );
  310. connect(
  311. action_save_segmented_,
  312. SIGNAL(triggered()),
  313. this,
  314. SLOT(saveSegmentedPicture())
  315. );
  316. connect(
  317. action_save_labels_,
  318. SIGNAL(triggered()),
  319. this,
  320. SLOT(saveAllInfo())
  321. );
  322. connect(
  323. button_add_label_,
  324. SIGNAL(clicked()),
  325. this,
  326. SLOT(addLabel())
  327. );
  328. connect(
  329. button_remove_label_,
  330. SIGNAL(clicked()),
  331. this, SLOT(removeLabel())
  332. );
  333. connect(
  334. button_next_image_,
  335. SIGNAL(clicked()),
  336. this,
  337. SLOT(nextImage())
  338. );
  339. connect(
  340. button_prev_image_,
  341. SIGNAL(clicked()),
  342. this,
  343. SLOT(prevImage())
  344. );
  345. connect(
  346. button_bound_box_tool_,
  347. SIGNAL(toggled(bool)),
  348. this,
  349. SLOT(setBoundingBoxTool(bool))
  350. );
  351. connect(
  352. button_polygon_tool_,
  353. SIGNAL(toggled(bool)),
  354. this,
  355. SLOT(setPolygonTool(bool))
  356. );
  357. connect(
  358. button_clear_selection_tool_,
  359. SIGNAL(clicked()),
  360. this,
  361. SLOT(clearAllTool())
  362. );
  363. connect(
  364. button_generate_colors_,
  365. SIGNAL(clicked()),
  366. this,
  367. SLOT(generateColors())
  368. );
  369. connect(
  370. button_delete_all_labels_,
  371. SIGNAL(clicked()),
  372. this,
  373. SLOT(clearLabelList())
  374. );
  375. connect(
  376. button_confirm_selection_,
  377. SIGNAL(clicked()),
  378. this,
  379. SLOT(confirmSelection())
  380. );
  381. connect(
  382. list_label_,
  383. SIGNAL(itemChanged(QListWidgetItem *)),
  384. this,
  385. SLOT(editLabel(QListWidgetItem *))
  386. );
  387. connect(
  388. list_label_,
  389. SIGNAL(itemClicked(QListWidgetItem *)),
  390. this,
  391. SLOT(setLabelID(QListWidgetItem *))
  392. );
  393. connect(
  394. list_areas_,
  395. SIGNAL(itemDoubleClicked(QListWidgetItem *)),
  396. image_holder_,
  397. SLOT(focusOnArea(QListWidgetItem *))
  398. );
  399. connect(
  400. list_areas_,
  401. SIGNAL(customContextMenuRequested(const QPoint &)),
  402. this,
  403. SLOT(areaListPopupMenu(const QPoint &))
  404. );
  405. connect(
  406. list_areas_,
  407. SIGNAL(itemChanged(QListWidgetItem *)),
  408. this,
  409. SLOT(onAreaChange(QListWidgetItem *))
  410. );
  411. connect(
  412. list_label_,
  413. SIGNAL(customContextMenuRequested(const QPoint &)),
  414. this,
  415. SLOT(labelListPopupMenu(const QPoint &))
  416. );
  417. connect(
  418. action_delete_area_,
  419. SIGNAL(triggered()),
  420. this,
  421. SLOT(deleteArea())
  422. );
  423. connect(
  424. action_edit_area_,
  425. SIGNAL(triggered()),
  426. this,
  427. SLOT(editArea())
  428. );
  429. connect(
  430. action_set_color_,
  431. SIGNAL(triggered()),
  432. this,
  433. SLOT(setLabelColor())
  434. );
  435. connect(
  436. action_toggle_priority_,
  437. SIGNAL(triggered()),
  438. this,
  439. SLOT(toggleLabelPriority())
  440. );
  441. connect(
  442. action_delete_label_,
  443. SIGNAL(triggered()),
  444. this,
  445. SLOT(removeLabel())
  446. );
  447. connect(
  448. action_add_description_,
  449. SIGNAL(triggered()),
  450. &image_description_form_,
  451. SLOT(show())
  452. );
  453. connect(
  454. action_options_,
  455. SIGNAL(triggered()),
  456. &options_form_,
  457. SLOT(show())
  458. );
  459. connect(
  460. image_holder_,
  461. SIGNAL(selectionStarted()),
  462. this,
  463. SLOT(onSelectionStarted())
  464. );
  465. connect(
  466. &image_description_form_,
  467. SIGNAL(descriptionSet(QString)),
  468. this,
  469. SLOT(setDescription(QString))
  470. );
  471. connect(
  472. image_holder_,
  473. SIGNAL(imageScaled()),
  474. this,
  475. SLOT(onImageScaled())
  476. );
  477. connect(
  478. &options_form_,
  479. SIGNAL(optionsSet()),
  480. this,
  481. SLOT(onOptionsSet())
  482. );
  483. image_holder_->setBoundingBoxList(&list_bounding_box_);
  484. image_holder_->setPolygonList(&list_polygon_);
  485. image_holder_->setLabelColorList(&list_label_colors_);
  486. image_holder_->setMainLabelNum(&main_label_);
  487. }
  488. ImageLabeler::~ImageLabeler()
  489. {
  490. delete action_quit_;
  491. delete action_open_labeled_image_;
  492. delete action_open_images_;
  493. delete action_load_legend_;
  494. delete action_save_legend_;
  495. delete action_save_segmented_;
  496. delete action_save_labels_;
  497. delete action_undo_;
  498. delete action_redo_;
  499. delete action_bound_box_tool_;
  500. delete action_polygon_tool_;
  501. delete action_tagging_tool_;
  502. delete action_add_description_;
  503. delete action_options_;
  504. delete action_about_;
  505. delete action_help_content_;
  506. delete menu_file_;
  507. delete menu_edit_;
  508. delete menu_help_;
  509. delete menu_bar_;
  510. delete action_delete_area_;
  511. delete action_edit_area_;
  512. delete popup_area_list_;
  513. delete action_toggle_priority_;
  514. delete action_set_color_;
  515. delete action_delete_label_;
  516. delete popup_label_list_;
  517. delete image_;
  518. delete image_holder_;
  519. delete button_add_label_;
  520. delete button_remove_label_;
  521. delete button_bound_box_tool_;
  522. delete button_polygon_tool_;
  523. delete button_tagging_tool_;
  524. delete button_clear_selection_tool_;
  525. delete button_generate_colors_;
  526. delete button_delete_all_labels_;
  527. delete button_next_image_;
  528. delete button_prev_image_;
  529. delete button_confirm_selection_;
  530. delete label_list_areas_;
  531. delete label_toolbox_;
  532. delete list_areas_;
  533. delete list_label_;
  534. delete layout_toolbox_;
  535. delete layout_right_;
  536. delete layout_center_buttons_;
  537. delete layout_frame_image_;
  538. delete layout_center_;
  539. delete layout_labelbox_buttons_;
  540. delete layout_labelbox_;
  541. delete layout_left_;
  542. delete layout_main_;
  543. delete frame_labelbox_;
  544. delete frame_toolbox_;
  545. delete frame_image_;
  546. delete frame_center_;
  547. delete central_widget_;
  548. delete list_images_;
  549. //delete current_image_;
  550. if (pure_data_) {
  551. delete[] *pure_data_;
  552. delete pure_data_;
  553. }
  554. }
  555. void
  556. ImageLabeler::addLabel()
  557. {
  558. QListWidgetItem *newItem = new QListWidgetItem;
  559. QString label;
  560. int itemNum = list_label_->count();
  561. label.append(QString("%1: ").arg(itemNum));
  562. if (itemNum) {
  563. newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
  564. label.append("New label");
  565. }
  566. else {
  567. newItem->setFlags(
  568. Qt::ItemIsUserCheckable | Qt::ItemIsSelectable |
  569. Qt::ItemIsEnabled
  570. );
  571. label.append("BACKGROUND");
  572. }
  573. newItem->setText(label);
  574. QPixmap iconPix = QPixmap(20, 20);
  575. iconPix.fill(Qt::white);
  576. QIcon icon(iconPix);
  577. list_label_colors_.append(0xffffffff);
  578. newItem->setIcon(icon);
  579. list_label_->addItem(newItem);
  580. list_label_->setItemSelected(newItem, true);
  581. }
  582. void
  583. ImageLabeler::addLabel(
  584. int aLabelID,
  585. bool isMain,
  586. QString aLabel
  587. )
  588. {
  589. QListWidgetItem *newItem = new QListWidgetItem;
  590. if (0 == aLabelID) {
  591. aLabel = QString("BACKGROUND");
  592. newItem->setFlags(
  593. Qt::ItemIsUserCheckable | Qt::ItemIsSelectable |
  594. Qt::ItemIsEnabled
  595. );
  596. }
  597. QString label;
  598. label.append(QString("%1: %2").
  599. arg(aLabelID).
  600. arg(aLabel)
  601. );
  602. /* TODO: check if there is another main label and make it common */
  603. if (isMain) {
  604. main_label_ = aLabelID;
  605. }
  606. QPixmap iconPix = QPixmap(20, 20);
  607. QColor color;
  608. if (0 != aLabelID)
  609. color = Qt::white;
  610. else
  611. color = Qt::black;
  612. iconPix.fill(color);
  613. QIcon icon(iconPix);
  614. list_label_colors_.append(color.rgb());
  615. newItem->setIcon(icon);
  616. newItem->setText(label);
  617. newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
  618. list_label_->addItem(newItem);
  619. list_label_->setItemSelected(newItem, true);
  620. }
  621. void
  622. ImageLabeler::editLabel(QListWidgetItem *anItem)
  623. {
  624. QString label = anItem->text();
  625. int itemRow = list_label_->row(anItem);
  626. QString prefix = QString("%1: ").arg(itemRow);
  627. if (-1 != label.indexOf(prefix)) {
  628. return;
  629. /* NOTREACHED */
  630. }
  631. label.prepend(QString("%1: ").arg(itemRow));
  632. if (main_label_ == itemRow) {
  633. label.append(" #main");
  634. }
  635. list_label_->blockSignals(true);
  636. anItem->setText(label);
  637. list_label_->blockSignals(false);
  638. }
  639. void
  640. ImageLabeler::removeLabel()
  641. {
  642. if (0 == list_label_->count()) {
  643. return;
  644. /* NOTREACHED */
  645. }
  646. QListWidgetItem *current = list_label_->currentItem();
  647. /* because we need to keep BACKGROUND category */
  648. if (0 == list_label_->row(current)) {
  649. return;
  650. /* NOTREACHED */
  651. }
  652. int row = list_label_->row(current);
  653. list_label_->takeItem(row);
  654. list_label_colors_.takeAt(row);
  655. delete current;
  656. }
  657. void
  658. ImageLabeler::setLabelID(
  659. QListWidgetItem *anItem
  660. )
  661. {
  662. Q_UNUSED(anItem)
  663. if (!list_label_->count()) {
  664. return;
  665. /* NOTREACHED */
  666. }
  667. label_ID_ = list_label_->row(anItem);
  668. }
  669. void
  670. ImageLabeler::addBBoxArea(
  671. int anID,
  672. BoundingBox aBBox
  673. )
  674. {
  675. QListWidgetItem *newItem = new QListWidgetItem;
  676. QString label;
  677. label.append(QString("%1: ").arg(list_areas_->count()));
  678. label.append(QString("BBox #%1; ").arg(anID));
  679. label.append(QString("LabelID: %1; ").arg(aBBox.label_ID_));
  680. label.append(
  681. QString("points:%1;%2;%3;%4; ").
  682. arg(aBBox.rect.topLeft().x()).
  683. arg(aBBox.rect.topLeft().y()).
  684. arg(aBBox.rect.bottomRight().x()).
  685. arg(aBBox.rect.bottomRight().y())
  686. );
  687. newItem->setText(label);
  688. //newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
  689. list_areas_->addItem(newItem);
  690. list_areas_->setItemSelected(newItem, true);
  691. }
  692. void
  693. ImageLabeler::addPolyArea(
  694. int aPolyID,
  695. Polygon aPoly
  696. )
  697. {
  698. QListWidgetItem *newItem = new QListWidgetItem;
  699. QString label;
  700. label.append(QString("%1: ").arg(list_areas_->count()));
  701. label.append(QString("Poly #%1; ").arg(aPolyID));
  702. label.append(QString("LabelID: %1; ").arg(aPoly.label_ID_));
  703. label.append("points:");
  704. for (int i = 0; i < aPoly.poly.count(); i++) {
  705. label.append(
  706. QString("%1;%2;").
  707. arg(aPoly.poly.point(i).x()).
  708. arg(aPoly.poly.point(i).y())
  709. );
  710. }
  711. newItem->setText(label);
  712. //newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
  713. list_areas_->addItem(newItem);
  714. list_areas_->setItemSelected(newItem, true);
  715. }
  716. /* TODO: finish area editing */
  717. void
  718. ImageLabeler::editArea()
  719. {
  720. bool oldState = list_areas_->blockSignals(true);
  721. if (!list_areas_->currentItem() || !list_areas_->count()) {
  722. return;
  723. /* NOTREACHED */
  724. }
  725. QListWidgetItem *current = list_areas_->currentItem();
  726. old_area_string_ = current->text();
  727. current->setFlags(current->flags() | Qt::ItemIsEditable);
  728. list_areas_->editItem(current);
  729. list_areas_->blockSignals(oldState);
  730. }
  731. void
  732. ImageLabeler::onAreaChange(QListWidgetItem *anItem)
  733. {
  734. list_areas_->blockSignals(true);
  735. QString areaString = anItem->text();
  736. int oldID = -1;
  737. if (-1 != areaString.indexOf("Poly")) {
  738. Polygon poly = polyFromString(&areaString, &oldID);
  739. if (-1 < poly.label_ID_ && !poly.poly.isEmpty() &&
  740. -1 < oldID) {
  741. list_polygon_.takeAt(oldID);
  742. list_polygon_.insert(oldID, poly);
  743. }
  744. else
  745. anItem->setText(old_area_string_);
  746. }
  747. else if (-1 != areaString.indexOf("BBox")) {
  748. BoundingBox bbox = BBoxFromString(&areaString, &oldID);
  749. if (-1 < bbox.label_ID_ && -1 < oldID) {
  750. list_bounding_box_.takeAt(oldID);
  751. list_bounding_box_.insert(oldID, bbox);
  752. }
  753. else
  754. anItem->setText(old_area_string_);
  755. }
  756. else {
  757. showWarning(tr("record format is corrupted, try again"));
  758. anItem->setText(old_area_string_);
  759. }
  760. anItem->setFlags(anItem->flags() ^ Qt::ItemIsEditable);
  761. list_areas_->blockSignals(false);
  762. }
  763. void
  764. ImageLabeler::deleteArea()
  765. {
  766. if (!list_areas_->currentItem() || !list_areas_->count()) {
  767. return;
  768. /* NOTREACHED */
  769. }
  770. QString text = list_areas_->currentItem()->text();
  771. bool ok = 0;
  772. //int labelID = getNumFromString(&text, "LabelID:", ";", &ok);
  773. // if (!ok) {
  774. // return;
  775. // /* NOTREACHED */
  776. // }
  777. /*
  778. * 0 - bbox
  779. * 1 - poly
  780. */
  781. QString shape;
  782. if (-1 != text.indexOf("BBox"))
  783. shape = QString("BBox");
  784. else if (-1 != text.indexOf("Poly"))
  785. shape = QString("Poly");
  786. else {
  787. return;
  788. /* NOTREACHED */
  789. }
  790. int areaNum = getNumFromString(&text, "#", ";", &ok);
  791. if (!ok) {
  792. return;
  793. /* NOTREACHED */
  794. }
  795. int currentItemRow = list_areas_->row(list_areas_->currentItem());
  796. /* changing all shapes(depends on current) which are next in the list */
  797. for (int i = list_areas_->count() - 1; i > currentItemRow; i--) {
  798. QListWidgetItem item = *(list_areas_->item(i));
  799. QString newText = item.text();
  800. if (-1 == newText.indexOf(shape))
  801. continue;
  802. int num = getNumFromString(&newText, "#", ";", &ok);
  803. num--;
  804. QString numString = QString("%1").arg(num);
  805. int numPos = newText.indexOf("#") + 1;
  806. newText.replace(numPos, numString.size(), numString);
  807. list_areas_->takeItem(i);
  808. list_areas_->insertItem(i, newText);
  809. }
  810. list_areas_->takeItem(currentItemRow);
  811. if (shape == "BBox")
  812. list_bounding_box_.removeAt(areaNum);
  813. else
  814. list_polygon_.removeAt(areaNum);
  815. image_holder_->update();
  816. }
  817. void
  818. ImageLabeler::toggleLabelPriority()
  819. {
  820. if (!list_label_->count()) {
  821. return;
  822. /* NOTREACHED */
  823. }
  824. QListWidgetItem *item = list_label_->currentItem();
  825. /* because we need to keep BACKGROUND category */
  826. if (0 == list_label_->row(item)) {
  827. return;
  828. /* NOTREACHED */
  829. }
  830. int itemRow = list_label_->row(item);
  831. QString text = item->text();
  832. /* cleaning previous " #main" mark */
  833. if (-1 != main_label_) {
  834. QListWidgetItem *lastMain = list_label_->item(main_label_);
  835. QString lastMainText = lastMain->text();
  836. int mainPos = lastMainText.indexOf(" #main");
  837. lastMainText = lastMainText.mid(0, mainPos);
  838. list_label_->blockSignals(true);
  839. lastMain->setText(lastMainText);
  840. list_label_->blockSignals(false);
  841. }
  842. if (main_label_ == itemRow) {
  843. int mainPos = text.indexOf(" #main");
  844. text = text.mid(0, mainPos);
  845. main_label_ = -1;
  846. }
  847. else {
  848. text.append(" #main");
  849. main_label_ = list_label_->row(item);
  850. }
  851. list_label_->blockSignals(true);
  852. item->setText(text);
  853. list_label_->blockSignals(false);
  854. image_holder_->update();
  855. }
  856. void
  857. ImageLabeler::getImagesFromDir(const QDir &dir)
  858. {
  859. /* avoiding freezing during recursive search for files */
  860. QApplication::processEvents();
  861. QStringList filenameFilter;
  862. filenameFilter <<
  863. "*.jpeg" <<
  864. "*.jpg" <<
  865. "*.gif" <<
  866. "*.png" <<
  867. "*.bmp" <<
  868. "*.tiff"
  869. ;
  870. QStringList listImages =
  871. dir.entryList(filenameFilter, QDir::Files);
  872. foreach (QString file, listImages)
  873. list_images_->append(dir.absoluteFilePath(file));
  874. QStringList listDir = dir.entryList(QDir::Dirs);
  875. foreach (QString subdir, listDir) {
  876. if ("." == subdir || ".." == subdir)
  877. continue;
  878. getImagesFromDir(QDir(dir.absoluteFilePath(subdir)));
  879. }
  880. }
  881. void
  882. ImageLabeler::nextImage()
  883. {
  884. if (list_images_->isEmpty()) {
  885. return;
  886. /* NOTREACHED */
  887. }
  888. if (askForUnsavedData()) {
  889. return;
  890. /* NOTREACHED */
  891. }
  892. if (list_images_->end() == current_image_ + 1)
  893. current_image_ = list_images_->begin();
  894. else
  895. current_image_++;
  896. image_->load(*current_image_);
  897. image_holder_->setPixmap(*image_);
  898. list_bounding_box_.clear();
  899. list_polygon_.clear();
  900. list_areas_->clear();
  901. image_holder_->clearAll();
  902. setWindowTitle(tr("ImageLabeler"));
  903. }
  904. void
  905. ImageLabeler::prevImage()
  906. {
  907. if (list_images_->isEmpty()) {
  908. return;
  909. /* NOTREACHED */
  910. }
  911. if (askForUnsavedData()) {
  912. return;
  913. /* NOTREACHED */
  914. }
  915. if (list_images_->begin() == current_image_)
  916. current_image_ = list_images_->end() - 1;
  917. else
  918. current_image_--;
  919. image_->load(*current_image_);
  920. image_holder_->setPixmap(*image_);
  921. list_bounding_box_.clear();
  922. list_polygon_.clear();
  923. list_areas_->clear();
  924. image_holder_->clearAll();
  925. setWindowTitle(tr("ImageLabeler"));
  926. }
  927. void
  928. ImageLabeler::saveAllInfo()
  929. {
  930. if (list_images_->isEmpty()) {
  931. showWarning("You have not opened any image yet");
  932. return;
  933. /* NOTREACHED */
  934. }
  935. /* ------------------------------------------------------------------------
  936. * XML part
  937. */
  938. QDomDocument doc(tr("ImageLabeler"));
  939. QDomElement root = doc.createElement(tr("pixelwise_labeling"));
  940. doc.appendChild(root);
  941. QDomElement image = doc.createElement(tr("image"));
  942. root.appendChild(image);
  943. QDomText pathToImage = doc.createTextNode(*current_image_);
  944. image.appendChild(pathToImage);
  945. QDomElement description = doc.createElement(tr("description"));
  946. root.appendChild(description);
  947. QDomText descriptionText = doc.createTextNode(image_description_);
  948. description.appendChild(descriptionText);
  949. legendToXml(&doc, &root);
  950. // QDomElement legend = doc.createElement(tr("legend"));
  951. // root.appendChild(legend);
  952. //
  953. // /* storing all labels made by user */
  954. // int labelCount = list_label_->count();
  955. // for (int i = 0; i < labelCount; i++) {
  956. // QDomElement label = doc.createElement(tr("label"));
  957. // label.setAttribute("color", QString("%1").arg(list_label_colors_.at(i), 0, 16));
  958. // label.setAttribute("id", i);
  959. //
  960. // QString priority;
  961. // if (main_label_ == i)
  962. // priority.append("1");
  963. // else
  964. // priority.append("0");
  965. // label.setAttribute("isMain", priority);
  966. //
  967. // QString labelText = list_label_->item(i)->text();
  968. //
  969. // /* removing the number prefix of label */
  970. // if (-1 != labelText.indexOf(QString("%1: ").arg(i))) {
  971. // labelText = labelText.mid(3, labelText.size() - 3);
  972. // }
  973. //
  974. // QDomText labelName = doc.createTextNode(labelText);
  975. // label.appendChild(labelName);
  976. // legend.appendChild(label);
  977. // }
  978. //
  979. // /* in case we have no labels */
  980. // if (0 == labelCount) {
  981. // QDomElement label = doc.createElement(tr("label"));
  982. // label.setAttribute(tr("id"), -1);
  983. // legend.appendChild(label);
  984. // }
  985. /* objects - selected areas */
  986. objectsToXml(&doc, &root);
  987. // QDomElement objects = doc.createElement(tr("objects"));
  988. // root.appendChild(objects);
  989. //
  990. // /* rects first */
  991. // for (int i = 0; i < list_bounding_box_.size(); i++) {
  992. // QDomElement rectData = doc.createElement(tr("bbox"));
  993. //
  994. // rectData.setAttribute("id", list_bounding_box_.at(i).label_ID_);
  995. //
  996. // QRect rect = list_bounding_box_.at(i).rect.normalized();
  997. //
  998. // QString rectDataString =
  999. // QString("%1;%2;%3;%4;").
  1000. // arg(rect.x()).
  1001. // arg(rect.y()).
  1002. // arg(rect.width()).
  1003. // arg(rect.height());
  1004. //
  1005. // QDomText rectDataText = doc.createTextNode(rectDataString);
  1006. // rectData.appendChild(rectDataText);
  1007. // objects.appendChild(rectData);
  1008. // }
  1009. //
  1010. // /* polys next */
  1011. // for (int i = 0; i < list_polygon_.size(); i++) {
  1012. // QDomElement polyData = doc.createElement(tr("poly"));
  1013. //
  1014. // polyData.setAttribute("id", list_polygon_.at(i).label_ID_);
  1015. //
  1016. // QPolygon poly = list_polygon_.at(i).poly;
  1017. //
  1018. // QString polyDataString;
  1019. // for (int j = 0; j < poly.count(); j++)
  1020. // polyDataString.append(
  1021. // QString("%1;%2;").
  1022. // arg(poly.point(j).x()).
  1023. // arg(poly.point(j).y())
  1024. // );
  1025. //
  1026. //
  1027. // QDomText polyDataText = doc.createTextNode(polyDataString);
  1028. // polyData.appendChild(polyDataText);
  1029. // objects.appendChild(polyData);
  1030. // }
  1031. setPureData();
  1032. QDomElement pureData = doc.createElement(tr("pure_data"));
  1033. QSize imageSize = image_->size();
  1034. QString pixelValues;
  1035. for (int i = 0; i < imageSize.height(); i++) {
  1036. for (int j = 0; j < imageSize.width(); j++) {
  1037. pixelValues.append(QString("%1").arg(pure_data_[i][j]));
  1038. //pixelValues.append(QString(""));
  1039. }
  1040. pixelValues.append("\n");
  1041. }
  1042. QDomText pureDataText = doc.createTextNode(pixelValues);
  1043. pureData.appendChild(pureDataText);
  1044. root.appendChild(pureData);
  1045. QString xml = doc.toString();
  1046. /* ------------------------------------------------------------------------
  1047. * XML part ends
  1048. */
  1049. QFileDialog fileDialog(0, tr("Save all info"));
  1050. fileDialog.setAcceptMode(QFileDialog::AcceptSave);
  1051. fileDialog.setDefaultSuffix("dat");
  1052. fileDialog.setFileMode(QFileDialog::AnyFile);
  1053. /* altering the name of a new file */
  1054. QString newFileName = alterFileName(*current_image_, "_labeled");
  1055. fileDialog.selectFile(newFileName);
  1056. QString filename;
  1057. if (fileDialog.exec()) {
  1058. filename = fileDialog.selectedFiles().last();
  1059. }
  1060. else {
  1061. //showWarning(tr("Can not open file dialog"));
  1062. return;
  1063. /* NOTREACHED */
  1064. }
  1065. if (filename.isEmpty()) {
  1066. return;
  1067. /* NOTREACHED */
  1068. }
  1069. QFile file(filename);
  1070. if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
  1071. showWarning(tr("Can not open file for writing"));
  1072. return;
  1073. /* NOTREACHED */
  1074. }
  1075. file.write(xml.toLocal8Bit());
  1076. file.close();
  1077. }
  1078. void
  1079. ImageLabeler::saveSegmentedPicture()
  1080. {
  1081. if (list_bounding_box_.isEmpty() && list_polygon_.isEmpty()) {
  1082. return;
  1083. /* NOTREACHED */
  1084. }
  1085. setPureData();
  1086. // QString suffix = *current_image_;
  1087. // int dotPos = suffix.lastIndexOf(".");
  1088. // suffix.mid(dotPos + 1, suffix.size() - dotPos - 1);
  1089. QFileDialog fileDialog(0, tr("Save segmented picture"));
  1090. fileDialog.setAcceptMode(QFileDialog::AcceptSave);
  1091. fileDialog.setDefaultSuffix("png");
  1092. fileDialog.setFileMode(QFileDialog::AnyFile);
  1093. /* altering the name of a new file */
  1094. QString newFileName = alterFileName(*current_image_, "_segmented");
  1095. fileDialog.selectFile(newFileName);
  1096. QString filename;
  1097. if (fileDialog.exec()) {
  1098. filename = fileDialog.selectedFiles().last();
  1099. }
  1100. else {
  1101. return;
  1102. /* NOTREACHED */
  1103. }
  1104. QSize imageSize = image_holder_->pixmap()->size();
  1105. QImage newImage(imageSize, QImage::Format_RGB32);
  1106. bool generateColorsFlag = auto_color_generation_;
  1107. bool flag = 0;
  1108. /* checking if all the colors are are different from white(default) */
  1109. if (!generateColorsFlag) {
  1110. for (int i = 1; i < list_label_->count(); i++) {
  1111. if (list_label_colors_.at(i) == 0xffffffff && !flag)
  1112. flag = 1;
  1113. else if (list_label_colors_.at(i) == 0xffffffff && flag) {
  1114. QMessageBox msgBox;
  1115. msgBox.setText(tr("There are few labels with default white color."));
  1116. msgBox.setInformativeText(tr("Do you want to generate all colors automatically? Otherwise you'll have to do it manually."));
  1117. msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
  1118. msgBox.setDefaultButton(QMessageBox::Yes);
  1119. msgBox.setIcon(QMessageBox::Question);
  1120. int ret = msgBox.exec();
  1121. if (QMessageBox::Yes == ret) {
  1122. generateColorsFlag = 1;
  1123. break;
  1124. }
  1125. else {
  1126. return;
  1127. /* NOTREACHED */
  1128. }
  1129. }
  1130. }
  1131. }
  1132. /* generating colors for labels */
  1133. if (list_label_colors_.count() < list_label_->count() ||
  1134. generateColorsFlag) {
  1135. generateColors();
  1136. }
  1137. for (int i = 0; i < imageSize.height(); i++)
  1138. for (int j = 0; j < imageSize.width(); j++) {
  1139. newImage.setPixel(j, i, list_label_colors_.at(pure_data_[i][j]));
  1140. }
  1141. if (!newImage.save(filename, "png", 100))
  1142. showWarning(tr("An error occurred while saving the segmented image"));
  1143. }
  1144. void
  1145. ImageLabeler::saveLegend()
  1146. {
  1147. if (!list_label_->count()) {
  1148. showWarning("You have not added any label yet");
  1149. return;
  1150. /* NOTREACHED */
  1151. }
  1152. /* ------------------------------------------------------------------------
  1153. * XML part
  1154. */
  1155. QDomDocument doc(tr("ImageLabeler"));
  1156. QDomElement root = doc.createElement(tr("root"));
  1157. doc.appendChild(root);
  1158. legendToXml(&doc, &root);
  1159. // QDomElement legend = doc.createElement(tr("legend"));
  1160. // root.appendChild(legend);
  1161. //
  1162. // /* storing all labels made by user */
  1163. // int labelCount = list_label_->count();
  1164. // for (int i = 0; i < labelCount; i++) {
  1165. // QDomElement label = doc.createElement(tr("label"));
  1166. // label.setAttribute("color", QString("%1").arg(list_label_colors_.at(i), 0, 16));
  1167. // label.setAttribute("id", i);
  1168. //
  1169. // QString priority;
  1170. // if (main_label_ == i)
  1171. // priority.append("1");
  1172. // else
  1173. // priority.append("0");
  1174. // label.setAttribute("isMain", priority);
  1175. //
  1176. // QString labelText = list_label_->item(i)->text();
  1177. //
  1178. // /* removing the number prefix of label */
  1179. // if (-1 != labelText.indexOf(QString("%1: ").arg(i))) {
  1180. // labelText = labelText.mid(3, labelText.size() - 3);
  1181. // }
  1182. //
  1183. // QDomText labelName = doc.createTextNode(labelText);
  1184. // label.appendChild(labelName);
  1185. // legend.appendChild(label);
  1186. // }
  1187. //
  1188. // /* in case we have no labels */
  1189. // if (0 == labelCount) {
  1190. // QDomElement label = doc.createElement(tr("label"));
  1191. // label.setAttribute(tr("id"), -1);
  1192. // legend.appendChild(label);
  1193. // }
  1194. QString xml = doc.toString();
  1195. /* ------------------------------------------------------------------------
  1196. * XML part ends
  1197. */
  1198. QFileDialog fileDialog(0, tr("Save legend"));
  1199. fileDialog.setAcceptMode(QFileDialog::AcceptSave);
  1200. fileDialog.setDefaultSuffix("dat");
  1201. fileDialog.setFileMode(QFileDialog::AnyFile);
  1202. /* altering the name of a new file */
  1203. QString newFileName = alterFileName(*current_image_, "_legend");
  1204. fileDialog.selectFile(newFileName);
  1205. QString filename;
  1206. if (fileDialog.exec()) {
  1207. filename = fileDialog.selectedFiles().last();
  1208. }
  1209. else {
  1210. //showWarning(tr("Can not open file dialog"));
  1211. return;
  1212. /* NOTREACHED */
  1213. }
  1214. if (filename.isEmpty()) {
  1215. return;
  1216. /* NOTREACHED */
  1217. }
  1218. QFile file(filename);
  1219. if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
  1220. showWarning(tr("Can not open file for writing"));
  1221. return;
  1222. /* NOTREACHED */
  1223. }
  1224. file.write(xml.toLocal8Bit());
  1225. file.close();
  1226. }
  1227. void
  1228. ImageLabeler::loadInfo()
  1229. {
  1230. if (askForUnsavedData()) {
  1231. return;
  1232. /* NOTREACHED */
  1233. }
  1234. QFileDialog fileDialog(0, tr("Load file with info"));
  1235. fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
  1236. fileDialog.setDefaultSuffix("dat");
  1237. fileDialog.setFileMode(QFileDialog::AnyFile);
  1238. QString filename;
  1239. if (fileDialog.exec()) {
  1240. filename = fileDialog.selectedFiles().last();
  1241. }
  1242. else {
  1243. //showWarning(tr("Can not open file dialog"));
  1244. return;
  1245. /* NOTREACHED */
  1246. }
  1247. QDomDocument doc("Image Labeler");
  1248. QFile file(filename);
  1249. if (!file.open(QIODevice::ReadOnly)) {
  1250. showWarning(tr("Can not open such file"));
  1251. return;
  1252. /* NOTREACHED */
  1253. }
  1254. QString errMsg;
  1255. if (!doc.setContent(&file, &errMsg)) {
  1256. showWarning(errMsg);
  1257. file.close();
  1258. return;
  1259. /* NOTREACHED */
  1260. }
  1261. file.close();
  1262. clearAll();
  1263. list_label_->clear();
  1264. enableTools();
  1265. /* getting all info */
  1266. QDomElement elements = doc.documentElement();
  1267. QDomNode rootNode = elements.firstChild();
  1268. QString string;
  1269. while(!rootNode.isNull()) {
  1270. QDomElement element = rootNode.toElement();
  1271. if(!element.isNull()) {
  1272. /* path to the image */
  1273. if (element.tagName() == "image") {
  1274. string = element.text();
  1275. if (string.isNull()) {
  1276. showWarning(
  1277. tr(
  1278. "The file with data doesn't contain path to the image"
  1279. )
  1280. );
  1281. return;
  1282. /* NOTREACHED */
  1283. }
  1284. list_images_->append(string);
  1285. current_image_ = list_images_->end();
  1286. current_image_--;
  1287. image_->load(*current_image_);
  1288. image_holder_->setPixmap(*image_);
  1289. }
  1290. /* image description */
  1291. else if (element.tagName() == "description" &&
  1292. !element.text().isNull()) {
  1293. image_description_ = element.text();
  1294. }
  1295. /* legend */
  1296. else if (element.tagName() == "legend") {
  1297. loadLegendFromNode(&element);
  1298. }
  1299. /* objects */
  1300. else if (element.tagName() == "objects") {
  1301. QDomNode subNode = element.firstChild();
  1302. QDomElement subElement;
  1303. while(!subNode.isNull()) {
  1304. subElement = subNode.toElement();
  1305. if (subElement.isNull() || subElement.text().isNull()) {
  1306. subNode = subNode.nextSibling();
  1307. continue;
  1308. }
  1309. string = subElement.attribute("id");
  1310. bool ok = 1;
  1311. int id = string.toInt(&ok, 10);
  1312. if (!ok) {
  1313. qDebug() <<
  1314. "while getting poly: "
  1315. "poly id format is corrupted";
  1316. subNode = subNode.nextSibling();
  1317. continue;
  1318. }
  1319. string = subElement.text();
  1320. if (subElement.tagName() == "bbox") {
  1321. setBBoxFromData(&string, &id);
  1322. }
  1323. if (subElement.tagName() == "poly") {
  1324. setPolyFromData(&string, &id);
  1325. }
  1326. subNode = subNode.nextSibling();
  1327. }
  1328. }
  1329. }
  1330. rootNode = rootNode.nextSibling();
  1331. }
  1332. }
  1333. void
  1334. ImageLabeler::loadImages()
  1335. {
  1336. if (askForUnsavedData()) {
  1337. return;
  1338. /* NOTREACHED */
  1339. }
  1340. QFileDialog fileDialog(0, tr("Load images"));
  1341. fileDialog.setFileMode(QFileDialog::Directory);
  1342. QString dirName("");
  1343. if (fileDialog.exec()) {
  1344. /* TODO: make it possible to select multiple folders */
  1345. dirName = fileDialog.selectedFiles().last();
  1346. }
  1347. else {
  1348. //showWarning(tr("Could not open file dialog"));
  1349. return;
  1350. /* NOTREACHED */
  1351. }
  1352. clearAll();
  1353. getImagesFromDir(QDir(dirName));
  1354. if (list_images_->isEmpty()) {
  1355. showWarning(tr("The folder you selected contains no images"));
  1356. return;
  1357. /* NOTREACHED */
  1358. }
  1359. current_image_ = list_images_->begin();
  1360. image_->load(list_images_->first());
  1361. image_holder_->setPixmap(*image_);
  1362. enableTools();
  1363. }
  1364. void
  1365. ImageLabeler::loadLegendFromFile()
  1366. {
  1367. QFileDialog fileDialog(0, tr("Load legend"));
  1368. fileDialog.setFileMode(QFileDialog::AnyFile);
  1369. QString filename;
  1370. if (fileDialog.exec()) {
  1371. filename = fileDialog.selectedFiles().last();
  1372. }
  1373. else {
  1374. //showWarning(tr("Could not open file dialog"));
  1375. return;
  1376. /* NOTREACHED */
  1377. }
  1378. QDomDocument doc("Image Labeler");
  1379. QFile file(filename);
  1380. if (!file.open(QIODevice::ReadOnly)) {
  1381. showWarning(tr("Can not open such file"));
  1382. return;
  1383. /* NOTREACHED */
  1384. }
  1385. QString errMsg;
  1386. if (!doc.setContent(&file, &errMsg)) {
  1387. showWarning(errMsg);
  1388. file.close();
  1389. return;
  1390. /* NOTREACHED */
  1391. }
  1392. file.close();
  1393. list_label_->clear();
  1394. /* getting legend */
  1395. QDomElement elements = doc.documentElement();
  1396. QDomNode rootNode = elements.firstChild();
  1397. QString string;
  1398. while(!rootNode.isNull()) {
  1399. QDomElement element = rootNode.toElement();
  1400. if(!element.isNull()) {
  1401. if (element.tagName() == "legend") {
  1402. loadLegendFromNode(&element);
  1403. }
  1404. }
  1405. rootNode = rootNode.nextSibling();
  1406. }
  1407. }
  1408. void
  1409. ImageLabeler::loadLegendFromNode(QDomElement *anElement)
  1410. {
  1411. if (!anElement) {
  1412. return;
  1413. /* NOTREACHED */
  1414. }
  1415. QDomNode subNode = anElement->firstChild();
  1416. QDomElement subElement;
  1417. QString string;
  1418. int id = -1;
  1419. bool isMain;
  1420. uint color = 0xff000000;
  1421. while(!subNode.isNull()) {
  1422. subElement = subNode.toElement();
  1423. if (!subElement.isNull() && !subElement.text().isNull()) {
  1424. string = subElement.attribute("id");
  1425. bool ok = 0;
  1426. id = string.toInt(&ok, 10);
  1427. if (!ok) {
  1428. qDebug() <<
  1429. "while getting legend: "
  1430. "label id format is corrupted";
  1431. subNode = subNode.nextSibling();
  1432. continue;
  1433. }
  1434. string = subElement.attribute("isMain");
  1435. isMain = string.toInt(&ok, 2);
  1436. if (!ok) {
  1437. qDebug() <<
  1438. "while getting legend: "
  1439. "label isMain flag format is corrupted";
  1440. subNode = subNode.nextSibling();
  1441. continue;
  1442. }
  1443. string = subElement.attribute("color");
  1444. color = string.toUInt(&ok, 16);
  1445. if (!ok) {
  1446. qDebug() <<
  1447. "while getting legend: "
  1448. "label color format is corrupted";
  1449. subNode = subNode.nextSibling();
  1450. continue;
  1451. }
  1452. string = subElement.text();
  1453. addLabel(id, isMain, string);
  1454. setLabelColor(id, color);
  1455. }
  1456. subNode = subNode.nextSibling();
  1457. }
  1458. }
  1459. void
  1460. ImageLabeler::legendToXml(QDomDocument *aDoc, QDomElement *aRoot)
  1461. {
  1462. QDomElement legend = aDoc->createElement(tr("legend"));
  1463. aRoot->appendChild(legend);
  1464. /* storing all labels made by user */
  1465. int labelCount = list_label_->count();
  1466. for (int i = 0; i < labelCount; i++) {
  1467. QDomElement label = aDoc->createElement(tr("label"));
  1468. label.setAttribute("color", QString("%1").arg(list_label_colors_.at(i), 0, 16));
  1469. label.setAttribute("id", i);
  1470. QString priority;
  1471. if (main_label_ == i)
  1472. priority.append("1");
  1473. else
  1474. priority.append("0");
  1475. label.setAttribute("isMain", priority);
  1476. QString labelText = list_label_->item(i)->text();
  1477. /* removing the number prefix of label */
  1478. if (-1 != labelText.indexOf(QString("%1: ").arg(i))) {
  1479. labelText = labelText.mid(3, labelText.size() - 3);
  1480. }
  1481. QDomText labelName = aDoc->createTextNode(labelText);
  1482. label.appendChild(labelName);
  1483. legend.appendChild(label);
  1484. }
  1485. /* in case we have no labels */
  1486. if (0 == labelCount) {
  1487. QDomElement label = aDoc->createElement(tr("label"));
  1488. label.setAttribute(tr("id"), -1);
  1489. legend.appendChild(label);
  1490. }
  1491. }
  1492. void
  1493. ImageLabeler::objectsToXml(QDomDocument *aDoc, QDomElement *aRoot)
  1494. {
  1495. QDomElement objects = aDoc->createElement(tr("objects"));
  1496. aRoot->appendChild(objects);
  1497. /* rects first */
  1498. for (int i = 0; i < list_bounding_box_.size(); i++) {
  1499. QDomElement rectData = aDoc->createElement(tr("bbox"));
  1500. rectData.setAttribute("id", list_bounding_box_.at(i).label_ID_);
  1501. QRect rect = list_bounding_box_.at(i).rect.normalized();
  1502. QString rectDataString =
  1503. QString("%1;%2;%3;%4;").
  1504. arg(rect.x()).
  1505. arg(rect.y()).
  1506. arg(rect.width()).
  1507. arg(rect.height());
  1508. QDomText rectDataText = aDoc->createTextNode(rectDataString);
  1509. rectData.appendChild(rectDataText);
  1510. objects.appendChild(rectData);
  1511. }
  1512. /* polys next */
  1513. for (int i = 0; i < list_polygon_.size(); i++) {
  1514. QDomElement polyData = aDoc->createElement(tr("poly"));
  1515. polyData.setAttribute("id", list_polygon_.at(i).label_ID_);
  1516. QPolygon poly = list_polygon_.at(i).poly;
  1517. QString polyDataString;
  1518. for (int j = 0; j < poly.count(); j++)
  1519. polyDataString.append(
  1520. QString("%1;%2;").
  1521. arg(poly.point(j).x()).
  1522. arg(poly.point(j).y())
  1523. );
  1524. QDomText polyDataText = aDoc->createTextNode(polyDataString);
  1525. polyData.appendChild(polyDataText);
  1526. objects.appendChild(polyData);
  1527. }
  1528. }
  1529. void
  1530. ImageLabeler::generateColors()
  1531. {
  1532. int labelCount = list_label_->count();
  1533. if (!labelCount) {
  1534. showWarning(tr("you have not added any labels yet"));
  1535. return;
  1536. /* NOTREACHED */
  1537. }
  1538. int coeff = (0xff / labelCount) * 3;
  1539. //QList< uint > colors;
  1540. list_label_colors_.clear();
  1541. list_label_colors_.append(0);
  1542. uchar red = 0xff;
  1543. uchar green = 0xff;
  1544. uchar blue = 0xff;
  1545. uchar iterationColor = coeff;
  1546. uint color = 0xffffffff;
  1547. int j = 1;
  1548. for (int i = 1; i < labelCount; i++) {
  1549. if (6 == j) {
  1550. iterationColor += coeff;
  1551. j = 1;
  1552. }
  1553. if (5 == j) {
  1554. red = 0xff - iterationColor;
  1555. green = 0xff - iterationColor;
  1556. blue = 0xff;
  1557. }
  1558. else if (4 == j) {
  1559. red = 0xff - iterationColor;
  1560. green = 0xff;
  1561. blue = 0xff - iterationColor;
  1562. }
  1563. else if (3 == j) {
  1564. red = 0xff - iterationColor;
  1565. green = 0xff;
  1566. blue = 0xff;
  1567. }
  1568. else if (2 == j) {
  1569. red = 0xff;
  1570. green = 0xff - iterationColor;
  1571. blue = 0xff;
  1572. }
  1573. else if (1 == j){
  1574. red = 0xff;
  1575. green = 0xff;
  1576. blue = 0xff - iterationColor;
  1577. }
  1578. j++;
  1579. color = red + (green * 0x100) + (blue * 0x10000) + 0xff000000;
  1580. int itemNo = list_label_colors_.count();
  1581. QPixmap iconPix = QPixmap(20, 20);
  1582. iconPix.fill(color);
  1583. QIcon icon(iconPix);
  1584. list_label_->item(itemNo)->setIcon(icon);
  1585. list_label_colors_.append(color);
  1586. }
  1587. }
  1588. void
  1589. ImageLabeler::setBBoxFromData(
  1590. QString *aBBoxData,
  1591. int *ID
  1592. )
  1593. {
  1594. BoundingBox bbox = BBoxFromData(aBBoxData);
  1595. if (!bbox.rect.isValid() || !ID) {
  1596. return;
  1597. /* NOTREACHED */
  1598. }
  1599. bbox.label_ID_ = *ID;
  1600. list_bounding_box_.append(bbox);
  1601. addBBoxArea(list_bounding_box_.count() - 1, bbox);
  1602. }
  1603. BoundingBox
  1604. ImageLabeler::BBoxFromData(
  1605. QString *aBBoxData
  1606. )
  1607. {
  1608. BoundingBox bbox;
  1609. QString buffer;
  1610. bbox.rect.setRect(-1, -1, -1, -1);
  1611. int startPos = 0;
  1612. bool ok = 1;
  1613. for (int i = 0; i < aBBoxData->size(); i++) {
  1614. if (';' != aBBoxData->at(i))
  1615. continue;
  1616. buffer = aBBoxData->mid(startPos, i - startPos);
  1617. int bboxData = buffer.toInt(&ok, 10);
  1618. if (!ok) {
  1619. qDebug() <<
  1620. "while getting objects: "
  1621. "poly format is corrupted";
  1622. break;
  1623. }
  1624. if (-1 == bbox.rect.x()) {
  1625. bbox.rect.setX(bboxData);
  1626. bbox.rect.setWidth(-1);
  1627. }
  1628. else if (-1 == bbox.rect.y()) {
  1629. bbox.rect.setY(bboxData);
  1630. bbox.rect.setHeight(-1);
  1631. }
  1632. else if (-1 == bbox.rect.width()) {
  1633. bbox.rect.setWidth(bboxData);
  1634. }
  1635. else if (-1 == bbox.rect.height()) {
  1636. bbox.rect.setHeight(bboxData);
  1637. }
  1638. startPos = i + 1;
  1639. }
  1640. if (!bbox.rect.isValid()) {
  1641. qDebug() <<
  1642. "BBoxFromData: "
  1643. "bbox format is corrupted";
  1644. bbox.rect.setRect(-1, -1, -1, -1);
  1645. }
  1646. else if (!ok) {
  1647. bbox.rect.setRect(-1, -1, -1, -1);
  1648. }
  1649. return bbox;
  1650. }
  1651. BoundingBox
  1652. ImageLabeler::BBoxFromString(
  1653. QString *aString,
  1654. int *oldID
  1655. )
  1656. {
  1657. BoundingBox bbox;
  1658. bbox.label_ID_ = -1;
  1659. *oldID = -1;
  1660. if (!aString) {
  1661. return bbox;
  1662. /* NOTREACHED */
  1663. }
  1664. if (-1 == aString->indexOf("BBox")) {
  1665. return bbox;
  1666. /* NOTREACHED */
  1667. }
  1668. /* getting bbox id in the list(it cannot be changed) */
  1669. bool ok = 0;
  1670. int bboxID = getNumFromString(aString, "BBox #", ";", &ok);
  1671. if (!ok || -1 <= bboxID) {
  1672. qDebug() <<
  1673. "BBoxFromString: poly ID is corrupted";
  1674. return bbox;
  1675. /* NOTREACHED */
  1676. }
  1677. /* getting new label id */
  1678. int labelID = getNumFromString(aString, "LabelID: ", ";", &ok);
  1679. if (!ok || -1 <= labelID) {
  1680. showWarning(
  1681. tr("new LabelID is wrong, area can not be changed")
  1682. );
  1683. return bbox;
  1684. /* NOTREACHED */
  1685. }
  1686. /* getting new points */
  1687. int pointsPos = aString->indexOf("points:") + 7;
  1688. int pointsLen = aString->size() - pointsPos;
  1689. if (pointsLen <= 0) {
  1690. showWarning(
  1691. tr("new points data is wrong, area can not be changed")
  1692. );
  1693. return bbox;
  1694. /* NOTREACHED */
  1695. }
  1696. QString pointsData = aString->mid(pointsPos, pointsLen);
  1697. bbox = BBoxFromData(&pointsData);
  1698. bbox.label_ID_ = labelID;
  1699. *oldID = bboxID;
  1700. return bbox;
  1701. }
  1702. void
  1703. ImageLabeler::setPolyFromData(
  1704. QString *aPolyData,
  1705. int *ID
  1706. )
  1707. {
  1708. Polygon poly = polyFromData(aPolyData);
  1709. if (poly.poly.isEmpty() || !ID) {
  1710. return;
  1711. /* NOTREACHED */
  1712. }
  1713. poly.label_ID_ = *ID;
  1714. list_polygon_.append(poly);
  1715. addPolyArea(list_polygon_.count() - 1, poly);
  1716. }
  1717. Polygon
  1718. ImageLabeler::polyFromData(
  1719. QString *aPolyData
  1720. )
  1721. {
  1722. Polygon poly;
  1723. poly.label_ID_ = -1;
  1724. QPoint point;
  1725. QString buffer;
  1726. int startPos = 0;
  1727. bool ok = 1;
  1728. bool evenFlag = 0;
  1729. for (int i = 0; i < aPolyData->size(); i++) {
  1730. if (';' != aPolyData->at(i))
  1731. continue;
  1732. buffer = aPolyData->mid(startPos, i - startPos);
  1733. int polyCoor = buffer.toInt(&ok, 10);
  1734. if (!ok) {
  1735. qDebug() <<
  1736. "while getting objects: "
  1737. "poly format is corrupted";
  1738. break;
  1739. }
  1740. if (!evenFlag) {
  1741. point.setX(polyCoor);
  1742. evenFlag = 1;
  1743. }
  1744. else {
  1745. point.setY(polyCoor);
  1746. poly.poly.append(point);
  1747. evenFlag = 0;
  1748. }
  1749. startPos = i + 1;
  1750. }
  1751. if (evenFlag) {
  1752. qDebug() <<
  1753. "polyFromData: "
  1754. "poly format is corrupted";
  1755. poly.poly.clear();
  1756. }
  1757. else if (!ok) {
  1758. poly.poly.clear();
  1759. }
  1760. return poly;
  1761. }
  1762. Polygon
  1763. ImageLabeler::polyFromString(
  1764. QString *aString,
  1765. int *oldID
  1766. )
  1767. {
  1768. Polygon poly;
  1769. poly.label_ID_ = -1;
  1770. *oldID = -1;
  1771. if (!aString) {
  1772. return poly;
  1773. /* NOTREACHED */
  1774. }
  1775. if (-1 == aString->indexOf("Poly")) {
  1776. return poly;
  1777. /* NOTREACHED */
  1778. }
  1779. /* getting poly id in the list(it cannot be changed) */
  1780. bool ok = 0;
  1781. int polyID = getNumFromString(aString, "Poly #", ";", &ok);
  1782. if (!ok || -1 <= polyID) {
  1783. qDebug() <<
  1784. "polyFromString: poly ID is corrupted";
  1785. return poly;
  1786. /* NOTREACHED */
  1787. }
  1788. /* getting new label id */
  1789. int labelID = getNumFromString(aString, "LabelID: ", ";", &ok);
  1790. if (!ok || -1 <= labelID) {
  1791. showWarning(
  1792. tr("new LabelID is wrong, area can not be changed")
  1793. );
  1794. return poly;
  1795. /* NOTREACHED */
  1796. }
  1797. /* getting new points */
  1798. int pointsPos = aString->indexOf("points:") + 7;
  1799. int pointsLen = aString->size() - pointsPos;
  1800. if (pointsLen <= 0) {
  1801. showWarning(
  1802. tr("new points data is wrong, area can not be changed")
  1803. );
  1804. return poly;
  1805. /* NOTREACHED */
  1806. }
  1807. QString pointsData = aString->mid(pointsPos, pointsLen);
  1808. poly = polyFromData(&pointsData);
  1809. poly.label_ID_ = labelID;
  1810. *oldID = polyID;
  1811. return poly;
  1812. }
  1813. void
  1814. ImageLabeler::showWarning(
  1815. const QString text
  1816. )
  1817. {
  1818. if (text.isEmpty()) {
  1819. return;
  1820. /* NOTREACHED */
  1821. }
  1822. QMessageBox msgBox;
  1823. msgBox.setText(text);
  1824. msgBox.setIcon(QMessageBox::Warning);
  1825. msgBox.exec();
  1826. }
  1827. bool
  1828. ImageLabeler::askForUnsavedData()
  1829. {
  1830. if (!list_bounding_box_.isEmpty() ||
  1831. !list_polygon_.isEmpty())
  1832. {
  1833. QMessageBox msgBox;
  1834. msgBox.setText(tr("There is some unsaved data"));
  1835. msgBox.setInformativeText(tr("Do you want to save your progress?"));
  1836. msgBox.setStandardButtons(
  1837. QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
  1838. msgBox.setDefaultButton(QMessageBox::Save);
  1839. msgBox.setIcon(QMessageBox::Question);
  1840. int ret = msgBox.exec();
  1841. if (QMessageBox::Save == ret)
  1842. saveAllInfo();
  1843. else if (QMessageBox::Cancel == ret)
  1844. return true;
  1845. }
  1846. return false;
  1847. }
  1848. void
  1849. ImageLabeler::setBoundingBoxTool(bool aButtonPressed)
  1850. {
  1851. if (aButtonPressed)
  1852. image_holder_->setTool(ImageHolder::BoundingBoxTool);
  1853. else {
  1854. image_holder_->setTool(ImageHolder::NoTool);
  1855. image_holder_->clearLast();
  1856. }
  1857. }
  1858. void
  1859. ImageLabeler::setPolygonTool(bool aButtonPressed)
  1860. {
  1861. if (aButtonPressed) {
  1862. image_holder_->setTool(ImageHolder::PolygonTool);
  1863. image_holder_->setFocus();
  1864. }
  1865. else {
  1866. image_holder_->setTool(ImageHolder::NoTool);
  1867. image_holder_->clearLast();
  1868. }
  1869. }
  1870. void
  1871. ImageLabeler::onSelectionStarted()
  1872. {
  1873. button_confirm_selection_->setEnabled(true);
  1874. }
  1875. void
  1876. ImageLabeler::onImageScaled()
  1877. {
  1878. }
  1879. void
  1880. ImageLabeler::confirmSelection()
  1881. {
  1882. if (!list_label_->count()) {
  1883. showWarning(tr("You haven't added any label"));
  1884. return;
  1885. /* NOTREACHED */
  1886. }
  1887. image_holder_->confirmSelection();
  1888. if (label_ID_ < 0)
  1889. label_ID_ = 0;
  1890. ImageHolder::Tool tool = image_holder_->tool();
  1891. switch (tool) {
  1892. case ImageHolder::BoundingBoxTool:
  1893. list_bounding_box_.last().label_ID_ = label_ID_;
  1894. addBBoxArea(
  1895. list_bounding_box_.count() - 1,
  1896. list_bounding_box_.last()
  1897. );
  1898. break;
  1899. case ImageHolder::PolygonTool:
  1900. list_polygon_.last().label_ID_ = label_ID_;
  1901. addPolyArea(
  1902. list_polygon_.count() - 1,
  1903. list_polygon_.last()
  1904. );
  1905. break;
  1906. default:
  1907. break;
  1908. }
  1909. button_confirm_selection_->setEnabled(false);
  1910. }
  1911. void
  1912. ImageLabeler::clearAll()
  1913. {
  1914. clearLabelList();
  1915. list_areas_->clear();
  1916. list_bounding_box_.clear();
  1917. list_polygon_.clear();
  1918. list_images_->clear();
  1919. main_label_ = -1;
  1920. image_holder_->clearAll();
  1921. }
  1922. void
  1923. ImageLabeler::clearAllTool()
  1924. {
  1925. list_areas_->clear();
  1926. list_bounding_box_.clear();
  1927. list_polygon_.clear();
  1928. main_label_ = -1;
  1929. image_holder_->clearAll();
  1930. }
  1931. void ImageLabeler::clearLabelList()
  1932. {
  1933. list_label_->clear();
  1934. addLabel(0, false, "BACKGROUND");
  1935. list_label_->item(0)->setFlags(
  1936. Qt::ItemIsUserCheckable | Qt::ItemIsSelectable |
  1937. Qt::ItemIsEnabled
  1938. );
  1939. }
  1940. void
  1941. ImageLabeler::enableTools()
  1942. {
  1943. action_save_labels_->setEnabled(true);
  1944. action_save_segmented_->setEnabled(true);
  1945. action_save_legend_->setEnabled(true);
  1946. action_bound_box_tool_->setEnabled(true);
  1947. action_polygon_tool_->setEnabled(true);
  1948. action_add_description_->setEnabled(true);
  1949. button_bound_box_tool_->setEnabled(true);
  1950. button_polygon_tool_->setEnabled(true);
  1951. button_add_label_->setEnabled(true);
  1952. button_remove_label_->setEnabled(true);
  1953. button_prev_image_->setEnabled(true);
  1954. button_next_image_->setEnabled(true);
  1955. button_clear_selection_tool_->setEnabled(true);
  1956. button_generate_colors_->setEnabled(true);
  1957. button_delete_all_labels_->setEnabled(true);
  1958. }
  1959. void
  1960. ImageLabeler::disableTools()
  1961. {
  1962. action_save_labels_->setEnabled(false);
  1963. action_save_segmented_->setEnabled(false);
  1964. action_save_legend_->setEnabled(false);
  1965. action_bound_box_tool_->setEnabled(false);
  1966. action_polygon_tool_->setEnabled(false);
  1967. action_add_description_->setEnabled(false);
  1968. button_bound_box_tool_->setEnabled(false);
  1969. button_polygon_tool_->setEnabled(false);
  1970. button_add_label_->setEnabled(false);
  1971. button_remove_label_->setEnabled(false);
  1972. button_prev_image_->setEnabled(false);
  1973. button_next_image_->setEnabled(false);
  1974. button_clear_selection_tool_->setEnabled(false);
  1975. button_generate_colors_->setEnabled(false);
  1976. button_delete_all_labels_->setEnabled(false);
  1977. }
  1978. void
  1979. ImageLabeler::areaListPopupMenu(const QPoint &aPos)
  1980. {
  1981. QPoint globalPos = list_areas_->mapToGlobal(aPos);
  1982. QModelIndex index = list_areas_->indexAt(aPos);
  1983. if (-1 == index.row()) {
  1984. return;
  1985. /* NOTREACHED */
  1986. }
  1987. list_areas_->item(index.row())->setSelected(true);
  1988. popup_area_list_->exec(globalPos);
  1989. }
  1990. void
  1991. ImageLabeler::labelListPopupMenu(const QPoint &aPos)
  1992. {
  1993. QPoint globalPos = list_label_->mapToGlobal(aPos);
  1994. QModelIndex index = list_label_->indexAt(aPos);
  1995. if (-1 == index.row() || !index.row()) {
  1996. return;
  1997. /* NOTREACHED */
  1998. }
  1999. list_label_->item(index.row())->setSelected(true);
  2000. popup_label_list_->exec(globalPos);
  2001. }
  2002. void
  2003. ImageLabeler::setDescription(QString aDescription)
  2004. {
  2005. image_description_ = aDescription;
  2006. setWindowTitle(image_description_);
  2007. }
  2008. void
  2009. ImageLabeler::setPureData()
  2010. {
  2011. /* initializing array */
  2012. if (pure_data_) {
  2013. delete[] *pure_data_;
  2014. delete pure_data_;
  2015. }
  2016. QSize imageSize = image_->size();
  2017. pure_data_ = new int *[imageSize.height()];
  2018. if (!pure_data_) {
  2019. return;
  2020. /* NOTREACHED */
  2021. }
  2022. for (int i = 0; i < imageSize.height(); i++) {
  2023. pure_data_[i] = new int[imageSize.width()];
  2024. if (!pure_data_[i]) {
  2025. return;
  2026. /* NOTREACHED */
  2027. }
  2028. }
  2029. int bboxCnt = list_bounding_box_.count();
  2030. int polyCnt = list_polygon_.count();
  2031. for (int i = 0; i < imageSize.height(); i++)
  2032. for (int j = 0; j < imageSize.width(); j++) {
  2033. pure_data_[i][j] = 0;
  2034. /* bboxes first */
  2035. for (int cnt = 0; cnt < bboxCnt; cnt++) {
  2036. BoundingBox bbox = list_bounding_box_.at(cnt);
  2037. if (bbox.rect.contains(j, i)) {
  2038. pure_data_[i][j] = bbox.label_ID_;
  2039. }
  2040. }
  2041. /* polys next */
  2042. for (int cnt = 0; cnt < polyCnt; cnt++) {
  2043. Polygon poly = list_polygon_.at(cnt);
  2044. if (poly.poly.containsPoint(QPoint(j, i), Qt::OddEvenFill)) {
  2045. pure_data_[i][j] = poly.label_ID_;
  2046. }
  2047. }
  2048. }
  2049. }
  2050. void
  2051. ImageLabeler::setLabelColor()
  2052. {
  2053. if (list_label_colors_.count() < list_label_->count()) {
  2054. generateColors();
  2055. }
  2056. QListWidgetItem *current = list_label_->currentItem();
  2057. int labelID = list_label_->row(current);
  2058. QColor defaultColor;
  2059. defaultColor.setRgb(list_label_colors_.at(labelID));
  2060. QColor newColor = QColorDialog::getColor(
  2061. defaultColor,
  2062. list_label_
  2063. );
  2064. if (!newColor.isValid()) {
  2065. return;
  2066. /* NOTREACHED */
  2067. }
  2068. list_label_colors_.takeAt(labelID);
  2069. list_label_colors_.insert(labelID, newColor.rgb());
  2070. QPixmap iconPix = QPixmap(20, 20);
  2071. iconPix.fill(newColor);
  2072. QIcon icon(iconPix);
  2073. current->setIcon(icon);
  2074. }
  2075. void
  2076. ImageLabeler::setLabelColor(int anID, QColor aColor)
  2077. {
  2078. if (anID < 0) {
  2079. return;
  2080. /* NOTREACHED */
  2081. }
  2082. if (list_label_colors_.count() < list_label_->count()) {
  2083. generateColors();
  2084. }
  2085. QListWidgetItem *item = list_label_->item(anID);
  2086. list_label_colors_.takeAt(anID);
  2087. list_label_colors_.insert(anID, aColor.rgb());
  2088. QPixmap iconPix = QPixmap(20, 20);
  2089. iconPix.fill(aColor);
  2090. QIcon icon(iconPix);
  2091. item->setIcon(icon);
  2092. }
  2093. void
  2094. ImageLabeler::onOptionsSet()
  2095. {
  2096. auto_color_generation_ = options_form_.autoColorGeneration();
  2097. }
  2098. void
  2099. ImageLabeler::resizeEvent (QResizeEvent *anEvent)
  2100. {
  2101. QWidget::resizeEvent(anEvent);
  2102. }
  2103. void
  2104. ImageLabeler::mousePressEvent(QMouseEvent *anEvent)
  2105. {
  2106. QWidget::mousePressEvent(anEvent);
  2107. }
  2108. void
  2109. ImageLabeler::keyPressEvent(QKeyEvent *anEvent)
  2110. {
  2111. if (Qt::Key_Left == anEvent->key() &&
  2112. Qt::NoModifier == anEvent->modifiers()) {
  2113. prevImage();
  2114. }
  2115. if (Qt::Key_Right == anEvent->key() &&
  2116. Qt::NoModifier == anEvent->modifiers()) {
  2117. nextImage();
  2118. }
  2119. if (Qt::Key_Enter == anEvent->key() &&
  2120. // Qt::NoModifier == anEvent->modifiers() &&
  2121. ImageHolder::NewSelection == image_holder_->state()) {
  2122. confirmSelection();
  2123. }
  2124. if (Qt::Key_Escape == anEvent->key()) {
  2125. image_holder_->clearLast();
  2126. image_holder_->clearFocusOnArea();
  2127. }
  2128. QWidget::keyPressEvent(anEvent);
  2129. }
  2130. /* TODO: finish scaling */
  2131. void
  2132. ImageLabeler::wheelEvent(QWheelEvent *anEvent)
  2133. {
  2134. /* zoomin */
  2135. if (0 < anEvent->delta()) {
  2136. //image_holder_->scaleImage(ZoomIn, 1.1);
  2137. }
  2138. /* zoomout */
  2139. else if (anEvent->delta() < 0) {
  2140. //image_holder_->scaleImage(ZoomOut, 1.1);
  2141. }
  2142. }
  2143. /*
  2144. *
  2145. */