ImageHolder.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. /*
  2. * ImageHolder.cpp
  3. *
  4. * Created on: Oct 5, 2011
  5. * Author: gapchich
  6. */
  7. #include "ImageHolder.h"
  8. #include "functions.h"
  9. #include <QKeyEvent>
  10. #include <QMouseEvent>
  11. #include <QPainter>
  12. #include <QListWidgetItem>
  13. #include <QDebug>
  14. ImageHolder::ImageHolder(QWidget *aParent)
  15. : QLabel(aParent)
  16. {
  17. repaint_needed_ = 0;
  18. tool_ = NoTool;
  19. state_ = StandBy;
  20. keyboard_modifier_ = Qt::NoModifier;
  21. focused_selection_ = -1;
  22. focused_selection_type_ = NoTool;
  23. list_bounding_box_ = 0;
  24. main_label_ = 0;
  25. //list_bounding_box_ = new QList< QRect >;
  26. scale_ = 1;
  27. setScaledContents(true);
  28. }
  29. ImageHolder::~ImageHolder()
  30. {
  31. //list_bounding_box_->clear();
  32. //delete list_bounding_box_;
  33. }
  34. void
  35. ImageHolder::paintEvent(QPaintEvent *anEvent)
  36. {
  37. QLabel::paintEvent(anEvent);
  38. QPainter painter(this);
  39. painter.setRenderHint(QPainter::Antialiasing);
  40. //painter.setRenderHint(QPainter::SmoothPixmapTransform);
  41. QPen pen;
  42. if (NoTool != tool_) {
  43. pen.setWidth(1);
  44. pen.setColor(QColor(Qt::black));
  45. pen.setStyle(Qt::DashLine);
  46. painter.setPen(pen);
  47. if (BoundingBoxTool == tool_) {
  48. /* scaling */
  49. QRect bbox = bounding_box_.rect;
  50. QPoint bboxTopLeft = bbox.topLeft() * scale_;
  51. QPoint bboxBottomRight = bbox.bottomRight() * scale_;
  52. bbox.setTopLeft(bboxTopLeft);
  53. bbox.setBottomRight(bboxBottomRight);
  54. painter.drawRect(bbox);
  55. }
  56. else if (PolygonTool == tool_) {
  57. /* scaling */
  58. QPoint point;
  59. QPolygon poly = polygon_.poly;
  60. for (int i = 0; i < poly.size(); i++) {
  61. point.setX(poly.at(i).x());
  62. point.setY(poly.at(i).y());
  63. point *= scale_;
  64. poly.remove(i);
  65. poly.insert(i, point);
  66. }
  67. painter.drawPolygon(poly);
  68. }
  69. // switch(tool_) {
  70. // case BoundingBoxTool:
  71. // painter.drawRect();
  72. // break;
  73. // case PolygonTool:
  74. // painter.drawPolygon(polygon_.poly);
  75. // break;
  76. // default:
  77. // break;
  78. // }
  79. }
  80. /* drawing bounding boxes */
  81. drawBoundingBoxes(&painter, &pen);
  82. drawPolygons(&painter, &pen);
  83. }
  84. void
  85. ImageHolder::drawBoundingBoxes(
  86. QPainter *aPainter,
  87. QPen *aPen
  88. )
  89. {
  90. /* FIXME: hardcoded colors */
  91. if (0 == list_bounding_box_)
  92. {
  93. return;
  94. /* NOTREACHED */
  95. }
  96. Qt::PenStyle penStyle = Qt::SolidLine;
  97. int width = 1;
  98. /* confirmed boxes */
  99. for (int i = 0; i < list_bounding_box_->size(); i++) {
  100. int labelID = list_bounding_box_->at(i).label_ID_;
  101. if (labelID < list_label_color_->count())
  102. aPen->setColor(QColor(list_label_color_->at(labelID)));
  103. else
  104. aPen->setColor(QColor(Qt::white));
  105. /* checking whether labeled area is of main object or not */
  106. if (labelID == *main_label_)
  107. width = 3;
  108. else
  109. width = 1;
  110. if (BoundingBoxTool == focused_selection_type_ &&
  111. focused_selection_ == i) {
  112. penStyle = Qt::DotLine;
  113. width = 2;
  114. }
  115. aPen->setWidth(width);
  116. aPen->setStyle(penStyle);
  117. aPainter->setPen(*aPen);
  118. /* scaling */
  119. QRect rect = list_bounding_box_->at(i).rect.normalized();
  120. QPoint topLeft = rect.topLeft() * scale_;
  121. QPoint bottomRight = rect.bottomRight() * scale_;
  122. rect.setTopLeft(topLeft);
  123. rect.setBottomRight(bottomRight);
  124. aPainter->drawRect(rect);
  125. /* drawing label ids of these boxes */
  126. QString labelIDText =
  127. QString("%1").arg(labelID);
  128. aPainter->drawText(
  129. rect.left() + 5,
  130. rect.top() + 5,
  131. 20,
  132. 20,
  133. Qt::AlignLeft,
  134. labelIDText
  135. );
  136. }
  137. }
  138. void
  139. ImageHolder::drawPolygons(
  140. QPainter *aPainter,
  141. QPen *aPen
  142. )
  143. {
  144. /* FIXME: hardcoded colors */
  145. if (0 == list_polygon_)
  146. {
  147. return;
  148. /* NOTREACHED */
  149. }
  150. Qt::PenStyle penStyle = Qt::SolidLine;
  151. int width = 1;
  152. /* confirmed polygons */
  153. for (int i = 0; i < list_polygon_->size(); i++) {
  154. penStyle = Qt::SolidLine;
  155. int labelID = list_polygon_->at(i).label_ID_;
  156. if (labelID < list_label_color_->count())
  157. aPen->setColor(QColor(list_label_color_->at(labelID)));
  158. else
  159. aPen->setColor(QColor(Qt::white));
  160. /* checking whether labeled area is of main object or not */
  161. if (labelID == *main_label_)
  162. width = 3;
  163. else
  164. width = 1;
  165. if (PolygonTool == focused_selection_type_ &&
  166. focused_selection_ == i) {
  167. penStyle = Qt::DotLine;
  168. width = 2;
  169. }
  170. aPen->setWidth(width);
  171. aPen->setStyle(penStyle);
  172. aPainter->setPen(*aPen);
  173. QPoint point;
  174. QPolygon poly = list_polygon_->at(i).poly;
  175. for (int j = 0; j < poly.size(); j++) {
  176. point.setX(poly.at(j).x());
  177. point.setY(poly.at(j).y());
  178. point *= scale_;
  179. poly.remove(j);
  180. poly.insert(j, point);
  181. }
  182. aPainter->drawPolygon(poly);
  183. /* drawing label ids of these polys */
  184. QString labelIDText =
  185. QString("%1").arg(labelID);
  186. QRect rect = poly.boundingRect();
  187. int x = rect.center().x();
  188. int y = rect.center().y();
  189. aPainter->drawText(
  190. x,
  191. y,
  192. 20,
  193. 20,
  194. Qt::AlignHCenter,
  195. labelIDText
  196. );
  197. }
  198. }
  199. void
  200. ImageHolder::triggerBoundBox(
  201. const QPoint &aNewPos,
  202. const QPoint &anOldPos,
  203. QRect *aNewRect
  204. )
  205. {
  206. aNewRect->setCoords(
  207. anOldPos.x(),
  208. anOldPos.y(),
  209. aNewPos.x(),
  210. aNewPos.y()
  211. );
  212. state_ = NewSelection;
  213. repaint_needed_ = 1;
  214. }
  215. void
  216. ImageHolder::triggerPolygon(
  217. const QPoint &aPoint,
  218. QPolygon *aNewPoly
  219. )
  220. {
  221. *aNewPoly << aPoint;
  222. repaint_needed_ = 1;
  223. }
  224. void
  225. ImageHolder::focusOnArea(QListWidgetItem *anItem)
  226. {
  227. QString text = anItem->text();
  228. Tool tool = NoTool;
  229. if (-1 != text.indexOf("BBox"))
  230. tool = BoundingBoxTool;
  231. else if (-1 != text.indexOf("Poly"))
  232. tool = PolygonTool;
  233. /* looking for a number of selected area */
  234. if (NoTool != tool) {
  235. bool ok = 0;
  236. focused_selection_ = getNumFromString(&text, "#", ";", &ok);
  237. if (!ok) {
  238. focused_selection_ = -1;
  239. focused_selection_type_ = NoTool;
  240. return;
  241. /* NOTREACHED */
  242. }
  243. switch (tool) {
  244. case BoundingBoxTool:
  245. focused_selection_type_ = BoundingBoxTool;
  246. break;
  247. case PolygonTool:
  248. focused_selection_type_ = PolygonTool;
  249. break;
  250. default:
  251. focused_selection_type_ = NoTool;
  252. break;
  253. }
  254. }
  255. update();
  256. }
  257. void
  258. ImageHolder::scaleImage(
  259. ZoomDirection aDirection,
  260. double scaleFactor
  261. )
  262. {
  263. //QSize size = pixmap()->size();
  264. QSize size = this->size();
  265. /* zoomin */
  266. if (ZoomIn == aDirection) {
  267. size *= scaleFactor;
  268. scale_ *= scaleFactor;
  269. }
  270. /* zoomout */
  271. else if (ZoomOut == aDirection) {
  272. size /= scaleFactor;
  273. scale_ /= scaleFactor;
  274. }
  275. // setScaledContents(true);
  276. this->resize(size);
  277. // setPixmap(
  278. // image_->scaled(
  279. // size,
  280. // Qt::IgnoreAspectRatio,
  281. // Qt::SmoothTransformation
  282. // )
  283. // );
  284. // setScaledContents(false);
  285. //resize(scaleFactor * pixmap()->size());
  286. //emit imageScaled();
  287. }
  288. void
  289. ImageHolder::clearFocusOnArea()
  290. {
  291. focused_selection_ = -1;
  292. focused_selection_type_ = NoTool;
  293. }
  294. void
  295. ImageHolder::setTool(Tool aTool)
  296. {
  297. switch(aTool) {
  298. case BoundingBoxTool:
  299. tool_ = BoundingBoxTool;
  300. break;
  301. case PolygonTool:
  302. tool_ = PolygonTool;
  303. break;
  304. case TaggingTool:
  305. tool_ = TaggingTool;
  306. break;
  307. default:
  308. tool_ = NoTool;
  309. break;
  310. }
  311. }
  312. void
  313. ImageHolder::setBoundingBoxList(QList< BoundingBox > *aBBoxList)
  314. {
  315. if (0 == aBBoxList) {
  316. return;
  317. /* NOTREACHED */
  318. }
  319. list_bounding_box_ = aBBoxList;
  320. }
  321. void
  322. ImageHolder::setPolygonList(QList< Polygon > *aPolygonList)
  323. {
  324. if (0 == aPolygonList) {
  325. return;
  326. /* NOTREACHED */
  327. }
  328. list_polygon_ = aPolygonList;
  329. }
  330. void
  331. ImageHolder::setLabelColorList(QList< uint > *aLabelColorList)
  332. {
  333. if (0 == aLabelColorList) {
  334. return;
  335. /* NOTREACHED */
  336. }
  337. list_label_color_ = aLabelColorList;
  338. }
  339. void
  340. ImageHolder::setMainLabelNum(int *aNum)
  341. {
  342. if (0 == aNum) {
  343. return;
  344. /* NOTREACHED */
  345. }
  346. main_label_ = aNum;
  347. }
  348. void
  349. ImageHolder::setImage(QPixmap *anImage)
  350. {
  351. if (0 == anImage) {
  352. return;
  353. /* NOTREACHED */
  354. }
  355. image_ = anImage;
  356. }
  357. void
  358. ImageHolder::clearAll()
  359. {
  360. //list_bounding_box_->clear();
  361. bounding_box_.rect.setRect(-1, -1, 0, 0);
  362. //list_polygon_->clear();
  363. polygon_.poly.clear();
  364. clearFocusOnArea();
  365. state_ = StandBy;
  366. update();
  367. }
  368. void
  369. ImageHolder::clearLast()
  370. {
  371. switch (tool_) {
  372. case BoundingBoxTool:
  373. bounding_box_.rect.setRect(-1, -1, 0, 0);
  374. break;
  375. case PolygonTool:
  376. polygon_.poly.clear();
  377. break;
  378. case TaggingTool:
  379. break;
  380. default:
  381. break;
  382. }
  383. bounding_box_.rect.setRect(-1, -1, 0, 0);
  384. state_ = StandBy;
  385. update();
  386. }
  387. void
  388. ImageHolder::confirmSelection()
  389. {
  390. if (NewSelection != state_ || NoTool == tool_) {
  391. return;
  392. /* NOTREACHED */
  393. }
  394. switch (tool_) {
  395. case BoundingBoxTool:
  396. list_bounding_box_->append(bounding_box_);
  397. bounding_box_.rect.setRect(-1, -1, 0, 0);
  398. break;
  399. case PolygonTool:
  400. list_polygon_->append(polygon_);
  401. polygon_.poly.clear();
  402. break;
  403. default:
  404. tool_ = NoTool;
  405. break;
  406. }
  407. state_ = StandBy;
  408. update();
  409. }
  410. ImageHolder::State
  411. ImageHolder::state()
  412. {
  413. return state_;
  414. }
  415. ImageHolder::Tool
  416. ImageHolder::tool()
  417. {
  418. return tool_;
  419. }
  420. void
  421. ImageHolder::keyPressEvent(QKeyEvent *anEvent)
  422. {
  423. QLabel::keyPressEvent(anEvent);
  424. //keyboard_modifier_ = anEvent->modifiers();
  425. if (repaint_needed_) {
  426. update();
  427. repaint_needed_ = 0;
  428. }
  429. }
  430. void
  431. ImageHolder::mouseMoveEvent(QMouseEvent *anEvent)
  432. {
  433. QPoint pos = anEvent->pos() / scale_;
  434. if (anEvent->pos().x() < 0)
  435. pos.setX(0);
  436. if (width() < anEvent->pos().x())
  437. pos.setX(width() - 1);
  438. if (anEvent->pos().y() < 0)
  439. pos.setY(0);
  440. if (height() < anEvent->pos().y())
  441. pos.setY(height() - 1);
  442. if ((anEvent->buttons() & Qt::LeftButton) &&
  443. BoundingBoxTool == tool_ &&
  444. NewSelection == state_ &&
  445. Qt::NoModifier == keyboard_modifier_)
  446. {
  447. triggerBoundBox(pos, prev_cursor_pos_, &(bounding_box_.rect));
  448. }
  449. if (PolygonTool == tool_ &&
  450. NewSelection == state_) {
  451. polygon_.poly.setPoint(polygon_.poly.count() - 1, pos);
  452. repaint_needed_ = 1;
  453. }
  454. if (repaint_needed_) {
  455. update();
  456. repaint_needed_ = 0;
  457. }
  458. }
  459. void
  460. ImageHolder::mousePressEvent(QMouseEvent *anEvent)
  461. {
  462. /* remembering coordinates of the click */
  463. if ((anEvent->buttons() & Qt::LeftButton) ||
  464. (anEvent->buttons() & Qt::RightButton))
  465. {
  466. prev_cursor_pos_ = anEvent->pos() / scale_;
  467. }
  468. if (anEvent->buttons() & Qt::LeftButton) {
  469. /* clearing the selected area if it is not confirmed */
  470. if (NewSelection == state_ && BoundingBoxTool == tool_) {
  471. bounding_box_.rect.setRect(-1, -1, 0, 0);
  472. state_ = StandBy;
  473. }
  474. /* making new points for poly */
  475. if (PolygonTool == tool_ &&
  476. NewSelection == state_ &&
  477. Qt::NoModifier == keyboard_modifier_)
  478. {
  479. triggerPolygon(anEvent->pos() / scale_, &(polygon_.poly));
  480. }
  481. /* starting new selection by click */
  482. if (StandBy == state_ && NoTool != tool_) {
  483. state_ = NewSelection;
  484. emit selectionStarted();
  485. polygon_.poly.clear();
  486. if (PolygonTool == tool_) {
  487. polygon_.poly << prev_cursor_pos_;
  488. }
  489. }
  490. }
  491. if (repaint_needed_) {
  492. update();
  493. repaint_needed_ = 0;
  494. }
  495. }
  496. void
  497. ImageHolder::mouseReleaseEvent(QMouseEvent *anEvent)
  498. {
  499. Q_UNUSED(anEvent)
  500. }
  501. /*
  502. *
  503. */