New feature: we can setup the camera to use a video file intead of the webcam.
Fixed a crash when user did "Update Objects" with loaded objects. git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@76 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
parent
465e2d846e
commit
0e3b934316
@ -142,7 +142,7 @@ void AddObjectDialog::setState(int state)
|
||||
else if(state == kSelectFeatures)
|
||||
{
|
||||
disconnect(camera_, SIGNAL(imageReceived(const cv::Mat &)), this, SLOT(update(const cv::Mat &)));
|
||||
camera_->stop();
|
||||
camera_->pause();
|
||||
|
||||
ui_->pushButton_cancel->setEnabled(true);
|
||||
ui_->pushButton_back->setEnabled(true);
|
||||
@ -169,7 +169,7 @@ void AddObjectDialog::setState(int state)
|
||||
else if(state == kVerifySelection)
|
||||
{
|
||||
disconnect(camera_, SIGNAL(imageReceived(const cv::Mat &)), this, SLOT(update(const cv::Mat &)));
|
||||
camera_->stop();
|
||||
camera_->pause();
|
||||
|
||||
ui_->pushButton_cancel->setEnabled(true);
|
||||
ui_->pushButton_back->setEnabled(true);
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <opencv2/imgproc/imgproc_c.h>
|
||||
#include "Settings.h"
|
||||
#include <QtCore/QFile>
|
||||
|
||||
Camera::Camera(QObject * parent) :
|
||||
QObject(parent),
|
||||
@ -30,6 +31,11 @@ void Camera::stop()
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::pause()
|
||||
{
|
||||
stopTimer();
|
||||
}
|
||||
|
||||
void Camera::takeImage()
|
||||
{
|
||||
if(capture_)
|
||||
@ -73,11 +79,23 @@ bool Camera::start()
|
||||
{
|
||||
if(!capture_)
|
||||
{
|
||||
capture_ = cvCaptureFromCAM(Settings::getCamera_deviceId());
|
||||
if(capture_)
|
||||
QString videoFile = Settings::getCamera_videoFilePath();
|
||||
if(QFile::exists(videoFile))
|
||||
{
|
||||
cvSetCaptureProperty(capture_, CV_CAP_PROP_FRAME_WIDTH, double(Settings::getCamera_imageWidth()));
|
||||
cvSetCaptureProperty(capture_, CV_CAP_PROP_FRAME_HEIGHT, double(Settings::getCamera_imageHeight()));
|
||||
capture_ = cvCaptureFromAVI(videoFile.toStdString().c_str());
|
||||
if(!capture_)
|
||||
{
|
||||
printf("WARNING: Cannot open file \"%s\". If you want to disable loading automatically this video file, clear the Camera/videoFilePath parameter. By default, webcam will be used instead of the file.\n", videoFile.toStdString().c_str());
|
||||
}
|
||||
}
|
||||
if(!capture_)
|
||||
{
|
||||
capture_ = cvCaptureFromCAM(Settings::getCamera_deviceId());
|
||||
if(capture_ && Settings::getCamera_imageWidth() && Settings::getCamera_imageHeight())
|
||||
{
|
||||
cvSetCaptureProperty(capture_, CV_CAP_PROP_FRAME_WIDTH, double(Settings::getCamera_imageWidth()));
|
||||
cvSetCaptureProperty(capture_, CV_CAP_PROP_FRAME_HEIGHT, double(Settings::getCamera_imageHeight()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!capture_)
|
||||
|
||||
@ -19,6 +19,8 @@ public:
|
||||
virtual void stop();
|
||||
virtual bool isRunning() {return cameraTimer_.isActive();}
|
||||
|
||||
void pause();
|
||||
|
||||
signals:
|
||||
void imageReceived(const cv::Mat & image);
|
||||
|
||||
|
||||
@ -71,6 +71,7 @@ MainWindow::MainWindow(Camera * camera, QWidget * parent) :
|
||||
connect(ui_->pushButton_updateObjects, SIGNAL(clicked()), this, SLOT(updateObjects()));
|
||||
|
||||
ui_->actionStop_camera->setEnabled(false);
|
||||
ui_->actionPause_camera->setEnabled(false);
|
||||
ui_->actionSave_objects->setEnabled(false);
|
||||
|
||||
// Actions
|
||||
@ -79,12 +80,20 @@ MainWindow::MainWindow(Camera * camera, QWidget * parent) :
|
||||
connect(ui_->actionLoad_scene_from_file, SIGNAL(triggered()), this, SLOT(loadSceneFromFile()));
|
||||
connect(ui_->actionStart_camera, SIGNAL(triggered()), this, SLOT(startProcessing()));
|
||||
connect(ui_->actionStop_camera, SIGNAL(triggered()), this, SLOT(stopProcessing()));
|
||||
connect(ui_->actionPause_camera, SIGNAL(triggered()), this, SLOT(pauseProcessing()));
|
||||
connect(ui_->actionExit, SIGNAL(triggered()), this, SLOT(close()));
|
||||
connect(ui_->actionSave_objects, SIGNAL(triggered()), this, SLOT(saveObjects()));
|
||||
connect(ui_->actionLoad_objects, SIGNAL(triggered()), this, SLOT(loadObjects()));
|
||||
connect(ui_->actionSetup_camera_from_video_file, SIGNAL(triggered()), this, SLOT(setupCameraFromVideoFile()));
|
||||
connect(ui_->actionSetup_camera_from_video_file_2, SIGNAL(triggered()), this, SLOT(setupCameraFromVideoFile()));
|
||||
connect(ui_->actionAbout, SIGNAL(triggered()), aboutDialog_ , SLOT(exec()));
|
||||
connect(ui_->actionRestore_all_default_settings, SIGNAL(triggered()), ui_->toolBox, SLOT(resetAllPages()));
|
||||
|
||||
ui_->actionSetup_camera_from_video_file->setCheckable(true);
|
||||
ui_->actionSetup_camera_from_video_file_2->setCheckable(true);
|
||||
ui_->actionSetup_camera_from_video_file->setChecked(!Settings::getCamera_videoFilePath().isEmpty());
|
||||
ui_->actionSetup_camera_from_video_file_2->setChecked(!Settings::getCamera_videoFilePath().isEmpty());
|
||||
|
||||
if(Settings::getGeneral_autoStartCamera())
|
||||
{
|
||||
// Set 1 msec to see state on the status bar.
|
||||
@ -237,6 +246,21 @@ void MainWindow::loadSceneFromFile()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setupCameraFromVideoFile()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Setup camera from video file..."), Settings::workingDirectory(), tr("Video Files (*.avi *.m4v)"));
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
Settings::setCamera_videoFilePath(fileName);
|
||||
ui_->toolBox->updateParameter(Settings::kCamera_videoFilePath());
|
||||
if(camera_->isRunning())
|
||||
{
|
||||
this->stopProcessing();
|
||||
this->startProcessing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::showObject(ObjWidget * obj)
|
||||
{
|
||||
if(obj)
|
||||
@ -257,6 +281,7 @@ void MainWindow::showObject(ObjWidget * obj)
|
||||
id = obj->id()+1;
|
||||
Settings::setGeneral_nextObjID(id);
|
||||
}
|
||||
ui_->toolBox->updateParameter(Settings::kGeneral_nextObjID());
|
||||
|
||||
QLabel * title = new QLabel(QString("%1 (%2)").arg(obj->id()).arg(QString::number(obj->keypoints().size())), this);
|
||||
QLabel * detectorDescriptorType = new QLabel(QString("%1/%2").arg(obj->detectorType()).arg(obj->descriptorType()), this);
|
||||
@ -346,13 +371,27 @@ void MainWindow::updateData()
|
||||
{
|
||||
if(dim >= 0 && objects_.at(i)->descriptors().cols != dim)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Descriptors of the objects are not all the same size!\nObjects opened must have all the same size (and from the same descriptor extractor)."));
|
||||
if(this->isVisible())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Descriptors of the objects are not all the same size!\nObjects opened must have all the same size (and from the same descriptor extractor)."));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ERROR: Descriptors of the objects are not all the same size! Objects opened must have all the same size (and from the same descriptor extractor).");
|
||||
}
|
||||
return;
|
||||
}
|
||||
dim = objects_.at(i)->descriptors().cols;
|
||||
if(type >= 0 && objects_.at(i)->descriptors().type() != type)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Descriptors of the objects are not all the same type!\nObjects opened must have been processed by the same descriptor extractor."));
|
||||
if(this->isVisible())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Descriptors of the objects are not all the same type!\nObjects opened must have been processed by the same descriptor extractor."));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ERROR: Descriptors of the objects are not all the same type! Objects opened must have been processed by the same descriptor extractor.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
type = objects_.at(i)->descriptors().type();
|
||||
@ -383,6 +422,7 @@ void MainWindow::startProcessing()
|
||||
{
|
||||
connect(camera_, SIGNAL(imageReceived(const cv::Mat &)), this, SLOT(update(const cv::Mat &)));
|
||||
ui_->actionStop_camera->setEnabled(true);
|
||||
ui_->actionPause_camera->setEnabled(true);
|
||||
ui_->actionStart_camera->setEnabled(false);
|
||||
ui_->actionLoad_scene_from_file->setEnabled(false);
|
||||
ui_->label_timeRefreshRate->setVisible(true);
|
||||
@ -391,7 +431,14 @@ void MainWindow::startProcessing()
|
||||
else
|
||||
{
|
||||
this->statusBar()->clearMessage();
|
||||
QMessageBox::critical(this, tr("Camera error"), tr("Camera initialization failed! (with device %1)").arg(Settings::getCamera_deviceId()));
|
||||
if(this->isVisible())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Camera error"), tr("Camera initialization failed! (with device %1)").arg(Settings::getCamera_deviceId()));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ERROR: Camera initialization failed! (with device %d)", Settings::getCamera_deviceId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,10 +450,26 @@ void MainWindow::stopProcessing()
|
||||
camera_->stop();
|
||||
}
|
||||
ui_->actionStop_camera->setEnabled(false);
|
||||
ui_->actionPause_camera->setEnabled(false);
|
||||
ui_->actionStart_camera->setEnabled(true);
|
||||
ui_->actionLoad_scene_from_file->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::pauseProcessing()
|
||||
{
|
||||
ui_->actionStop_camera->setEnabled(true);
|
||||
ui_->actionPause_camera->setEnabled(true);
|
||||
ui_->actionStart_camera->setEnabled(false);
|
||||
if(camera_->isRunning())
|
||||
{
|
||||
camera_->pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
camera_->start();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::update(const cv::Mat & image)
|
||||
{
|
||||
// reset objects color
|
||||
@ -707,4 +770,7 @@ void MainWindow::notifyParametersChanged()
|
||||
this->update(image);
|
||||
ui_->label_timeRefreshRate->setVisible(false);
|
||||
}
|
||||
|
||||
ui_->actionSetup_camera_from_video_file->setChecked(!Settings::getCamera_videoFilePath().isEmpty());
|
||||
ui_->actionSetup_camera_from_video_file_2->setChecked(!Settings::getCamera_videoFilePath().isEmpty());
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ protected:
|
||||
public slots:
|
||||
void startProcessing();
|
||||
void stopProcessing();
|
||||
void pauseProcessing();
|
||||
|
||||
private slots:
|
||||
void loadObjects();
|
||||
@ -47,6 +48,7 @@ private slots:
|
||||
void addObject();
|
||||
void addObjectsFromFiles();
|
||||
void loadSceneFromFile();
|
||||
void setupCameraFromVideoFile();
|
||||
void removeObject(ObjWidget * object);
|
||||
void update(const cv::Mat & image);
|
||||
void updateObjects();
|
||||
|
||||
@ -403,6 +403,12 @@ void ObjWidget::load(QDataStream & streamPtr)
|
||||
descriptors = cv::Mat(rows, cols, type, data.data()).clone();
|
||||
streamPtr >> image_;
|
||||
this->setData(kpts, descriptors, 0, detectorType, descriptorType);
|
||||
if(iplImage_)
|
||||
{
|
||||
cvReleaseImage(&iplImage_);
|
||||
iplImage_ = 0;
|
||||
}
|
||||
iplImage_ = QImage2Ipl(image_.toImage());
|
||||
//this->setMinimumSize(image_.size());
|
||||
}
|
||||
|
||||
|
||||
@ -123,6 +123,36 @@ void ParametersToolBox::setupUi()
|
||||
}
|
||||
}
|
||||
|
||||
void ParametersToolBox::updateParameter(const QString & key)
|
||||
{
|
||||
QWidget * widget = this->findChild<QWidget*>(key);
|
||||
QString type = Settings::getParametersType().value(key);
|
||||
if(type.compare("QString") == 0)
|
||||
{
|
||||
((QLineEdit*)widget)->setText(Settings::getParameter(key).toString());
|
||||
}
|
||||
else if(type.compare("int") == 0)
|
||||
{
|
||||
((QSpinBox*)widget)->setValue(Settings::getParameter(key).toInt());
|
||||
}
|
||||
else if(type.compare("uint") == 0)
|
||||
{
|
||||
((QSpinBox*)widget)->setValue(Settings::getParameter(key).toInt());
|
||||
}
|
||||
else if(type.compare("double") == 0)
|
||||
{
|
||||
((QDoubleSpinBox*)widget)->setValue(Settings::getParameter(key).toDouble());
|
||||
}
|
||||
else if(type.compare("float") == 0)
|
||||
{
|
||||
((QDoubleSpinBox*)widget)->setValue(Settings::getParameter(key).toDouble());
|
||||
}
|
||||
else if(type.compare("bool") == 0)
|
||||
{
|
||||
((QCheckBox*)widget)->setChecked(Settings::getParameter(key).toBool());
|
||||
}
|
||||
}
|
||||
|
||||
void ParametersToolBox::addParameter(QVBoxLayout * layout,
|
||||
const QString & key,
|
||||
const QVariant & value)
|
||||
@ -216,11 +246,11 @@ void ParametersToolBox::addParameter(QVBoxLayout * layout,
|
||||
|
||||
if(def>0)
|
||||
{
|
||||
widget->setMaximum(def*10);
|
||||
widget->setMaximum(def*1000000);
|
||||
}
|
||||
else if(def<0)
|
||||
{
|
||||
widget->setMinimum(def*10);
|
||||
widget->setMinimum(def*1000000);
|
||||
widget->setMaximum(0);
|
||||
}
|
||||
widget->setValue(value);
|
||||
@ -253,6 +283,7 @@ void ParametersToolBox::changeParameter(const QString & value)
|
||||
if(sender())
|
||||
{
|
||||
Settings::setParameter(sender()->objectName(), value);
|
||||
emit parametersChanged();
|
||||
}
|
||||
}
|
||||
void ParametersToolBox::changeParameter()
|
||||
|
||||
@ -20,6 +20,7 @@ public:
|
||||
|
||||
void setupUi();
|
||||
QWidget * getParameterWidget(const QString & key);
|
||||
void updateParameter(const QString & key);
|
||||
|
||||
private:
|
||||
void addParameter(QVBoxLayout * layout, const QString & key, const QVariant & value);
|
||||
|
||||
@ -56,6 +56,7 @@ class Settings
|
||||
PARAMETER(Camera, imageWidth, int, 640);
|
||||
PARAMETER(Camera, imageHeight, int, 480);
|
||||
PARAMETER(Camera, imageRate, int, 2); // Hz
|
||||
PARAMETER(Camera, videoFilePath, QString, "");
|
||||
|
||||
//List format : [Index:item0;item1;item3;...]
|
||||
PARAMETER(Detector, Type, QString, "7:Dense;Fast;GoodFeaturesToTrack;Mser;Orb;Sift;Star;Surf");
|
||||
|
||||
@ -15,10 +15,10 @@ QImage Ipl2QImage(const IplImage *newImage)
|
||||
int y;
|
||||
char* data = newImage->imageData;
|
||||
|
||||
qtemp= QImage(newImage->width, newImage->height,QImage::Format_RGB32 );
|
||||
for( y = 0; y < newImage->height; y++, data +=newImage->widthStep )
|
||||
qtemp= QImage(newImage->width, newImage->height,QImage::Format_RGB32);
|
||||
for( y = 0; y < newImage->height; ++y, data +=newImage->widthStep )
|
||||
{
|
||||
for( x = 0; x < newImage->width; x++)
|
||||
for( x = 0; x < newImage->width; ++x)
|
||||
{
|
||||
uint *p = (uint*)qtemp.scanLine (y) + x;
|
||||
*p = qRgb(data[x * newImage->nChannels+2], data[x * newImage->nChannels+1],data[x * newImage->nChannels]);
|
||||
@ -31,3 +31,33 @@ QImage Ipl2QImage(const IplImage *newImage)
|
||||
}
|
||||
return qtemp;
|
||||
}
|
||||
|
||||
IplImage * QImage2Ipl(const QImage & image)
|
||||
{
|
||||
IplImage * iplTmp = 0;
|
||||
if(!image.isNull() && image.depth() == 32 && image.format() == QImage::Format_RGB32)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
// assume RGB (3 channels)
|
||||
int channels = 3;
|
||||
iplTmp = cvCreateImage(cvSize(image.width(), image.height()), IPL_DEPTH_8U, channels);
|
||||
char* data = iplTmp->imageData;
|
||||
for( y = 0; y < image.height(); ++y, data+=iplTmp->widthStep)
|
||||
{
|
||||
for( x = 0; x < image.width(); ++x)
|
||||
{
|
||||
QRgb rgb = image.pixel(x, y);
|
||||
data[x * channels+2] = qRed(rgb); //r
|
||||
data[x * channels+1] = qGreen(rgb); //g
|
||||
data[x * channels] = qBlue(rgb); //b
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("failed to convert image : depth=%d(!=32) format=%d(!=%d)\n", image.depth(), image.format(), QImage::Format_RGB32);
|
||||
}
|
||||
return iplTmp;
|
||||
}
|
||||
|
||||
@ -8,6 +8,10 @@
|
||||
#include <QtGui/QImage>
|
||||
#include <opencv2/core/core.hpp>
|
||||
|
||||
// IplImage to QImage
|
||||
QImage Ipl2QImage(const IplImage *newImage);
|
||||
|
||||
// QImage to IplImage
|
||||
IplImage * QImage2Ipl(const QImage & image);
|
||||
|
||||
#endif
|
||||
|
||||
@ -153,8 +153,12 @@
|
||||
<addaction name="actionLoad_scene_from_file"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionStart_camera"/>
|
||||
<addaction name="actionPause_camera"/>
|
||||
<addaction name="actionStop_camera"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSetup_camera_from_video_file"/>
|
||||
<addaction name="actionSetup_camera_from_video_file_2"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionRestore_all_default_settings"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
@ -495,6 +499,21 @@
|
||||
<string>Load scene from file...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPause_camera">
|
||||
<property name="text">
|
||||
<string>Pause camera</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSetup_camera_from_video_file">
|
||||
<property name="text">
|
||||
<string>Setup camera from video file...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSetup_camera_from_video_file_2">
|
||||
<property name="text">
|
||||
<string>Setup camera from video file...</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user