Browse Source

-added a possibility to edit previously created areas

gapchich 13 years ago
parent
commit
e2b7faff58
5 changed files with 371 additions and 81 deletions
  1. 243 36
      ImageHolder.cpp
  2. 23 5
      ImageHolder.h
  3. 96 34
      ImageLabeler.cpp
  4. 8 5
      ImageLabeler.h
  5. 1 1
      main.cpp

+ 243 - 36
ImageHolder.cpp

@@ -12,6 +12,7 @@
 #include <QMouseEvent>
 #include <QPainter>
 #include <QListWidgetItem>
+#include <qmath.h>
 #include <QDebug>
 
 ImageHolder::ImageHolder(QWidget *aParent)
@@ -23,7 +24,11 @@ ImageHolder::ImageHolder(QWidget *aParent)
 	keyboard_modifier_ = Qt::NoModifier;
 
 	focused_selection_ = -1;
-	focused_selection_type_ = NoTool;
+	focused_selection_type_ = NoFigure;
+
+	hovered_point_.figure = NoFigure;
+	hovered_point_.figureID = -1;
+	hovered_point_.pointID = -1;
 
 	list_bounding_box_ = 0;
 	main_label_ = 0;
@@ -31,7 +36,10 @@ ImageHolder::ImageHolder(QWidget *aParent)
 
 	scale_ = 1;
 
+	point_radius_ = 6;
+
 	setScaledContents(true);
+	setMouseTracking(true);
 }
 
 ImageHolder::~ImageHolder()
@@ -115,7 +123,7 @@ ImageHolder::drawBoundingBoxes(
 	int width = 1;
 	/* confirmed boxes */
 	for (int i = 0; i < list_bounding_box_->size(); i++) {
-		int labelID = list_bounding_box_->at(i).label_ID_;
+		int labelID = list_bounding_box_->at(i)->label_ID_;
 
 		if (labelID < list_label_color_->count())
 			aPen->setColor(QColor(list_label_color_->at(labelID)));
@@ -128,24 +136,61 @@ ImageHolder::drawBoundingBoxes(
 		else
 			width = 1;
 
-		if (BoundingBoxTool == focused_selection_type_ &&
+		if (RectFigure == focused_selection_type_ &&
 			focused_selection_ == i) {
 			penStyle = Qt::DotLine;
 			width = 2;
 		}
 
-		aPen->setWidth(width);
-		aPen->setStyle(penStyle);
-		aPainter->setPen(*aPen);
-
 		/* scaling */
-		QRect rect = list_bounding_box_->at(i).rect.normalized();
+		QRect rect = list_bounding_box_->at(i)->rect.normalized();
 		QPoint topLeft = rect.topLeft() * scale_;
 		QPoint bottomRight = rect.bottomRight() * scale_;
 
 		rect.setTopLeft(topLeft);
 		rect.setBottomRight(bottomRight);
 
+		if (focused_selection_ == i &&
+			focused_selection_type_ == RectFigure) {
+			QPen circPen;
+			circPen.setWidth(2);
+			circPen.setStyle(Qt::SolidLine);
+			circPen.setColor(aPen->color());
+			aPainter->setPen(circPen);
+			for (int j = 0; j < 4; j++) {
+				QPoint point;
+				if (!j) {
+					point = rect.topLeft();
+				}
+				else if (1 == j)
+				{
+					point = rect.topRight();
+				}
+				else if (2 == j)
+				{
+					point = rect.bottomRight();
+				}
+				else if (3 == j)
+				{
+					point = rect.bottomLeft();
+				}
+				if (i == hovered_point_.figureID &&
+					j == hovered_point_.pointID &&
+					RectFigure == hovered_point_.figure) {
+					QBrush brush;
+					brush.setColor(aPen->color());
+					brush.setStyle(Qt::SolidPattern);
+					aPainter->setBrush(brush);
+				}
+				aPainter->drawEllipse(point, point_radius_, point_radius_);
+				aPainter->setBrush(Qt::NoBrush);
+			}
+		}
+
+		aPen->setWidth(width);
+		aPen->setStyle(penStyle);
+		aPainter->setPen(*aPen);
+
 		aPainter->drawRect(rect);
 		/* drawing label ids of these boxes */
 		QString labelIDText =
@@ -182,7 +227,7 @@ ImageHolder::drawPolygons(
 	/* confirmed polygons */
 	for (int i = 0; i < list_polygon_->size(); i++) {
 		penStyle = Qt::SolidLine;
-		int labelID = list_polygon_->at(i).label_ID_;
+		int labelID = list_polygon_->at(i)->label_ID_;
 
 		if (labelID < list_label_color_->count())
 			aPen->setColor(QColor(list_label_color_->at(labelID)));
@@ -195,27 +240,45 @@ ImageHolder::drawPolygons(
 		else
 			width = 1;
 
-		if (PolygonTool == focused_selection_type_ &&
+		if (PolyFigure == focused_selection_type_ &&
 			focused_selection_ == i) {
 			penStyle = Qt::DotLine;
 			width = 2;
 		}
 
-
-		aPen->setWidth(width);
-		aPen->setStyle(penStyle);
-		aPainter->setPen(*aPen);
-
 		QPoint point;
-		QPolygon poly = list_polygon_->at(i).poly;
+		QPolygon poly = list_polygon_->at(i)->poly;
 		for (int j = 0; j < poly.size(); j++) {
 			point.setX(poly.at(j).x());
 			point.setY(poly.at(j).y());
 			point *= scale_;
 			poly.remove(j);
 			poly.insert(j, point);
+
+			if (focused_selection_ == i &&
+				focused_selection_type_ == PolyFigure) {
+				QPen circPen;
+				circPen.setWidth(2);
+				circPen.setStyle(Qt::SolidLine);
+				circPen.setColor(aPen->color());
+				aPainter->setPen(circPen);
+				if (j == hovered_point_.pointID &&
+					i == hovered_point_.figureID &&
+					PolyFigure == hovered_point_.figure) {
+					QBrush brush;
+					brush.setColor(aPen->color());
+					brush.setStyle(Qt::SolidPattern);
+					aPainter->setBrush(brush);
+				}
+				aPainter->drawEllipse(point, point_radius_, point_radius_);
+				aPainter->setBrush(Qt::NoBrush);
+			}
 		}
 
+		aPen->setWidth(width);
+		aPen->setStyle(penStyle);
+		aPainter->setPen(*aPen);
+
 		aPainter->drawPolygon(poly);
 		/* drawing label ids of these polys */
 		QString labelIDText =
@@ -283,20 +346,20 @@ ImageHolder::focusOnArea(QListWidgetItem *anItem)
 
 		if (!ok) {
 			focused_selection_ = -1;
-			focused_selection_type_ = NoTool;
+			focused_selection_type_ = NoFigure;
 			return;
 			/* NOTREACHED */
 		}
 
 		switch (tool) {
 		case BoundingBoxTool:
-			focused_selection_type_ = BoundingBoxTool;
+			focused_selection_type_ = RectFigure;
 			break;
 		case PolygonTool:
-			focused_selection_type_ = PolygonTool;
+			focused_selection_type_ = PolyFigure;
 			break;
 		default:
-			focused_selection_type_ = NoTool;
+			focused_selection_type_ = NoFigure;
 			break;
 		}
 
@@ -345,7 +408,8 @@ void
 ImageHolder::clearFocusOnArea()
 {
 	focused_selection_ = -1;
-	focused_selection_type_ = NoTool;
+	focused_selection_type_ = NoFigure;
+	update();
 }
 
 void
@@ -368,7 +432,7 @@ ImageHolder::setTool(Tool aTool)
 }
 
 void
-ImageHolder::setBoundingBoxList(QList< BoundingBox > *aBBoxList)
+ImageHolder::setBoundingBoxList(QList< BoundingBox * > *aBBoxList)
 {
 	if (0 == aBBoxList) {
 		return;
@@ -379,7 +443,7 @@ ImageHolder::setBoundingBoxList(QList< BoundingBox > *aBBoxList)
 }
 
 void
-ImageHolder::setPolygonList(QList< Polygon > *aPolygonList)
+ImageHolder::setPolygonList(QList< Polygon * > *aPolygonList)
 {
 	if (0 == aPolygonList) {
 		return;
@@ -464,20 +528,21 @@ ImageHolder::confirmSelection()
 		/* NOTREACHED */
 	}
 
-	switch (tool_) {
-	case BoundingBoxTool:
-		list_bounding_box_->append(bounding_box_);
+	if (BoundingBoxTool == tool_) {
+		BoundingBox *bbox = new BoundingBox;
+		*bbox = bounding_box_;
+		list_bounding_box_->append(bbox);
 		bounding_box_.rect.setRect(-1, -1, 0, 0);
-		break;
-	case PolygonTool:
-		list_polygon_->append(polygon_);
+	}
+	else if (PolygonTool == tool_) {
+		Polygon *poly = new Polygon;
+		*poly = polygon_;
+		list_polygon_->append(poly);
 		polygon_.poly.clear();
-		break;
-	default:
-		tool_ = NoTool;
-		break;
 	}
 
+	list_poly_history_.clear();
+
 	state_ = StandBy;
 	update();
 }
@@ -494,6 +559,17 @@ ImageHolder::tool()
 	return tool_;
 }
 
+int
+ImageHolder::focusedSelection()
+{
+	return focused_selection_;
+}
+Figure
+ImageHolder::focusedSelectionType()
+{
+	return focused_selection_type_;
+}
+
 void
 ImageHolder::undo()
 {
@@ -530,6 +606,82 @@ ImageHolder::redo()
 	}
 }
 
+void
+ImageHolder::checkForPoints(QPoint *aPos)
+{
+	if ((!list_polygon_->count() &&
+		!list_bounding_box_->count()) ||
+		!aPos) {
+		return;
+		/* NOTREACHED */
+	}
+
+	int newRadius = 0;
+	int x = aPos->x();
+	int y = aPos->y();
+	/* center coordinates */
+	int xc = 0;
+	int yc = 0;
+	for (int i = 0; i < list_polygon_->count(); i++) {
+		QPolygon poly = list_polygon_->at(i)->poly;
+		for (int j = 0; j < poly.count(); j++) {
+			xc = poly.at(j).x();
+			yc = poly.at(j).y();
+			newRadius = qSqrt(qPow(x - xc, 2) + qPow(y - yc, 2));
+			if (newRadius <= point_radius_) {
+				hovered_point_.figure = PolyFigure;
+				hovered_point_.figureID = i;
+				hovered_point_.pointID = j;
+				repaint_needed_ = 1;
+				return;
+				/* NOTREACHED */
+			}
+		}
+	}
+
+	for (int i = 0; i < list_bounding_box_->count(); i++) {
+		QRect rect = list_bounding_box_->at(i)->rect;
+
+		for (int j = 0; j < 4; j++) {
+			if (!j) {
+				xc = rect.left();
+				yc = rect.top();
+			}
+			else if (1 == j)
+			{
+				xc = rect.right();
+				yc = rect.top();
+			}
+			else if (2 == j)
+			{
+				xc = rect.right();
+				yc = rect.bottom();
+			}
+			else if (3 == j)
+			{
+				xc = rect.left();
+				yc = rect.bottom();
+			}
+
+
+			newRadius = qSqrt(qPow(x - xc, 2) + qPow(y - yc, 2));
+			if (newRadius <= point_radius_) {
+				hovered_point_.figure = RectFigure;
+				hovered_point_.figureID = i;
+				hovered_point_.pointID = j;
+				repaint_needed_ = 1;
+				return;
+				/* NOTREACHED */
+			}
+		}
+	}
+
+	hovered_point_.figure = NoFigure;
+	hovered_point_.figureID = -1;
+	hovered_point_.pointID = -1;
+	repaint_needed_ = 1;
+}
+
 void
 ImageHolder::keyPressEvent(QKeyEvent *anEvent)
 {
@@ -570,8 +722,46 @@ ImageHolder::mouseMoveEvent(QMouseEvent *anEvent)
 	}
 
 	if (PolygonTool == tool_ &&
-		NewSelection == state_) {
+		NewSelection == state_ &&
+		(anEvent->buttons() & Qt::LeftButton))
+	{
 		polygon_.poly.setPoint(polygon_.poly.count() - 1, pos);
+		//triggerPolygon(pos, &(polygon_.poly));
+		repaint_needed_ = 1;
+	}
+
+	if (-1 != focused_selection_ &&
+		!(anEvent->buttons() & Qt::LeftButton)) {
+		checkForPoints(&pos);
+	}
+
+	/* editing polygons */
+	if (-1 != hovered_point_.figureID &&
+		!list_polygon_->isEmpty() &&
+		PolyFigure == hovered_point_.figure &&
+		(anEvent->buttons() & Qt::LeftButton))
+	{
+		Polygon *poly = list_polygon_->at(hovered_point_.figureID);
+		poly->poly.setPoint(hovered_point_.pointID, pos);
+		repaint_needed_ = 1;
+	}
+
+	/* editing bounding boxes */
+	if (-1 != hovered_point_.figureID &&
+		!list_bounding_box_->isEmpty() &&
+		RectFigure == hovered_point_.figure &&
+		(anEvent->buttons() & Qt::LeftButton))
+	{
+		BoundingBox *rect = list_bounding_box_->at(hovered_point_.figureID);
+		if (0 == hovered_point_.pointID)
+			rect->rect.setTopLeft(pos);
+		else if (1 == hovered_point_.pointID)
+			rect->rect.setTopRight(pos);
+		else if (2 == hovered_point_.pointID)
+				rect->rect.setBottomRight(pos);
+		else if (3 == hovered_point_.pointID)
+				rect->rect.setBottomLeft(pos);
+
 		repaint_needed_ = 1;
 	}
 
@@ -591,6 +781,8 @@ ImageHolder::mousePressEvent(QMouseEvent *anEvent)
 		prev_cursor_pos_ = anEvent->pos() / scale_;
 	}
 
+	QPoint pos = anEvent->pos() / scale_;
+
 	if (anEvent->buttons() & Qt::LeftButton) {
 		/* clearing the selected area if it is not confirmed */
 		if (NewSelection == state_ && BoundingBoxTool == tool_) {
@@ -603,11 +795,12 @@ ImageHolder::mousePressEvent(QMouseEvent *anEvent)
 			NewSelection == state_ &&
 			Qt::NoModifier == keyboard_modifier_)
 		{
-			triggerPolygon(anEvent->pos() / scale_, &(polygon_.poly));
+			triggerPolygon(pos, &(polygon_.poly));
 		}
 
 		/* starting new selection by click */
-		if (StandBy == state_ && NoTool != tool_) {
+		if (StandBy == state_ && NoTool != tool_ &&
+			-1 == focused_selection_) {
 			state_ = NewSelection;
 			emit selectionStarted();
 
@@ -628,6 +821,20 @@ void
 ImageHolder::mouseReleaseEvent(QMouseEvent *anEvent)
 {
 	Q_UNUSED(anEvent)
+
+	if (-1 != hovered_point_.figureID)
+		emit areaEdited();
+
+	if (RectFigure == hovered_point_.figure &&
+		-1 != hovered_point_.figureID &&
+		!list_bounding_box_->
+			at(hovered_point_.figureID)->
+			rect.isValid()
+		)
+	{
+		BoundingBox *rect = list_bounding_box_->at(hovered_point_.figureID);
+		rect->rect = rect->rect.normalized();
+	}
 }
 
 /*

+ 23 - 5
ImageHolder.h

@@ -10,6 +10,12 @@
 
 #include <QLabel>
 
+enum Figure {
+	NoFigure,
+	RectFigure,
+	PolyFigure
+};
+
 struct BoundingBox {
 	QRect rect;
 	int label_ID_;
@@ -20,6 +26,12 @@ struct Polygon {
 	int label_ID_;
 };
 
+struct HoveredPoint {
+	Figure figure;
+	int figureID;
+	int pointID;
+};
+
 enum ZoomDirection {
 	NoZoom,
 	ZoomIn,
@@ -56,6 +68,7 @@ protected:
 		QPainter *aPainter,
 		QPen *aPen
 		);
+	void checkForPoints(QPoint *aPos);
 
 public:
 	enum Tool {
@@ -74,12 +87,14 @@ public:
 	virtual ~ImageHolder();
 
 	void setTool(Tool aTool);
-	void setBoundingBoxList(QList< BoundingBox > *aBBoxList);
-	void setPolygonList(QList< Polygon > *aPolyList);
+	void setBoundingBoxList(QList< BoundingBox * > *aBBoxList);
+	void setPolygonList(QList< Polygon * > *aPolyList);
 	void setLabelColorList(QList< uint > *aLabelColorList);
 	void setMainLabelNum(int *aNum);
 	void setImage(QPixmap *anImage);
 	void scaleImage(ZoomDirection aDirection, double scaleFactor);
+	int focusedSelection();
+	Figure focusedSelectionType();
 	State state();
 	Tool tool();
 
@@ -96,12 +111,13 @@ public slots:
 signals:
 	void selectionStarted();
 	void imageScaled();
+	void areaEdited();
 
 private:
 	bool repaint_needed_;
 
-	QList< BoundingBox > *list_bounding_box_;
-	QList< Polygon > *list_polygon_;
+	QList< BoundingBox * > *list_bounding_box_;
+	QList< Polygon * > *list_polygon_;
 	QList< uint > *list_label_color_;
 	QList< QPoint > list_poly_history_;
 	QPixmap *image_;
@@ -109,6 +125,7 @@ private:
 	BoundingBox bounding_box_;
 	Polygon polygon_;
 	int keyboard_modifier_;
+	HoveredPoint hovered_point_;
 
 	QPoint prev_cursor_pos_;
 
@@ -116,9 +133,10 @@ private:
 	State state_;
 
 	int focused_selection_;
-	Tool focused_selection_type_;
+	Figure focused_selection_type_;
 
 	double scale_;
+	int point_radius_;
 };
 
 #endif /* IMAGEHOLDER_H_ */

+ 96 - 34
ImageLabeler.cpp

@@ -513,7 +513,7 @@ ImageLabeler::ImageLabeler(QWidget *aParent) :
 		list_areas_,
 		SIGNAL(itemChanged(QListWidgetItem *)),
 		this,
-		SLOT(onAreaChange(QListWidgetItem *))
+		SLOT(onAreaItemChange(QListWidgetItem *))
 		);
 	connect(
 		list_label_,
@@ -569,6 +569,12 @@ ImageLabeler::ImageLabeler(QWidget *aParent) :
 		this,
 		SLOT(onImageScaled())
 		);
+	connect(
+		image_holder_,
+		SIGNAL(areaEdited()),
+		this,
+		SLOT(onAreaEdit())
+		);
 	connect(
 		&options_form_,
 		SIGNAL(optionsSet()),
@@ -818,13 +824,17 @@ ImageLabeler::setLabelID(
 void
 ImageLabeler::addBBoxArea(
 	int anID,
-	BoundingBox aBBox
+	BoundingBox aBBox,
+	int itemID
 )
 {
 	QListWidgetItem *newItem = new QListWidgetItem;
 
+	if (-1 == itemID)
+		itemID = list_areas_->count();
+
 	QString label;
-	label.append(QString("%1: ").arg(list_areas_->count()));
+	label.append(QString("%1: ").arg(itemID));
 
 	label.append(QString("BBox #%1; ").arg(anID));
 	label.append(QString("LabelID: %1; ").arg(aBBox.label_ID_));
@@ -838,20 +848,24 @@ ImageLabeler::addBBoxArea(
 
 	newItem->setText(label);
 	//newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
-	list_areas_->addItem(newItem);
+	list_areas_->insertItem(itemID, newItem);
 	list_areas_->setItemSelected(newItem, true);
 }
 
 void
 ImageLabeler::addPolyArea(
 	int aPolyID,
-	Polygon aPoly
+	Polygon aPoly,
+	int itemID
 )
 {
 	QListWidgetItem *newItem = new QListWidgetItem;
 
+	if (-1 == itemID)
+		itemID = list_areas_->count();
+
 	QString label;
-	label.append(QString("%1: ").arg(list_areas_->count()));
+	label.append(QString("%1: ").arg(itemID));
 
 	label.append(QString("Poly #%1; ").arg(aPolyID));
 	label.append(QString("LabelID: %1; ").arg(aPoly.label_ID_));
@@ -866,7 +880,7 @@ ImageLabeler::addPolyArea(
 
 	newItem->setText(label);
 	//newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
-	list_areas_->addItem(newItem);
+	list_areas_->insertItem(itemID, newItem);
 	list_areas_->setItemSelected(newItem, true);
 }
 
@@ -889,15 +903,16 @@ ImageLabeler::editArea()
 }
 
 void
-ImageLabeler::onAreaChange(QListWidgetItem *anItem)
+ImageLabeler::onAreaItemChange(QListWidgetItem *anItem)
 {
 	list_areas_->blockSignals(true);
 	QString areaString = anItem->text();
 	int oldID = -1;
 	if (-1 != areaString.indexOf("Poly")) {
-		Polygon poly = polyFromString(&areaString, &oldID);
+		Polygon *poly = new Polygon;
+		*poly = polyFromString(&areaString, &oldID);
 
-		if (-1 < poly.label_ID_ && !poly.poly.isEmpty() &&
+		if (-1 < poly->label_ID_ && !poly->poly.isEmpty() &&
 			-1 < oldID) {
 			list_polygon_.takeAt(oldID);
 			list_polygon_.insert(oldID, poly);
@@ -906,9 +921,10 @@ ImageLabeler::onAreaChange(QListWidgetItem *anItem)
 			anItem->setText(old_area_string_);
 	}
 	else if (-1 != areaString.indexOf("BBox")) {
-		BoundingBox bbox = BBoxFromString(&areaString, &oldID);
+		BoundingBox *bbox = new BoundingBox;
+		*bbox = BBoxFromString(&areaString, &oldID);
 
-		if (-1 < bbox.label_ID_ && -1 < oldID) {
+		if (-1 < bbox->label_ID_ && -1 < oldID) {
 			list_bounding_box_.takeAt(oldID);
 			list_bounding_box_.insert(oldID, bbox);
 		}
@@ -922,6 +938,43 @@ ImageLabeler::onAreaChange(QListWidgetItem *anItem)
 
 	anItem->setFlags(anItem->flags() ^ Qt::ItemIsEditable);
 	list_areas_->blockSignals(false);
+	image_holder_->update();
+}
+
+
+void
+ImageLabeler::onAreaEdit()
+{
+	if (!list_areas_->count() ||
+		-1 == image_holder_->focusedSelection()) {
+		//showWarning(tr("You haven't added any label"));
+		return;
+		/* NOTREACHED */
+	}
+
+	int figureID = image_holder_->focusedSelection();
+	Figure figure = image_holder_->focusedSelectionType();
+
+	for (int i = 0; i < list_areas_->count(); i++) {
+		QListWidgetItem *item = list_areas_->item(i);
+		QString text = item->text();
+		if (RectFigure == figure && -1 != text.indexOf("BBox")) {
+			bool ok = 0;
+			int num = getNumFromString(&text, "BBox #", ";", &ok);
+			if (ok && num == figureID) {
+				list_areas_->takeItem(i);
+				addBBoxArea(num, *list_bounding_box_.at(num), i);
+			}
+		}
+		else if (PolyFigure == figure && -1 != text.indexOf("Poly")) {
+			bool ok = 0;
+			int num = getNumFromString(&text, "Poly #", ";", &ok);
+			if (ok && num == figureID) {
+				list_areas_->takeItem(i);
+				addPolyArea(num, *list_polygon_.at(num), i);
+			}
+		}
+	}
 }
 
 void
@@ -1744,9 +1797,9 @@ ImageLabeler::objectsToXml(QDomDocument *aDoc, QDomElement *aRoot)
 	for (int i = 0; i < list_bounding_box_.size(); i++) {
 		QDomElement rectData = aDoc->createElement(tr("bbox"));
 
-		rectData.setAttribute("id", list_bounding_box_.at(i).label_ID_);
+		rectData.setAttribute("id", list_bounding_box_.at(i)->label_ID_);
 
-		QRect rect = list_bounding_box_.at(i).rect.normalized();
+		QRect rect = list_bounding_box_.at(i)->rect.normalized();
 
 		QString rectDataString =
 			QString("%1;%2;%3;%4;").
@@ -1764,9 +1817,9 @@ ImageLabeler::objectsToXml(QDomDocument *aDoc, QDomElement *aRoot)
 	for (int i = 0; i < list_polygon_.size(); i++) {
 		QDomElement polyData = aDoc->createElement(tr("poly"));
 
-		polyData.setAttribute("id", list_polygon_.at(i).label_ID_);
+		polyData.setAttribute("id", list_polygon_.at(i)->label_ID_);
 
-		QPolygon poly = list_polygon_.at(i).poly;
+		QPolygon poly = list_polygon_.at(i)->poly;
 
 		QString polyDataString;
 		for (int j = 0; j < poly.count(); j++)
@@ -1855,15 +1908,16 @@ ImageLabeler::setBBoxFromData(
 	int *ID
 )
 {
-	BoundingBox bbox = BBoxFromData(aBBoxData);
-	if (!bbox.rect.isValid() || !ID) {
+	BoundingBox *bbox = new BoundingBox;
+	*bbox = BBoxFromData(aBBoxData);
+	if (!bbox->rect.isValid() || !ID) {
 		return;
 		/* NOTREACHED */
 	}
 
-	bbox.label_ID_ = *ID;
+	bbox->label_ID_ = *ID;
 	list_bounding_box_.append(bbox);
-	addBBoxArea(list_bounding_box_.count() - 1, bbox);
+	addBBoxArea(list_bounding_box_.count() - 1, *bbox);
 }
 
 BoundingBox
@@ -1987,16 +2041,17 @@ ImageLabeler::setPolyFromData(
 	int *ID
 )
 {
-	Polygon poly = polyFromData(aPolyData);
+	Polygon *poly = new Polygon;
+	*poly = polyFromData(aPolyData);
 
-	if (poly.poly.isEmpty() || !ID) {
+	if (poly->poly.isEmpty() || !ID) {
 		return;
 		/* NOTREACHED */
 	}
 
-	poly.label_ID_ = *ID;
+	poly->label_ID_ = *ID;
 	list_polygon_.append(poly);
-	addPolyArea(list_polygon_.count() - 1, poly);
+	addPolyArea(list_polygon_.count() - 1, *poly);
 }
 
 Polygon
@@ -2202,17 +2257,17 @@ ImageLabeler::confirmSelection()
 	ImageHolder::Tool tool = image_holder_->tool();
 	switch (tool) {
 	case ImageHolder::BoundingBoxTool:
-		list_bounding_box_.last().label_ID_ = label_ID_;
+		list_bounding_box_.last()->label_ID_ = label_ID_;
 		addBBoxArea(
 			list_bounding_box_.count() - 1,
-			list_bounding_box_.last()
+			*(list_bounding_box_.last())
 			);
 		break;
 	case ImageHolder::PolygonTool:
-		list_polygon_.last().label_ID_ = label_ID_;
+		list_polygon_.last()->label_ID_ = label_ID_;
 		addPolyArea(
 			list_polygon_.count() - 1,
-			list_polygon_.last()
+			*(list_polygon_.last())
 			);
 		break;
 	default:
@@ -2369,16 +2424,16 @@ ImageLabeler::setPureData()
 			pure_data_[i][j] = 0;
 			/* bboxes first */
 			for (int cnt = 0; cnt < bboxCnt; cnt++) {
-				BoundingBox bbox = list_bounding_box_.at(cnt);
-				if (bbox.rect.contains(j, i)) {
-					pure_data_[i][j] = bbox.label_ID_;
+				BoundingBox *bbox = list_bounding_box_.at(cnt);
+				if (bbox->rect.contains(j, i)) {
+					pure_data_[i][j] = bbox->label_ID_;
 				}
 			}
 			/* polys next */
 			for (int cnt = 0; cnt < polyCnt; cnt++) {
-				Polygon poly = list_polygon_.at(cnt);
-				if (poly.poly.containsPoint(QPoint(j, i), Qt::OddEvenFill)) {
-					pure_data_[i][j] = poly.label_ID_;
+				Polygon *poly = list_polygon_.at(cnt);
+				if (poly->poly.containsPoint(QPoint(j, i), Qt::OddEvenFill)) {
+					pure_data_[i][j] = poly->label_ID_;
 				}
 			}
 		}
@@ -2514,6 +2569,13 @@ ImageLabeler::keyPressEvent(QKeyEvent *anEvent)
 		confirmSelection();
 	}
 
+	if ((Qt::Key_Enter == anEvent->key() ||
+		Qt::Key_Return == anEvent->key()) &&
+	//	Qt::NoModifier == anEvent->modifiers() &&
+		-1 != image_holder_->focusedSelection()) {
+		image_holder_->clearFocusOnArea();
+	}
+
 	if (Qt::Key_Escape == anEvent->key()) {
 		image_holder_->clearLast();
 		image_holder_->clearFocusOnArea();

+ 8 - 5
ImageLabeler.h

@@ -89,11 +89,13 @@ public slots:
 	void setLabelID(QListWidgetItem *anItem);
 	void addBBoxArea(
 		int anID,
-		BoundingBox aBBox
+		BoundingBox aBBox,
+		int itemID = -1
 		);
 	void addPolyArea(
 		int aPolyID,
-		Polygon aPoly
+		Polygon aPoly,
+		int itemID = -1
 		);
 	void deleteArea();
 	void editArea();
@@ -120,7 +122,8 @@ public slots:
 	void onImageScaled();
 	void onOptionsSet();
 	void onSelectionStarted();
-	void onAreaChange(QListWidgetItem *);
+	void onAreaItemChange(QListWidgetItem *);
+	void onAreaEdit();
 	void setPureData();
 	void setLabelColor();
 	void setLabelColor(int anID, QColor aColor);
@@ -222,8 +225,8 @@ private:
 	QStringList *list_images_;
 	QStringList::iterator current_image_;
 	QString segmented_image_;
-	QList< BoundingBox > list_bounding_box_;
-	QList< Polygon > list_polygon_;
+	QList< BoundingBox * > list_bounding_box_;
+	QList< Polygon * > list_polygon_;
 	QList< uint > list_label_colors_;
 
 	QString old_area_string_;

+ 1 - 1
main.cpp

@@ -5,7 +5,7 @@
 
 int main(int argc, char *argv[])
 {
-    QApplication app(argc, argv);
+	QApplication app(argc, argv);
     app.setApplicationName(QObject::tr("Image Labeler"));
 
     QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());