SOL9 Sample: SimpleBlobDetector
|
1 Screenshot
2 Source code
/*
* SimpleBlobDetector.cpp
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*/
//2017/12/01 Added save, saveAs methods to MainView.
#define _CONSOLE_
#include <sol/StringT.h>
#include <sol/LabeledTrackBar.h>
#include <sol/opencv/OpenCVApplicationView.h>
#include <sol/opencv/OpenCVImageView.h>
#include <sol/FileDialog.h>
namespace SOL {
class MainView :public OpenCVApplicationView {
private:
///////////////////////////////////////////////
//Inner classes start.
class OriginalImageView: public OpenCVImageView {
private:
cv::Mat originalImage;
cv::Mat& getMat()
{
return originalImage;
}
virtual void display()
{
show(originalImage);
}
public:
OriginalImageView(View* parent, const char* name, Args& args)
:OpenCVImageView(parent, name, args)
{
try {
const char* filename = (const char*)args.get(XmNimageFileName);
int imageLoadingFlag = args.get(XmNimageLoadingFlag);
loadImage(filename, imageLoadingFlag);
} catch (SOL::Exception ex) {
caught(ex);
}
}
~OriginalImageView()
{
}
void loadImage(const char* filename,
int imageLoadingFlag= CV_LOAD_IMAGE_COLOR)
{
originalImage = readImage(filename, imageLoadingFlag);
refresh();
}
};
class DetectedImageView: public OpenCVImageView {
private:
cv::Mat originalImage;
cv::Mat grayScaleImage;
cv::Mat detectedImage;
cv::Mat& getMat()
{
return detectedImage;
}
//The scaled image is displayed on this image view.
virtual void display()
{
show(detectedImage);
}
public:
DetectedImageView(View* parent, const char* name, Args& args)
:OpenCVImageView(parent, name, args)
{
try {
const char* filename = (const char*)args.get(XmNimageFileName);
int imageLoadingFlag = args.get(XmNimageLoadingFlag);
loadImage(filename, imageLoadingFlag);
} catch (SOL::Exception ex) {
caught(ex);
}
}
~DetectedImageView()
{
}
void loadImage(const char* filename,
int imageLoadingFlag= CV_LOAD_IMAGE_COLOR)
{
originalImage = readImage(filename, imageLoadingFlag);
cv::cvtColor(originalImage, grayScaleImage, cv::COLOR_BGR2GRAY);
detectedImage = grayScaleImage.clone();
refresh();
}
void detect(int minDist, int minArea,
int maxArea)
{
try {
cv::SimpleBlobDetector::Params params;
params.thresholdStep = 10.0;
params.minThreshold = 50.0;
params.maxThreshold = 220.0;
params.filterByArea = true;
params.minArea = minArea;
params.maxArea = maxArea;
params.filterByColor = true;
params.blobColor = 0;
params.filterByCircularity = true;
params.minCircularity = 0.5;
params.filterByConvexity = true;
params.minConvexity = 0.8;
params.filterByInertia = true;
params.minInertiaRatio = 0.1;
params.minRepeatability = 2.0;
params.minDistBetweenBlobs= 5.0;
params.minDistBetweenBlobs= (double)minDist;
Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
std::vector<KeyPoint> keypoints;
detector->detect(grayScaleImage, keypoints);
drawKeypoints(grayScaleImage, keypoints,
detectedImage, CV_RGB(255, 0, 0),
DrawMatchesFlags::DRAW_RICH_KEYPOINTS );
refresh();
} catch (cv::Exception& ex) {
}
}
};
//Inner classes end.
private:
StringT<char> imageFile;
StringT<char> savedImageFile;
int imageLoadingFlag;
SmartPtr<OriginalImageView> originalImage;
SmartPtr<DetectedImageView> detectedImage;
static const int TEMPLATE_WINDOW_SIZE_MAX = 31;
int minAreaSize; //7
SmartPtr<LabeledTrackBar> minAreaSizeTrackBar;
static const int SEARCH_WINDOW_SIZE_MAX = 31;
int maxAreaSize; //21
SmartPtr<LabeledTrackBar> maxAreaSizeTrackBar;
static const int H_PARAMETER_MAX = 31;
int minDistBetweenBlobs; //3
SmartPtr<LabeledTrackBar> minDistBetweenBlobsTrackBar;
FileDialog filedlg;
public:
void minAreaSizeScrolled(Action& action)
{
minAreaSize = minAreaSizeTrackBar->getPosition();
detectedImage -> detect(minDistBetweenBlobs, minAreaSize,
maxAreaSize);
}
void maxAreaSizeScrolled(Action& action)
{
maxAreaSize = maxAreaSizeTrackBar->getPosition();
detectedImage -> detect(minDistBetweenBlobs, minAreaSize,
maxAreaSize);
}
void minDistBetweenBlobsScrolled(Action& action)
{
minDistBetweenBlobs = minDistBetweenBlobsTrackBar->getPosition();
detectedImage -> detect(minDistBetweenBlobs, minAreaSize,
maxAreaSize);
}
void updateCaption()
{
char caption[1024];
sprintf_s(caption, CountOf(caption), "%s - %s", (const char*)imageFile,
getAppName());
setText(caption);
}
void openFile(const char* filename)
{
try {
imageFile = filename;
//originalImage->invalidate();
originalImage->loadImage(filename, imageLoadingFlag);
//originalImage->invalidate();
detectedImage ->loadImage(filename, imageLoadingFlag);
detectedImage -> detect(minDistBetweenBlobs, minAreaSize,
maxAreaSize);
updateCaption();
} catch (SOL::Exception& ex) {
caught(ex);
}
}
void resize(int w, int h)
{
int CP_WIDTH = 260;
int ww = w-CP_WIDTH;
if (originalImage && detectedImage && minDistBetweenBlobsTrackBar &&
minAreaSizeTrackBar && maxAreaSizeTrackBar) {
originalImage-> reshape(0, 0, ww/2, h);
detectedImage -> reshape(ww/2, 0, ww/2-1, h);
minDistBetweenBlobsTrackBar -> reshape(ww+1, 0, CP_WIDTH-2, 50);
minAreaSizeTrackBar -> reshape(ww+1, 60, CP_WIDTH-2, 50);
maxAreaSizeTrackBar -> reshape(ww+1, 120, CP_WIDTH-2, 50);
}
}
void open(Action& action)
{
Args ar;
char dir[MAX_PATH] = { 0 };
if (restoreFileFolder(dir, CountOf(dir))) {
ar.set(XmNdirectory, dir);
filedlg.setValues(ar);
}
try {
if(filedlg.open()) {
const char* filename = filedlg.getFileName();
saveFileFolder(filename);
openFile(filename);
}
} catch (Exception& ex) {
caught(ex);
}
}
public:
MainView(OpenCVApplication& applet, const char* name, Args& args)
:OpenCVApplicationView(applet, name, args)
{
imageFile = "../images/cat.jpg";
imageLoadingFlag = CV_LOAD_IMAGE_COLOR;
try {
Args ar;
ar.reset();
ar.set(XmNimageFileName, (const char*)imageFile);
ar.set(XmNimageLoadingFlag, imageLoadingFlag);
originalImage = new OriginalImageView(this, "", ar);
ar.reset();
ar.set(XmNimageFileName, (const char*)imageFile);
ar.set(XmNimageLoadingFlag, imageLoadingFlag);
detectedImage = new DetectedImageView(this, "", ar);
//3 Create a minDistBetweenBlobsTrackBar.
minDistBetweenBlobs = 9;
ar.reset();
ar.set(XmNminimum, 5);
ar.set(XmNmaximum, 100);
ar.set(XmNposition, minDistBetweenBlobs);
minDistBetweenBlobsTrackBar = new LabeledTrackBar(this, "MinDistanceBetweenBlob", ar);
minDistBetweenBlobsTrackBar -> addCallback(XmNtrackBarScrollCallback, this,
(Callback)&MainView::minDistBetweenBlobsScrolled, NULL);
//4 Create a minAreaSizeTrackBar.
minAreaSize = 15;
ar.reset();
ar.set(XmNminimum, 1);
ar.set(XmNmaximum, 100);
ar.set(XmNposition, minAreaSize);
minAreaSizeTrackBar = new LabeledTrackBar(this, "MinArea", ar);
minAreaSizeTrackBar -> addCallback(XmNtrackBarScrollCallback, this,
(Callback)&MainView::minAreaSizeScrolled, NULL);
//5 Create a maxAreaSizeTrackBar.
maxAreaSize = 130;
ar.reset();
ar.set(XmNminimum, 100);
ar.set(XmNmaximum, 2000);
ar.set(XmNposition, maxAreaSize);
maxAreaSizeTrackBar = new LabeledTrackBar(this, "MaxArea", ar);
maxAreaSizeTrackBar -> addCallback(XmNtrackBarScrollCallback, this,
(Callback)&MainView::maxAreaSizeScrolled, NULL);
detectedImage -> detect(minDistBetweenBlobs, minAreaSize,
maxAreaSize);
updateCaption();
ar.reset();
ar.set(XmNfilter, FileDialog::getImageFilesFilter());
filedlg.create(this, "OpenFile", ar);
postResizeRequest();
} catch(SOL::Exception& ex) {
caught(ex);
}
}
~MainView()
{
}
//2017/12/01
void save(Action& action)
{
try {
if (!savedImageFile.isEmpty()) {
//Write detected image into the filename.
detectedImage->writeImage(savedImageFile);
} else {
saveAs(action);
}
} catch (Exception& ex) {
caught(ex);
}
}
//2017/12/01
void saveAs(Action& action)
{
Args ar;
char dir[MAX_PATH] = { 0 };
if (restoreFileFolder(dir, CountOf(dir))) {
ar.set(XmNdirectory, dir);
filedlg.setValues(ar);
}
try {
if(filedlg.save()) {
const char* filename = filedlg.getFileName();
saveFileFolder(filename);
//Write detected image into the filename.
detectedImage->writeImage(filename);
savedImageFile = filename;
}
} catch (Exception& ex) {
caught(ex);
}
}
};
}
//
void main(int argc, char** argv)
{
try {
ModuleFileName module(argv[0]);
const char* name = module.getAppName();
OpenCVApplication applet(name, argc, argv);
Args args;
args.set(XmNwidth, 940);
args.set(XmNheight, 380);
MainView view(applet, name, args);
view.realize();
applet.run();
} catch (SOL::Exception& ex) {
caught(ex);
}
}
Last modified: 2 Dec. 2017
Copyright (c) 2017 Antillia.com ALL RIGHTS RESERVED.