ImageView: added option to set maximum range for depth colormap

This commit is contained in:
matlabbe
2022-03-03 18:01:04 -05:00
parent b9c7182a08
commit 1e82fd3110
3 changed files with 66 additions and 22 deletions

View File

@@ -71,6 +71,7 @@ public:
const QColor & getDefaultMatchingFeatureColor() const; const QColor & getDefaultMatchingFeatureColor() const;
const QColor & getDefaultMatchingLineColor() const; const QColor & getDefaultMatchingLineColor() const;
const QColor & getBackgroundColor() const; const QColor & getBackgroundColor() const;
float getDepthColorMapRange() const;
uCvQtDepthColorMap getDepthColorMap() const; uCvQtDepthColorMap getDepthColorMap() const;
float viewScale() const; float viewScale() const;
@@ -87,6 +88,7 @@ public:
void setDefaultMatchingFeatureColor(const QColor & color); void setDefaultMatchingFeatureColor(const QColor & color);
void setDefaultMatchingLineColor(const QColor & color); void setDefaultMatchingLineColor(const QColor & color);
void setBackgroundColor(const QColor & color); void setBackgroundColor(const QColor & color);
void setDepthColorMapRange(float value);
void setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const cv::Mat & depth = cv::Mat(), const QColor & color = Qt::yellow); void setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const cv::Mat & depth = cv::Mat(), const QColor & color = Qt::yellow);
void setFeatures(const std::vector<cv::KeyPoint> & features, const cv::Mat & depth = cv::Mat(), const QColor & color = Qt::yellow); void setFeatures(const std::vector<cv::KeyPoint> & features, const cv::Mat & depth = cv::Mat(), const QColor & color = Qt::yellow);
@@ -133,6 +135,7 @@ private:
QColor _defaultFeatureColor; QColor _defaultFeatureColor;
QColor _defaultMatchingFeatureColor; QColor _defaultMatchingFeatureColor;
QColor _defaultMatchingLineColor; QColor _defaultMatchingLineColor;
float _depthColorMapRange;
QMenu * _menu; QMenu * _menu;
QAction * _showImage; QAction * _showImage;
@@ -153,6 +156,7 @@ private:
QAction * _colorMapBlackToWhite; QAction * _colorMapBlackToWhite;
QAction * _colorMapRedToBlue; QAction * _colorMapRedToBlue;
QAction * _colorMapBlueToRed; QAction * _colorMapBlueToRed;
QAction * _colorMapRange;
QMenu * _featureMenu; QMenu * _featureMenu;
QMenu * _scaleMenu; QMenu * _scaleMenu;

View File

@@ -39,9 +39,17 @@ enum uCvQtDepthColorMap{
* depth (float32, uint16) image and RGB/BGR 8bits images. * depth (float32, uint16) image and RGB/BGR 8bits images.
* @param image the cv::Mat image (can be 1 channel [CV_8U, CV_16U or CV_32F] or 3 channels [CV_U8]) * @param image the cv::Mat image (can be 1 channel [CV_8U, CV_16U or CV_32F] or 3 channels [CV_U8])
* @param isBgr if 3 channels, it is BGR or RGB order. * @param isBgr if 3 channels, it is BGR or RGB order.
* @param colorMap gradient of color to use to visualize depth
* @param depthMin fixed minimum range (m) of the depth gradient (if depthMax<=depthMin, max/min are computed based on data in depth image)
* @param depthMax fixed maximum range (m) of the depth gradient (if depthMax<=depthMin, max/min are computed based on data in depth image)
* @return the QImage * @return the QImage
*/ */
inline QImage uCvMat2QImage(const cv::Mat & image, bool isBgr = true, uCvQtDepthColorMap colorMap = uCvQtDepthWhiteToBlack) inline QImage uCvMat2QImage(
const cv::Mat & image,
bool isBgr = true,
uCvQtDepthColorMap colorMap = uCvQtDepthWhiteToBlack,
float depthMin = 0,
float depthMax = 0)
{ {
QImage qtemp; QImage qtemp;
if(!image.empty() && image.depth() == CV_8U) if(!image.empty() && image.depth() == CV_8U)
@@ -87,18 +95,21 @@ inline QImage uCvMat2QImage(const cv::Mat & image, bool isBgr = true, uCvQtDepth
{ {
// Assume depth image (float in meters) // Assume depth image (float in meters)
const float * data = (const float *)image.data; const float * data = (const float *)image.data;
float min=data[0], max=data[0]; float min=depthMax>depthMin?depthMin:data[0], max=depthMax>depthMin?depthMax:data[0];
for(unsigned int i=1; i<image.total(); ++i) if(depthMax <= depthMin)
{ {
if(uIsFinite(data[i]) && data[i] > 0) for(unsigned int i=1; i<image.total(); ++i)
{ {
if(!uIsFinite(min) || (data[i] > 0 && data[i]<min)) if(uIsFinite(data[i]) && data[i] > 0)
{ {
min = data[i]; if(!uIsFinite(min) || (data[i] > 0 && data[i]<min))
} {
if(!uIsFinite(max) || (data[i] > 0 && data[i]>max)) min = data[i];
{ }
max = data[i]; if(!uIsFinite(max) || (data[i] > 0 && data[i]>max))
{
max = data[i];
}
} }
} }
} }
@@ -115,7 +126,7 @@ inline QImage uCvMat2QImage(const cv::Mat & image, bool isBgr = true, uCvQtDepth
} }
else else
{ {
*p = uchar(255.0f - ((data[x]-min)*255.0f)/(max-min)); *p = uchar(std::max(0.0f, std::min(255.0f, 255.0f - ((data[x]-min)*255.0f)/(max-min))));
if(*p == 255) if(*p == 255)
{ {
*p = 0; *p = 0;
@@ -147,18 +158,21 @@ inline QImage uCvMat2QImage(const cv::Mat & image, bool isBgr = true, uCvQtDepth
{ {
// Assume depth image (unsigned short in mm) // Assume depth image (unsigned short in mm)
const unsigned short * data = (const unsigned short *)image.data; const unsigned short * data = (const unsigned short *)image.data;
unsigned short min=data[0], max=data[0]; unsigned short min=depthMax>depthMin?(unsigned short)(depthMin*1000):data[0], max=depthMax>depthMin?(unsigned short)(depthMax*1000):data[0];
for(unsigned int i=1; i<image.total(); ++i) if(depthMax<=depthMin)
{ {
if(uIsFinite(data[i]) && data[i] > 0) for(unsigned int i=1; i<image.total(); ++i)
{ {
if(!uIsFinite(min) || (data[i] > 0 && data[i]<min)) if(uIsFinite(data[i]) && data[i] > 0)
{ {
min = data[i]; if(!uIsFinite(min) || (data[i] > 0 && data[i]<min))
} {
if(!uIsFinite(max) || (data[i] > 0 && data[i]>max)) min = data[i];
{ }
max = data[i]; if(!uIsFinite(max) || (data[i] > 0 && data[i]>max))
{
max = data[i];
}
} }
} }
} }
@@ -175,7 +189,7 @@ inline QImage uCvMat2QImage(const cv::Mat & image, bool isBgr = true, uCvQtDepth
} }
else else
{ {
*p = uchar(255.0f - (float(data[x]-min)/float(max-min))*255.0f); *p = uchar(std::max(0.0f, std::min(255.0f, 255.0f - (float(data[x]-min)/float(max-min))*255.0f)));
if(*p == 255) if(*p == 255)
{ {
*p = 0; *p = 0;

View File

@@ -170,6 +170,7 @@ ImageView::ImageView(QWidget * parent) :
_defaultFeatureColor(Qt::yellow), _defaultFeatureColor(Qt::yellow),
_defaultMatchingFeatureColor(Qt::magenta), _defaultMatchingFeatureColor(Qt::magenta),
_defaultMatchingLineColor(Qt::cyan), _defaultMatchingLineColor(Qt::cyan),
_depthColorMapRange(0),
_imageItem(0), _imageItem(0),
_imageDepthItem(0) _imageDepthItem(0)
{ {
@@ -251,11 +252,13 @@ ImageView::ImageView(QWidget * parent) :
_colorMapBlueToRed = colorMap->addAction(tr("Blue to red")); _colorMapBlueToRed = colorMap->addAction(tr("Blue to red"));
_colorMapBlueToRed->setCheckable(true); _colorMapBlueToRed->setCheckable(true);
_colorMapBlueToRed->setChecked(false); _colorMapBlueToRed->setChecked(false);
_colorMapRange = colorMap->addAction(tr("Max Range..."));
group = new QActionGroup(this); group = new QActionGroup(this);
group->addAction(_colorMapWhiteToBlack); group->addAction(_colorMapWhiteToBlack);
group->addAction(_colorMapBlackToWhite); group->addAction(_colorMapBlackToWhite);
group->addAction(_colorMapRedToBlue); group->addAction(_colorMapRedToBlue);
group->addAction(_colorMapBlueToRed); group->addAction(_colorMapBlueToRed);
group->addAction(_colorMapRange);
_saveImage = _menu->addAction(tr("Save picture...")); _saveImage = _menu->addAction(tr("Save picture..."));
_saveImage->setEnabled(false); _saveImage->setEnabled(false);
@@ -286,6 +289,7 @@ void ImageView::saveSettings(QSettings & settings, const QString & group) const
settings.setValue("graphics_view_scale", this->isGraphicsViewScaled()); settings.setValue("graphics_view_scale", this->isGraphicsViewScaled());
settings.setValue("graphics_view_scale_to_height", this->isGraphicsViewScaledToHeight()); settings.setValue("graphics_view_scale_to_height", this->isGraphicsViewScaledToHeight());
settings.setValue("colormap", _colorMapWhiteToBlack->isChecked()?0:_colorMapBlackToWhite->isChecked()?1:_colorMapRedToBlue->isChecked()?2:3); settings.setValue("colormap", _colorMapWhiteToBlack->isChecked()?0:_colorMapBlackToWhite->isChecked()?1:_colorMapRedToBlue->isChecked()?2:3);
settings.setValue("colormap_range", this->getDepthColorMapRange());
if(!group.isEmpty()) if(!group.isEmpty())
{ {
settings.endGroup(); settings.endGroup();
@@ -316,6 +320,7 @@ void ImageView::loadSettings(QSettings & settings, const QString & group)
_colorMapBlackToWhite->setChecked(colorMap==1); _colorMapBlackToWhite->setChecked(colorMap==1);
_colorMapRedToBlue->setChecked(colorMap==2); _colorMapRedToBlue->setChecked(colorMap==2);
_colorMapBlueToRed->setChecked(colorMap==3); _colorMapBlueToRed->setChecked(colorMap==3);
this->setDepthColorMapRange(settings.value("colormap_range", this->getDepthColorMapRange()).toFloat());
if(!group.isEmpty()) if(!group.isEmpty())
{ {
settings.endGroup(); settings.endGroup();
@@ -379,6 +384,11 @@ const QColor & ImageView::getBackgroundColor() const
return _graphicsView->backgroundBrush().color(); return _graphicsView->backgroundBrush().color();
} }
float ImageView::getDepthColorMapRange() const
{
return _depthColorMapRange;
}
uCvQtDepthColorMap ImageView::getDepthColorMap() const uCvQtDepthColorMap ImageView::getDepthColorMap() const
{ {
uCvQtDepthColorMap colorMap = uCvQtDepthWhiteToBlack; uCvQtDepthColorMap colorMap = uCvQtDepthWhiteToBlack;
@@ -676,6 +686,12 @@ void ImageView::setBackgroundColor(const QColor & color)
} }
} }
void ImageView::setDepthColorMapRange(float value)
{
_depthColorMapRange = value;
}
void ImageView::computeScaleOffsets(const QRect & targetRect, float & scale, float & offsetX, float & offsetY) const void ImageView::computeScaleOffsets(const QRect & targetRect, float & scale, float & offsetX, float & offsetY) const
{ {
scale = 1.0f; scale = 1.0f;
@@ -950,6 +966,16 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
this->setImageDepth(_imageDepthCv); this->setImageDepth(_imageDepthCv);
Q_EMIT configChanged(); Q_EMIT configChanged();
} }
else if(action == _colorMapRange)
{
bool ok = false;
double value = QInputDialog::getDouble(this, tr("Set depth colormap max range"), tr("Range (m), 0=no limit"), _depthColorMapRange, 0, 9999, 1, &ok);
if(ok)
{
this->setDepthColorMapRange(value);
Q_EMIT configChanged();
}
}
else if(action == _setAlpha) else if(action == _setAlpha)
{ {
bool ok = false; bool ok = false;
@@ -1126,7 +1152,7 @@ void ImageView::setImage(const QImage & image)
void ImageView::setImageDepth(const cv::Mat & imageDepth) void ImageView::setImageDepth(const cv::Mat & imageDepth)
{ {
_imageDepthCv = imageDepth; _imageDepthCv = imageDepth;
setImageDepth(uCvMat2QImage(_imageDepthCv, true, getDepthColorMap())); setImageDepth(uCvMat2QImage(_imageDepthCv, true, getDepthColorMap(), 0.0f, _depthColorMapRange));
} }
void ImageView::setImageDepth(const QImage & imageDepth) void ImageView::setImageDepth(const QImage & imageDepth)