4#include "main_widget.hpp"
11#include <QElapsedTimer>
12#include <QGraphicsSceneMouseEvent>
14#include <QGraphicsRectItem>
16#include <cvb/image.hpp>
17#include <cvb/device_factory.hpp>
18#include <cvb/device.hpp>
19#include <cvb/async/single_stream_handler.hpp>
20#include <cvb/driver/driver.hpp>
21#include <cvb/shapefinder2/classifier_factory.hpp>
23MainWidget::MainWidget()
26 imageScene_ =
new CustomImageScene(
this);
31 imageView_->resize(800, 600);
33 imageView_->setDragMode(QGraphicsView::RubberBandDrag);
36 ctrlWidget_ =
new ControlWidget(
this);
37 addWidget(imageView_);
38 addWidget(ctrlWidget_);
44 streamHandler_ = CustomStreamHandler::Create(device_->Stream(), *
this);
46 ctrlWidget_->EnableGrabCheckBox(
true);
48 QObject::connect(
this, SIGNAL(SearchDone()),
this, SLOT(ShowSearchResult()));
53 device_->Stream()->GetSnapshot();
57void MainWidget::HandleLoad()
59 imageScene_->ClearScene();
62 ,
Cvb::UI::CvbToQt(Cvb::ExpandPath(Cvb::InstallPath() + CVB_LIT(
"tutorial/ShapeFinder/Images/SF2/Lusterterminal")))
63 ,
"CVB Emulator Image Lists (*.emu);;CVB Drivers (*.vin);;Images (*.bmp *.png *.tif *.tiff *.jpg)");
64 if (fileName.isEmpty())
67 if (fileName.contains(
".emu", Qt::CaseInsensitive))
68 fileName = fileName.replace(
"/",
"\\");
73 if (fileName.contains(
".bmp", Qt::CaseInsensitive) || fileName.contains(
".png", Qt::CaseInsensitive) || fileName.contains(
".tif", Qt::CaseInsensitive) || fileName.contains(
".jpg", Qt::CaseInsensitive))
76 imageView_->Refresh(image);
78 ctrlWidget_->EnableGrabCheckBox(
false);
86 streamHandler_ = CustomStreamHandler::Create(device_->Stream(), *
this);
88 ctrlWidget_->EnableGrabCheckBox(
true);
98void MainWidget::HandleGrab(
int state)
100 if (state == Qt::CheckState::Checked)
102 imageScene_->ClearScene();
105 streamHandler_->Run();
110 bool wait = imageView_->IsWaitForRepaintEnabled();
112 imageView_->SetWaitForRepaintEnabled(!wait);
114 streamHandler_->Finish();
116 imageView_->SetWaitForRepaintEnabled(wait);
121void MainWidget::HandleSnap()
123 device_->Stream()->GetSnapshot();
124 if (continuedSearch_)
127 imageScene_->ClearScene();
131void MainWidget::HandleSave()
135 ,
"Bitmap File (*.bmp);;CVB Emulator Image Lists (*.emu);;JPEG (*.jpg, *.jpeg);;Portable Network Graphic (*.png);;Tagged Image File Format (*.tif, *.tiff);;All Files (*.*)");
136 if (fileName.isEmpty())
142void MainWidget::HandleLoadModel()
144 imageScene_->ClearScene();
147 ,
Cvb::UI::CvbToQt(Cvb::ExpandPath(Cvb::InstallPath() + CVB_LIT(
"tutorial/ShapeFinder/Images/SF2/Lusterterminal")))
148 ,
"ShapeFinder2 models (*.sf2)");
149 if (fileName.isEmpty())
156void MainWidget::HandleSaveModel()
159 ,
Cvb::UI::CvbToQt(Cvb::ExpandPath(Cvb::InstallPath() + CVB_LIT(
"tutorial/ShapeFinder/Images/SF2/Lusterterminal")))
160 ,
"ShapeFinder2 models (*.sf2)");
161 if (fileName.isEmpty())
168void MainWidget::HandleTrain()
172 ctrlWidget_->SetTrainView(*selection_);
173 imageScene_->ClearScene();
178 ctrlWidget_->SetTrainView(*imageView_->Image());
179 auto aoi = imageView_->Image()->Bounds();
180 selectionRect_ =
Cvb::Rect<double>(aoi.Left(), aoi.Top(), aoi.Right(), aoi.Bottom());
185 double centerX = selectionRect_.Left() + ((selectionRect_.Right() - selectionRect_.Left()) / 2);
186 double centerY = selectionRect_.Top() + ((selectionRect_.Bottom() - selectionRect_.Top()) / 2);
188 Cvb::Rect<int> teachWindow(selectionRect_.Left() - centerX, selectionRect_.Top() - centerY, selectionRect_.Right() - centerX, selectionRect_.Bottom() - centerY);
200void MainWidget::HandleSearch()
204 QMessageBox::warning(
this,
"SF2 Search",
"Please create (train) or load a model/classifier first.");
212void MainWidget::HandleContSearch(
int state)
214 imageScene_->ClearScene();
216 if (state == Qt::Checked)
217 continuedSearch_ =
true;
219 continuedSearch_ =
false;
229void MainWidget::HandleSelection(
QRectF selection)
233 auto convertedArea = imageView_->Image()->ImageToPixelCoordinates(area);
240 selectionRect_ = boundingRect;
244void MainWidget::Search()
250 double relativeThreshold = 0.55;
251 int minimumThreshold = 20;
252 int coarseLocality = 10;
258 Cvb::Rect<int> aoi(selectionRect_.Left(), selectionRect_.Top(), selectionRect_.Right(), selectionRect_.Bottom());
259 SearchWithCuda(imageView_->Image()->Plane(0), aoi, mode, relativeThreshold, minimumThreshold, coarseLocality);
260 SearchWithoutCuda(imageView_->Image()->Plane(0), aoi, mode, relativeThreshold, minimumThreshold, coarseLocality);
264 SearchWithCuda(imageView_->Image()->Plane(0), imageView_->Image()->Bounds(), mode, relativeThreshold, minimumThreshold, coarseLocality);
265 SearchWithoutCuda(imageView_->Image()->Plane(0), imageView_->Image()->Bounds(), mode, relativeThreshold, minimumThreshold, coarseLocality);
280 searchResult_ = classifier_->SearchAll(plane, aoi, mode, relativeThreshold, minimumThreshold, coarseLocality);
282 durationWithCuda_ = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
289 searchResult_ = classifier_->SearchAll(plane, aoi, mode, relativeThreshold, minimumThreshold, coarseLocality);
291 durationWithoutCuda_ = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
295void MainWidget::ShowSearchResult()
298 ctrlWidget_->SetResultInfo(searchResult_.size());
299 imageScene_->SetSearchResult(*imageView_->Image(), searchResult_, durationWithCuda_, durationWithoutCuda_);
303ControlWidget::ControlWidget(
QWidget* parent)
313 QObject::connect(openImgBtn, SIGNAL(clicked()), parent, SLOT(HandleLoad()));
315 grabCheckBox_ =
new QCheckBox(tr(
"Grab"));
316 QObject::connect(grabCheckBox_, SIGNAL(stateChanged(
int)), parent, SLOT(HandleGrab(
int)));
324 contSearchCheckBox_ =
new QCheckBox(tr(
"Continued Search"));
325 QObject::connect(contSearchCheckBox_, SIGNAL(stateChanged(
int)), parent, SLOT(HandleContSearch(
int)));
330 QObject::connect(loadModelBtn, SIGNAL(clicked()), parent, SLOT(HandleLoadModel()));
333 QObject::connect(saveModelBtn, SIGNAL(clicked()), parent, SLOT(HandleSaveModel()));
339 QObject::connect(searchBtn, SIGNAL(clicked()), parent, SLOT(HandleSearch()));
341 resultLabel_ =
new QLabel(tr(
"Number of search results: 0"));
348 gbLayout->
addWidget(resultLabel_, 2, 0, 1, -1);
351 mainLayout->addWidget(trainImageView_, 0, 0, 1, -1);
352 mainLayout->addWidget(openImgBtn, 1, 0, 1, 1);
353 mainLayout->addWidget(grabCheckBox_, 1, 1, 1, 1);
354 mainLayout->addWidget(snapBtn, 1, 2, 1, 1);
355 mainLayout->addWidget(saveBtn, 2, 0, 1, 1);
356 mainLayout->addWidget(contSearchCheckBox_, 2, 1, 1, -1);
357 mainLayout->addWidget(groupBox, 3, 0, 1, -1);
359 setLayout(mainLayout);
362void ControlWidget::EnableGrabCheckBox(
bool value)
364 grabCheckBox_->setEnabled(value);
367void ControlWidget::SetResultInfo(
size_t numResults)
370 resultLabel_->setText(count);
373void ControlWidget::SetTrainView(
const Cvb::Image & image)
376 trainImageView_->Refresh(image);
380CustomImageScene::CustomImageScene(
QWidget* parent)
381 :
Cvb::UI::ImageScene(parent)
389 searchResult_ = result;
392 for (
int i = 0; i < searchResult_.size(); i++)
408 this->addItem(textLabel);
410 text->
setPos(point.X() + 5, point.Y() + 2.5);
414 QString label1 =
"Duration with Cuda: ";
415 QString label2 =
"Duration without Cuda: ";
429void CustomImageScene::ClearScene()
438 this->ImageView()->setDragMode(QGraphicsView::RubberBandDrag);
441 pointStart_ =
event->scenePos();
447 pointEnd_ =
event->scenePos();
449 this->addRect(
QRectF(pointStart_, pointEnd_),
QPen(Qt::blue, 0));
451 emit SelectionDone(
QRectF(pointStart_, pointEnd_));
double Deg() const noexcept
Get the value in degrees.
Definition: angle.hpp:87
Structure that represents an area of interest in the image.
Definition: area_2d.hpp:21
static std::shared_ptr< T > Open(const String &provider, AcquisitionStack acquisitionStack=AcquisitionStack::PreferVin)
Opens a device with the given provider with its default board and port (if applicable).
Definition: decl_device_factory.hpp:55
The Common Vision Blox image.
Definition: decl_image.hpp:45
static std::unique_ptr< Image > Load(const String &fileName)
Loads an image with the given file name.
Definition: detail_image.hpp:32
Point2D< double > PixelToImageCoordinates(Point2D< double > point) const noexcept
Convert a point from pixel to image coordinates.
Definition: decl_image.hpp:486
Image plane information container.
Definition: decl_image_plane.hpp:33
Rectangle object.
Definition: rect.hpp:26
T Bottom() const noexcept
Gets bottom row of the rectangle (still inside the rectangle).
Definition: rect.hpp:151
T Top() const noexcept
Gets first row of the rectangle.
Definition: rect.hpp:111
T Right() const noexcept
Gets rightmost column of the rectangle (still inside the rectangle).
Definition: rect.hpp:131
T Left() const noexcept
Gets first column of the rectangle.
Definition: rect.hpp:91
Rectangle object.
Definition: rect_lt.hpp:24
Size2D< T > Size() const noexcept
Gets the size of the rectangle.
Definition: rect_lt.hpp:205
Point2D< T > Location() const noexcept
Gets the location of the top left corner of the rectangle.
Definition: rect_lt.hpp:226
ShapeFinder2 classifier factory object.
Definition: classifier_factory.hpp:27
std::unique_ptr< Classifier > Learn(const ImagePlane &plane, Point2D< double > position, Rect< int > teachWindow, const std::vector< Point2D< int > > &dontCarePoints) const
Creates a ShapeFinder2 classifier from plane 0 of the input image.
Definition: classifier_factory.hpp:263
static std::unique_ptr< Classifier > Create(const String &fileName)
Creates a classifier object loading a classifier file.
Definition: classifier.hpp:64
Search result as returned by the classifier.
Definition: search_result.hpp:24
double Quality() const noexcept
Quality measure of the result.
Definition: search_result.hpp:77
Angle Rotation() const noexcept
Rotation angle of the result.
Definition: search_result.hpp:97
double Y() const noexcept
Y position at which the object has been found.
Definition: search_result.hpp:67
double X() const noexcept
X position at which the object has been found.
Definition: search_result.hpp:57
Stores a pair of numbers that represents the width and the height of a subject, typically a rectangle...
Definition: size_2d.hpp:20
View to display an image.
Definition: decl_image_view.hpp:75
@ ForceDisable
User disabled CUDA.
@ Default
Use CUDA if available.
PrecisionMode
Controls precision over accuracy for ShapeFinder 1 type searches.
Definition: shapefinder2.hpp:47
@ NoCorrelation
In the NoCorrelation mode, only the ShapeFinder edge model will be searched.
Cvb::String QtToCvb(const QString text) noexcept
Convenience converter for strings.
Definition: ui.hpp:238
QString CvbToQt(const Cvb::String &text) noexcept
Convenience converter for strings.
Definition: ui.hpp:253
Root namespace for the Image Manager interface.
Definition: c_barcode.h:15
void setBrush(const QBrush &brush)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
void setPos(const QPointF &pos)
void setScale(qreal factor)
void setDefaultTextColor(const QColor &col)
QMessageBox::StandardButton critical(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString & append(QChar ch)
QString number(int n, int base)