SOL9 Sample: ObjectDetectionByCascadeClassifierWithPopupMenu
|
1 Screenshot
2 Source code
/*
* ObjectDetectionByCascadeClassifierWithPopupMenu.cpp
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*/
#define _CONSOLE_
#include <sol/ModuleFileName.h>
#include <sol/DropFiles.h>
#include <sol/PopupMenu.h>
#include <sol/FolderBrowser.h>
#include <sol/Label.h>
#include <sol/ComboBox.h>
#include <sol/Profile.h>
#include <sol/StringT.h>
#include <sol/opencv/OpenCVObject.h>
#include <sol/opencv/OpenCVApplicationView.h>
#include <sol/opencv/OpenCVNamedWindow.h>
#include <sol/PushButton.h>
#include <sol/FileDialog.h>
#include <vector>
#include "Resource.h"
namespace SOL {
class MainView :public OpenCVApplicationView {
private:
////////////////////////////////////////////////////////////////////////////////////////
//Inner class starts.
class SimpleView :public OpenCVNamedWindow {
private:
StringT<char> filePath;
int loadFlag;
cv::Mat image;
void display()
{
show(image);
}
public:
SimpleView(View* parent, const char* name, Args& args)
:OpenCVNamedWindow(parent, name, args)
{
try {
const char* filename = (const char*)args.get(XmNimageFileName);
int imageLoadingFlag = (int)args.get(XmNimageLoadingFlag);
loadImage(filename, imageLoadingFlag); //"..\\images\\WafukuMannequin.png");
} catch (Exception& ex) {
caught(ex);
}
}
~SimpleView()
{
}
void loadImage(const char* filename, int flag=CV_LOAD_IMAGE_COLOR)
{
try {
filePath = filename;
loadFlag = flag;
image = readImage(filename, flag);
refresh();
} catch (Exception& ex) {
caught(ex);
}
}
void reload()
{
try {
image = readImage((const char*)filePath, loadFlag);
refresh();
} catch (Exception& ex) {
caught(ex);
}
}
void writeImage(const char* filename)
{
OpenCVNamedWindow::writeImage(filename, image);
}
void detect(const char* path)
{
try {
CascadeClassifier classifier;
classifier.load(path);
cv::vector<Rect> faces;
classifier.detectMultiScale(image, faces, 1.1, 3, 0, cv::Size(20,20));
if (faces.size() == 0) {
MessageBox(NULL, "Not detected by detectMultiScale.",
"DetectOperation", MB_OK|MB_ICONINFORMATION);
}
for (int i = 0; i < faces.size(); i++){
rectangle(image, Point(faces[i].x, faces[i].y),
Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height),
Scalar(0, 200, 0), 3, CV_AA);
}
refresh();
} catch (Exception& ex) {
caught(ex);
}
}
};
//Inner class ends
////////////////////////////////////////////////////////////////////////////////////////
StringT<char> imageFile;
StringT<char> savedImageFile;
SmartPtr<SimpleView> view;
SmartPtr<Label> label;
SmartPtr<ComboBox> comboBox;
SmartPtr<FolderBrowser> folderBrowser;
SmartPtr<PushButton> classifierButton;
SmartPtr<PushButton> reloadButton;
SmartPtr<PushButton> detectButton;
String selectedFolder;
FileDialog filedlg;
SmartPtr<PopupMenu> popupMenu;
typedef enum {
POPUP_CLEAR = 300,
POPUP_COPY,
POPUP_SAVEAS,
} POPUPMENU;
void updateCaption()
{
char caption[MAX_PATH];
sprintf_s(caption, CountOf(caption), "%s - %s",
(const char*)imageFile,
getAppName());
setText(caption);
}
void resize(int w, int h)
{
if (label && comboBox && view && detectButton && detectButton) {
classifierButton-> reshape( w-100+10, 4, 80, 28);
label -> reshape( 0, 4, 100, 28);
comboBox -> reshape( 90, 4, w-190, 120);
view -> reshape( 0, 40, w-100, h-45);
reloadButton -> reshape(w-100 + 10, 80, 80, 28);
detectButton -> reshape(w-100 + 10, 140, 80, 28);
}
}
void open(Action& action)
{
Args ar;
char dir[MAX_PATH] = {0};
//Restore previously select folder from a registry(profile of this application) for fileDialog
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);
}
}
void classifierFolder(Action& action)
{
if (folderBrowser->show(selectedFolder)) {
char pattern[MAX_PATH];
sprintf_s(pattern, sizeof(pattern), "%s\\*.xml", (const char*)selectedFolder);
comboBox->clear();
comboBox->findFiles(pattern);
comboBox->setCurSel(0);
}
}
void reload(Action& action)
{
if (view) {
view ->reload();
}
}
void detect(Action& action)
{
char path[MAX_PATH];
String filterName = comboBox->getCurrentSelection();
sprintf_s(path, sizeof(path), "%s\\%s",
(const char*)selectedFolder, (const char*)filterName);
if (view) {
view->detect(path);
}
}
void openFile(const char* filename)
{
try {
view -> loadImage(filename, CV_LOAD_IMAGE_COLOR);
imageFile = filename;
const char* fname = strrchr(filename, '\\');
if (fname) {
fname++;
}
imageFile = fname;
updateCaption();
} catch (Exception& ex) {
caught(ex);
}
}
void dropFiles(Action& action)
{
char fileName[MAX_PATH] = { 0 };
DropFiles drop((HDROP)action.getWParam());
int num = drop.queryFile(0, fileName, CountOf(fileName));
if(num > 0) {
if (filedlg.isImageFileName(fileName)) {
openFile(fileName);
bringUp();
} else {
bringUp(); //Activate and raise this view
showErrorDialog("Invalid image filename", fileName, MB_OK);
}
}
}
void mouseCallback(int event, int x, int y, int flags, void* param)
{
if(event == CV_EVENT_RBUTTONDOWN) {
if (popupMenu) {
popupMenu->track();
}
}
}
void popupClear(Action& action)
{
int rc = MessageBox(NULL, "PopupMenu calllback: clear", "Confirmation",
MB_OKCANCEL|MB_ICONEXCLAMATION);
if (rc == IDOK) {
; //Do nothing here.
}
}
void popupCopy(Action& action)
{
int rc = MessageBox(NULL, "PopupMenu callback: copy", "Confirmation",
MB_OKCANCEL|MB_ICONEXCLAMATION);
if (rc == IDOK) {
; //Do nothing here.
}
}
void popupSaveAs(Action& action)
{
Args ar;
FileDialog savedlg;
ar.set(XmNaccessMode, FileDialog::SAVE);
savedlg.create(this, "FileSave", ar);
savedlg.popup(action);
if (action.getResult()) {
char* filename = savedlg.getFileName();
view->writeImage(filename);
}
}
void confirm(Action& action)
{
int rc = MessageBox(NULL, "Are you sure to close this window?", "Confirmation",
MB_OKCANCEL|MB_ICONEXCLAMATION);
if (rc == IDOK) {
exit(action);
}
}
public:
MainView(OpenCVApplication& applet, const char* name, Args& args)
:OpenCVApplicationView(applet, name, args)
{
try {
imageFile = "..\\images\\WafukuMannequin.png";
Args ar;
label = new Label(this, "Classifier", ar);
ar.reset();
classifierButton = new PushButton(this, "...", ar);
classifierButton -> addCallback(XmNactivateCallback, this,
(Callback)&MainView::classifierFolder, NULL);
ar.reset();
ar.set(XmNstyle, CBS_SORT|CBS_DROPDOWNLIST);
comboBox = new ComboBox(this, "", ar);
ar.reset();
ar.set(XmNimageFileName, imageFile);
ar.set(XmNimageLoadingFlag, CV_LOAD_IMAGE_COLOR);
view = new SimpleView(this, "cvwindow", ar);
view -> addCallback(XmNdropCallback, this,
(Callback)&MainView::dropFiles, NULL);
addCallback(XmNmenuCallback, IDM_FILTER, this,
(Callback)&MainView::classifierFolder, NULL);
ar.reset();
reloadButton = new PushButton(this, "Reload", ar);
reloadButton -> addCallback(XmNactivateCallback, this,
(Callback)&MainView::reload, NULL);
ar.reset();
detectButton = new PushButton(this, "Detect", ar);
detectButton -> addCallback(XmNactivateCallback, this,
(Callback)&MainView::detect, NULL);
ar.reset();
ar.set(XmNstartingDirectory, "C:\\dev\\opencv3.2");
folderBrowser = new FolderBrowser(this, "FolderBrowser", ar);
ar.reset();
ar.set(XmNfilter, FileDialog::getImageFilesFilter());
filedlg.create(this, "OpenFile", ar);
//Create a popupMenu
PopupMenuItem popupMenuItems[] = {
{POPUP_CLEAR, "Clear (&X)", (Callback)&MainView::popupClear},
{POPUP_COPY, "Copy (&C)", (Callback)&MainView::popupCopy},
{POPUP_SAVEAS, "Save as (&S)", (Callback)&MainView::popupSaveAs},
};
popupMenu = new PopupMenu(this);
for (int i = 0; i<CountOf(popupMenuItems); i++) {
popupMenu->append(popupMenuItems[i].menuId, popupMenuItems[i].name);
addCallback(XmNmenuCallback, popupMenuItems[i].menuId, this,
popupMenuItems[i].callback, NULL);
}
//Add XmNmouseCallback to view.
view -> addCallback(XmNmouseCallback, this,
(MouseCallback)&MainView::mouseCallback, NULL);
addCallback(XmNmenuCallback, IDM_OPEN, this,
(Callback)&MainView::open, NULL);
addCallback(XmNmenuCallback, IDM_EXIT, this,
(Callback)&MainView::confirm, NULL);
updateCaption();
} catch (Exception& ex) {
caught(ex);
}
}
~MainView()
{
}
//2017/12/01
void save(Action& action)
{
try {
if (!savedImageFile.isEmpty()) {
//Write detected image into the filename.
view->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.
view->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, 700);
args.set(XmNheight, 500);
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.