EditDepthArea.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include <QWidget>
29 #include <QPainter>
30 #include <QMouseEvent>
31 #include <QMenu>
32 #include <QAction>
33 #include <QActionGroup>
34 #include <QInputDialog>
35 
38 
39 namespace rtabmap {
40 
42  : QWidget(parent)
43 {
44  setAttribute(Qt::WA_StaticContents);
45  modified_ = false;
46  scribbling_ = false;
47  myPenWidth_ = 10;
48  clusterError_ = 0.02;
49 
50  menu_ = new QMenu(tr(""), this);
51  showRGB_ = menu_->addAction(tr("Show RGB Image"));
52  showRGB_->setCheckable(true);
53  showRGB_->setChecked(true);
54  removeCluster_ = menu_->addAction(tr("Remove Cluster"));
55  clusterErrorCluster_ = menu_->addAction(tr("Set Cluster Error"));
56  setPenWidth_ = menu_->addAction(tr("Set Pen Width..."));
57  QMenu * colorMap = menu_->addMenu("Depth color map");
58  colorMapWhiteToBlack_ = colorMap->addAction(tr("White to black"));
59  colorMapWhiteToBlack_->setCheckable(true);
60  colorMapWhiteToBlack_->setChecked(false);
61  colorMapBlackToWhite_ = colorMap->addAction(tr("Black to white"));
62  colorMapBlackToWhite_->setCheckable(true);
63  colorMapBlackToWhite_->setChecked(false);
64  colorMapRedToBlue_ = colorMap->addAction(tr("Red to blue"));
65  colorMapRedToBlue_->setCheckable(true);
66  colorMapRedToBlue_->setChecked(true);
67  colorMapBlueToRed_ = colorMap->addAction(tr("Blue to red"));
68  colorMapBlueToRed_->setCheckable(true);
69  colorMapBlueToRed_->setChecked(false);
70  QActionGroup * group = new QActionGroup(this);
71  group->addAction(colorMapWhiteToBlack_);
72  group->addAction(colorMapBlackToWhite_);
73  group->addAction(colorMapRedToBlue_);
74  group->addAction(colorMapBlueToRed_);
75  resetChanges_ = menu_->addAction(tr("Reset Changes"));
76 }
77 
78 void EditDepthArea::setImage(const cv::Mat &depth, const cv::Mat & rgb)
79 {
80  UASSERT(!depth.empty());
81  UASSERT(depth.type() == CV_32FC1 ||
82  depth.type() == CV_16UC1);
83  originalImage_ = depth;
84 
86  if(colorMapBlackToWhite_->isChecked())
87  {
88  colorMap = uCvQtDepthBlackToWhite;
89  }
90  else if(colorMapRedToBlue_->isChecked())
91  {
92  colorMap = uCvQtDepthRedToBlue;
93  }
94  else if(colorMapBlueToRed_->isChecked())
95  {
96  colorMap = uCvQtDepthBlueToRed;
97  }
98 
99  image_ = uCvMat2QImage(depth, true, colorMap).convertToFormat(QImage::Format_RGB32);
100 
101  imageRGB_ = QImage();
102  if(!rgb.empty())
103  {
104  imageRGB_ = uCvMat2QImage(rgb);
105  if( depth.cols != rgb.cols ||
106  depth.rows != rgb.rows)
107  {
108  // scale rgb to depth
109  imageRGB_ = imageRGB_.scaled(image_.size());
110  }
111  }
112  showRGB_->setEnabled(!imageRGB_.isNull());
113  modified_ = false;
114  update();
115 }
116 
118 {
119  cv::Mat modifiedImage = originalImage_.clone();
120  if(modified_)
121  {
122  UASSERT(image_.width() == modifiedImage.cols &&
123  image_.height() == modifiedImage.rows);
124  UASSERT(modifiedImage.type() == CV_32FC1 ||
125  modifiedImage.type() == CV_16UC1);
126  for(int j=0; j<image_.height(); ++j)
127  {
128  for(int i=0; i<image_.width(); ++i)
129  {
130  if(qRed(image_.pixel(i, j)) == 0 &&
131  qGreen(image_.pixel(i, j)) == 0 &&
132  qBlue(image_.pixel(i, j)) == 0)
133  {
134  if(modifiedImage.type() == CV_32FC1)
135  {
136  modifiedImage.at<float>(j,i) = 0.0f;
137  }
138  else // CV_16UC1
139  {
140  modifiedImage.at<unsigned short>(j,i) = 0;
141  }
142  }
143  }
144  }
145  }
146  return modifiedImage;
147 }
148 
149 void EditDepthArea::setPenWidth(int newWidth)
150 {
151  myPenWidth_ = newWidth;
152 }
153 
155 {
156  image_ = uCvMat2QImage(originalImage_).convertToFormat(QImage::Format_RGB32);
157  modified_ = false;
158  update();
159 }
160 
162 {
164  {
165  colorMapBlackToWhite_->setChecked(true);
166  }
167  else if(type == uCvQtDepthRedToBlue)
168  {
169  colorMapRedToBlue_->setChecked(true);
170  }
171  else if(type == uCvQtDepthBlueToRed)
172  {
173  colorMapBlueToRed_->setChecked(true);
174  }
175  else
176  {
177  colorMapWhiteToBlack_->setChecked(true);
178  }
179 
180  if(!originalImage_.empty())
181  {
182  image_ = uCvMat2QImage(originalImage_, true, type).convertToFormat(QImage::Format_RGB32);
183  update();
184  }
185 }
186 
187 void EditDepthArea::mousePressEvent(QMouseEvent *event)
188 {
189  if (event->button() == Qt::LeftButton) {
190  float scale, offsetX, offsetY;
191  computeScaleOffsets(rect(), scale, offsetX, offsetY);
192  lastPoint_.setX((event->pos().x()-offsetX)/scale);
193  lastPoint_.setY((event->pos().y()-offsetY)/scale);
194 
195  scribbling_ = true;
196  }
197 }
198 
199 void EditDepthArea::mouseMoveEvent(QMouseEvent *event)
200 {
201  if ((event->buttons() & Qt::LeftButton) && scribbling_)
202  {
203  float scale, offsetX, offsetY;
204  computeScaleOffsets(rect(), scale, offsetX, offsetY);
205  QPoint to;
206  to.setX((event->pos().x()-offsetX)/scale);
207  to.setY((event->pos().y()-offsetY)/scale);
208  drawLineTo(to);
209  }
210 }
211 
212 void EditDepthArea::mouseReleaseEvent(QMouseEvent *event)
213 {
214  if (event->button() == Qt::LeftButton && scribbling_) {
215  float scale, offsetX, offsetY;
216  computeScaleOffsets(rect(), scale, offsetX, offsetY);
217  QPoint to;
218  to.setX((event->pos().x()-offsetX)/scale);
219  to.setY((event->pos().y()-offsetY)/scale);
220  drawLineTo(to);
221  scribbling_ = false;
222  }
223 }
224 
225 void EditDepthArea::computeScaleOffsets(const QRect & targetRect, float & scale, float & offsetX, float & offsetY) const
226 {
227  scale = 1.0f;
228  offsetX = 0.0f;
229  offsetY = 0.0f;
230 
231  if(!image_.isNull())
232  {
233  float w = image_.width();
234  float h = image_.height();
235  float widthRatio = float(targetRect.width()) / w;
236  float heightRatio = float(targetRect.height()) / h;
237 
238  //printf("w=%f, h=%f, wR=%f, hR=%f, sW=%d, sH=%d\n", w, h, widthRatio, heightRatio, this->rect().width(), this->rect().height());
239  if(widthRatio < heightRatio)
240  {
241  scale = widthRatio;
242  }
243  else
244  {
245  scale = heightRatio;
246  }
247 
248  //printf("ratio=%f\n",ratio);
249 
250  w *= scale;
251  h *= scale;
252 
253  if(w < targetRect.width())
254  {
255  offsetX = (targetRect.width() - w)/2.0f;
256  }
257  if(h < targetRect.height())
258  {
259  offsetY = (targetRect.height() - h)/2.0f;
260  }
261  //printf("offsetX=%f, offsetY=%f\n",offsetX, offsetY);
262  }
263 }
264 
265 void EditDepthArea::paintEvent(QPaintEvent *event)
266 {
267  //Scale
268  float ratio, offsetX, offsetY;
269  this->computeScaleOffsets(event->rect(), ratio, offsetX, offsetY);
270  QPainter painter(this);
271 
272  painter.translate(offsetX, offsetY);
273  painter.scale(ratio, ratio);
274 
275  if(showRGB_->isChecked() && !imageRGB_.isNull())
276  {
277  painter.setOpacity(0.5);
278  painter.drawImage(QPoint(0,0), imageRGB_);
279  }
280 
281  painter.drawImage(QPoint(0,0), image_);
282 }
283 
284 void EditDepthArea::resizeEvent(QResizeEvent *event)
285 {
286  QWidget::resizeEvent(event);
287 }
288 
289 void floodfill(QRgb * bits, const cv::Mat & depthImage, int x, int y, float lastDepthValue, float error, int &iterations)
290 {
291  ++iterations;
292  if(x>=0 && x<depthImage.cols &&
293  y>=0 && y<depthImage.rows)
294  {
295  float currentValue;
296  if(depthImage.type() == CV_32FC1)
297  {
298  currentValue = depthImage.at<float>(y, x);
299  }
300  else
301  {
302  currentValue = float(depthImage.at<unsigned short>(y, x))/1000.0f;
303  }
304  if(currentValue == 0.0f)
305  {
306  return;
307  }
308 
309  QRgb & rgb = bits[x+y*depthImage.cols];
310  if(qRed(rgb) == 0 && qGreen(rgb) == 0 && qBlue(rgb) == 0)
311  {
312  return;
313  }
314  if(lastDepthValue>=0.0f && fabs(lastDepthValue - currentValue) > error*lastDepthValue)
315  {
316  return;
317  }
318  rgb = 0;
319 
320  if(y+1<depthImage.rows)
321  {
322  QRgb & rgb = bits[x+(y+1)*depthImage.cols];
323  if(qRed(rgb) != 0 || qGreen(rgb) != 0 || qBlue(rgb) != 0)
324  {
325  floodfill(bits, depthImage, x, y+1, currentValue, error, iterations);
326  }
327  }
328  if(y-1>=0)
329  {
330  QRgb & rgb = bits[x+(y-1)*depthImage.cols];
331  if(qRed(rgb) != 0 || qGreen(rgb) != 0 || qBlue(rgb) != 0)
332  {
333  floodfill(bits, depthImage, x, y-1, currentValue, error, iterations);
334  }
335  }
336  if(x+1<depthImage.cols)
337  {
338  QRgb & rgb = bits[x+1+y*depthImage.cols];
339  if(qRed(rgb) != 0 || qGreen(rgb) != 0 || qBlue(rgb) != 0)
340  {
341  floodfill(bits, depthImage, x+1, y, currentValue, error, iterations);
342  }
343  }
344  if(x-1>=0)
345  {
346  QRgb & rgb = bits[x-1+y*depthImage.cols];
347  if(qRed(rgb) != 0 || qGreen(rgb) != 0 || qBlue(rgb) != 0)
348  {
349  floodfill(bits, depthImage, x-1, y, currentValue, error, iterations);
350  }
351  }
352  }
353 }
354 
355 void EditDepthArea::contextMenuEvent(QContextMenuEvent * e)
356 {
357  QAction * action = menu_->exec(e->globalPos());
358  if(action == showRGB_)
359  {
360  this->update();
361  }
362  else if(action == removeCluster_)
363  {
364  float scale, offsetX, offsetY;
365  computeScaleOffsets(rect(), scale, offsetX, offsetY);
366  QPoint pixel;
367  pixel.setX((e->pos().x()-offsetX)/scale);
368  pixel.setY((e->pos().y()-offsetY)/scale);
369  if(pixel.x()>=0 && pixel.x() < originalImage_.cols &&
370  pixel.y()>=0 && pixel.y() < originalImage_.rows)
371  {
372  int iterations=0;
373  floodfill((QRgb*)image_.bits(), originalImage_, pixel.x(), pixel.y(), -1.0f, clusterError_, iterations);
374  }
375  modified_=true;
376  this->update();
377  }
378  else if(action == clusterErrorCluster_)
379  {
380  bool ok;
381  double error = QInputDialog::getDouble(this, tr("Set Cluster Error"), tr("Error:"), clusterError(), 0.001, 1, 3, &ok);
382  if(ok)
383  {
385  }
386  modified_=true;
387  }
388  else if(action == setPenWidth_)
389  {
390  bool ok;
391  int width = QInputDialog::getInt(this, tr("Set Pen Width"), tr("Width (pixels):"), penWidth(), 1, 999, 1, &ok);
392  if(ok)
393  {
394  myPenWidth_ = width;
395  }
396  }
397  else if(action == colorMapBlackToWhite_ ||
401  {
403  if(colorMapBlackToWhite_->isChecked())
404  {
405  colorMap = uCvQtDepthBlackToWhite;
406  }
407  else if(colorMapRedToBlue_->isChecked())
408  {
409  colorMap = uCvQtDepthRedToBlue;
410  }
411  else if(colorMapBlueToRed_->isChecked())
412  {
413  colorMap = uCvQtDepthBlueToRed;
414  }
415  this->setColorMap(colorMap);
416  }
417  else if(action == resetChanges_)
418  {
419  this->resetChanges();
420  }
421 }
422 
423 void EditDepthArea::drawLineTo(const QPoint &endPoint)
424 {
425  QPainter painter(&image_);
426  painter.setPen(QPen(Qt::black, myPenWidth_, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
427  painter.drawLine(lastPoint_, endPoint);
428  modified_ = true;
429 
430  update();
431  lastPoint_ = endPoint;
432 }
433 
434 }
rtabmap::EditDepthArea::menu_
QMenu * menu_
Definition: EditDepthArea.h:86
w
RowVector3d w
update
def update(text)
rtabmap::EditDepthArea::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *event)
Definition: EditDepthArea.cpp:199
rtabmap::EditDepthArea::getModifiedImage
cv::Mat getModifiedImage() const
Definition: EditDepthArea.cpp:117
rtabmap::EditDepthArea::clusterError
double clusterError() const
Definition: EditDepthArea.h:59
bits
Map< const Array< unsigned char, sizeof(T), 1 > > bits(const T &x)
rtabmap::EditDepthArea::penWidth
int penWidth() const
Definition: EditDepthArea.h:57
uCvQtDepthRedToBlue
@ uCvQtDepthRedToBlue
Definition: UCv2Qt.h:33
rtabmap::EditDepthArea::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *event)
Definition: EditDepthArea.cpp:212
h
const double h
rtabmap::EditDepthArea::setColorMap
void setColorMap(uCvQtDepthColorMap type)
Definition: EditDepthArea.cpp:161
rtabmap::EditDepthArea::colorMapBlackToWhite_
QAction * colorMapBlackToWhite_
Definition: EditDepthArea.h:93
rtabmap::EditDepthArea::removeCluster_
QAction * removeCluster_
Definition: EditDepthArea.h:88
uCvQtDepthColorMap
uCvQtDepthColorMap
Definition: UCv2Qt.h:30
type
y
Matrix3f y
rtabmap::EditDepthArea::lastPoint_
QPoint lastPoint_
Definition: EditDepthArea.h:84
rtabmap::EditDepthArea::showRGB_
QAction * showRGB_
Definition: EditDepthArea.h:87
uCvQtDepthBlueToRed
@ uCvQtDepthBlueToRed
Definition: UCv2Qt.h:34
fabs
Real fabs(const Real &a)
rtabmap::EditDepthArea::resetChanges
void resetChanges()
Definition: EditDepthArea.cpp:154
rtabmap::EditDepthArea::mousePressEvent
virtual void mousePressEvent(QMouseEvent *event)
Definition: EditDepthArea.cpp:187
rtabmap::EditDepthArea::drawLineTo
void drawLineTo(const QPoint &endPoint)
Definition: EditDepthArea.cpp:423
scale
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics scale
j
std::ptrdiff_t j
rtabmap::EditDepthArea::EditDepthArea
EditDepthArea(QWidget *parent=0)
Definition: EditDepthArea.cpp:41
rtabmap::EditDepthArea::paintEvent
virtual void paintEvent(QPaintEvent *event)
Definition: EditDepthArea.cpp:265
rtabmap::EditDepthArea::originalImage_
cv::Mat originalImage_
Definition: EditDepthArea.h:83
UASSERT
#define UASSERT(condition)
x
x
error
void error(const char *str)
rtabmap::EditDepthArea::colorMapRedToBlue_
QAction * colorMapRedToBlue_
Definition: EditDepthArea.h:94
action
action
rtabmap::EditDepthArea::setImage
void setImage(const cv::Mat &depth, const cv::Mat &rgb=cv::Mat())
Definition: EditDepthArea.cpp:78
f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
rtabmap::floodfill
void floodfill(QRgb *bits, const cv::Mat &depthImage, int x, int y, float lastDepthValue, float error, int &iterations)
Definition: EditDepthArea.cpp:289
uCvQtDepthWhiteToBlack
@ uCvQtDepthWhiteToBlack
Definition: UCv2Qt.h:31
rtabmap::EditDepthArea::resetChanges_
QAction * resetChanges_
Definition: EditDepthArea.h:90
rtabmap::EditDepthArea::imageRGB_
QImage imageRGB_
Definition: EditDepthArea.h:81
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
ULogger.h
ULogger class and convenient macros.
rtabmap::EditDepthArea::setPenWidth
void setPenWidth(int newWidth)
Definition: EditDepthArea.cpp:149
rtabmap::EditDepthArea::resizeEvent
virtual void resizeEvent(QResizeEvent *event)
Definition: EditDepthArea.cpp:284
rtabmap::EditDepthArea::colorMapBlueToRed_
QAction * colorMapBlueToRed_
Definition: EditDepthArea.h:95
rtabmap::EditDepthArea::clusterError_
double clusterError_
Definition: EditDepthArea.h:80
rtabmap::EditDepthArea::setPenWidth_
QAction * setPenWidth_
Definition: EditDepthArea.h:91
ratio
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size ratio
rtabmap::EditDepthArea::clusterErrorCluster_
QAction * clusterErrorCluster_
Definition: EditDepthArea.h:89
rtabmap::EditDepthArea::computeScaleOffsets
void computeScaleOffsets(const QRect &targetRect, float &scale, float &offsetX, float &offsetY) const
Definition: EditDepthArea.cpp:225
float
float
rtabmap::EditDepthArea::colorMapWhiteToBlack_
QAction * colorMapWhiteToBlack_
Definition: EditDepthArea.h:92
uCvMat2QImage
QImage uCvMat2QImage(const cv::Mat &image, bool isBgr=true, uCvQtDepthColorMap colorMap=uCvQtDepthWhiteToBlack, float depthMin=0, float depthMax=0)
Definition: UCv2Qt.h:47
uCvQtDepthBlackToWhite
@ uCvQtDepthBlackToWhite
Definition: UCv2Qt.h:32
rtabmap::EditDepthArea::modified_
bool modified_
Definition: EditDepthArea.h:77
rtabmap::EditDepthArea::contextMenuEvent
virtual void contextMenuEvent(QContextMenuEvent *e)
Definition: EditDepthArea.cpp:355
rtabmap
Definition: CameraARCore.cpp:35
rtabmap::EditDepthArea::scribbling_
bool scribbling_
Definition: EditDepthArea.h:78
rtabmap::EditDepthArea::image_
QImage image_
Definition: EditDepthArea.h:82
i
int i
rtabmap::EditDepthArea::myPenWidth_
int myPenWidth_
Definition: EditDepthArea.h:79
EditDepthArea.h


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jul 25 2024 02:50:09