EditDepthArea: added cluster error menu option, fixed seg fault on large cluster removal

This commit is contained in:
matlabbe
2019-04-26 18:03:07 -04:00
parent 38a83c0cd9
commit cd2c261e2b
2 changed files with 58 additions and 13 deletions

View File

@@ -55,6 +55,8 @@ public:
void setPenWidth(int newWidth);
int penWidth() const { return myPenWidth_; }
void setClusterError(double error) { clusterError_ = error; }
double clusterError() const { return clusterError_; }
void setColorMap(uCvQtDepthColorMap type);
public Q_SLOTS:
@@ -75,6 +77,7 @@ private:
bool modified_;
bool scribbling_;
int myPenWidth_;
double clusterError_;
QImage imageRGB_;
QImage image_;
cv::Mat originalImage_;
@@ -83,6 +86,7 @@ private:
QMenu * menu_;
QAction * showRGB_;
QAction * removeCluster_;
QAction * clusterErrorCluster_;
QAction * resetChanges_;
QAction * setPenWidth_;
QAction * colorMapWhiteToBlack_;

View File

@@ -44,12 +44,14 @@ EditDepthArea::EditDepthArea(QWidget *parent)
modified_ = false;
scribbling_ = false;
myPenWidth_ = 10;
clusterError_ = 0.02;
menu_ = new QMenu(tr(""), this);
showRGB_ = menu_->addAction(tr("Show RGB Image"));
showRGB_->setCheckable(true);
showRGB_->setChecked(true);
removeCluster_ = menu_->addAction(tr("Remove Cluster"));
clusterErrorCluster_ = menu_->addAction(tr("Set Cluster Error"));
setPenWidth_ = menu_->addAction(tr("Set Pen Width..."));
QMenu * colorMap = menu_->addMenu("Depth color map");
colorMapWhiteToBlack_ = colorMap->addAction(tr("White to black"));
@@ -283,8 +285,9 @@ void EditDepthArea::resizeEvent(QResizeEvent *event)
QWidget::resizeEvent(event);
}
void floodfill(QImage & image, const cv::Mat & depthImage, int x, int y, float lastDepthValue, float error)
void floodfill(QRgb * bits, const cv::Mat & depthImage, int x, int y, float lastDepthValue, float error, int &iterations)
{
++iterations;
if(x>=0 && x<depthImage.cols &&
y>=0 && y<depthImage.rows)
{
@@ -297,13 +300,13 @@ void floodfill(QImage & image, const cv::Mat & depthImage, int x, int y, float l
{
currentValue = float(depthImage.at<unsigned short>(y, x))/1000.0f;
}
QRgb rgb = image.pixel(x,y);
if(qRed(rgb) == 0 && qGreen(rgb) == 0 && qBlue(rgb) == 0)
if(currentValue == 0.0f)
{
return;
}
if(currentValue == 0.0f)
QRgb & rgb = bits[x+y*depthImage.cols];
if(qRed(rgb) == 0 && qGreen(rgb) == 0 && qBlue(rgb) == 0)
{
return;
}
@@ -311,13 +314,40 @@ void floodfill(QImage & image, const cv::Mat & depthImage, int x, int y, float l
{
return;
}
rgb = 0;
image.setPixel(x, y, 0);
floodfill(image, depthImage, x, y+1, currentValue, error);
floodfill(image, depthImage, x, y-1, currentValue, error);
floodfill(image, depthImage, x-1, y, currentValue, error);
floodfill(image, depthImage, x+1, y, currentValue, error);
if(y+1<depthImage.rows)
{
QRgb & rgb = bits[x+(y+1)*depthImage.cols];
if(qRed(rgb) != 0 || qGreen(rgb) != 0 || qBlue(rgb) != 0)
{
floodfill(bits, depthImage, x, y+1, currentValue, error, iterations);
}
}
if(y-1>=0)
{
QRgb & rgb = bits[x+(y-1)*depthImage.cols];
if(qRed(rgb) != 0 || qGreen(rgb) != 0 || qBlue(rgb) != 0)
{
floodfill(bits, depthImage, x, y-1, currentValue, error, iterations);
}
}
if(x+1<depthImage.cols)
{
QRgb & rgb = bits[x+1+y*depthImage.cols];
if(qRed(rgb) != 0 || qGreen(rgb) != 0 || qBlue(rgb) != 0)
{
floodfill(bits, depthImage, x+1, y, currentValue, error, iterations);
}
}
if(x-1>=0)
{
QRgb & rgb = bits[x-1+y*depthImage.cols];
if(qRed(rgb) != 0 || qGreen(rgb) != 0 || qBlue(rgb) != 0)
{
floodfill(bits, depthImage, x-1, y, currentValue, error, iterations);
}
}
}
}
@@ -338,15 +368,26 @@ void EditDepthArea::contextMenuEvent(QContextMenuEvent * e)
if(pixel.x()>=0 && pixel.x() < originalImage_.cols &&
pixel.y()>=0 && pixel.y() < originalImage_.rows)
{
floodfill(image_, originalImage_, pixel.x(), pixel.y(), -1.0f, 0.02f);
int iterations=0;
floodfill((QRgb*)image_.bits(), originalImage_, pixel.x(), pixel.y(), -1.0f, clusterError_, iterations);
}
modified_=true;
this->update();
}
else if(action == clusterErrorCluster_)
{
bool ok;
double error = QInputDialog::getDouble(this, tr("Set Cluster Error"), tr("Error:"), clusterError(), 0.001, 1, 3, &ok);
if(ok)
{
clusterError_= error;
}
modified_=true;
}
else if(action == setPenWidth_)
{
bool ok;
int width = QInputDialog::getInt(this, tr("Set Pen Width"), tr("Width:"), penWidth(), 1, 99, 1, &ok);
int width = QInputDialog::getInt(this, tr("Set Pen Width"), tr("Width (pixels):"), penWidth(), 1, 999, 1, &ok);
if(ok)
{
myPenWidth_ = width;