ImageLabeler.cpp 57 KB

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