SOL9 Sample: CustomYoloObjectDetector

SOL9 2.0 Samples

1 Screenshot











2 Source code

/*
 * CustomYoloObjectDetector.cpp 
 * Copyright (c) 2019 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


//2019/05/27 
//2019/06/13 Updated to use OUTPUT_FOLDER in CustomYoloObjectDetector.ini to specify a foldername in which 
// detected_image.jpg and detail_information.csv files are saved


#define _CONSOLE_
#define USE_STD

#define  OPENCV

#include <sol/yolo3/Detector3.h>

#include <sol/ModuleFileName.h>
#include <sol/DropFiles.h>

#include <sol/ListView.h>
#include <sol/StringList.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 "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 setImage(cv::Mat mat)
    {
      this->image = mat;
      refresh();
    }
  
    void writeImage(const char* filename)
    {
      OpenCVNamedWindow::writeImage(filename, image);
    }
  };
  //Inner class endss
  ////////////////////////////////////////////////////////////////////////////////////////

  StringT<char>           imageFile;
  StringT<char>           savedImageFile;
  SmartPtr<Detector3>      detector;
  
  SmartPtr<SimpleView>    view;
  SmartPtr<ListView>      listv;

  SmartPtr<PushButton>    reloadButton;
  SmartPtr<PushButton>    detectButton;
  String                  selectedFolder;
  std::string             darknet_root;
  std::string             cfg_filename;
  std::string             coco_filename;
  std::string             weight_filename;
  
  std::vector<std::string>       class_names;
  FileDialog              filedlg;
  Profile                 profile;

 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 (view && listv && detectButton  && reloadButton) {
      view            -> reshape(         0,  40,  w-310, h-45);
      reloadButton    -> reshape(10,       4,     80,   28);
      detectButton    -> reshape(100 + 10, 4,     80,   28);
      listv           -> reshape(w-305,  40, 300, h-45);
    }
  }

  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 (profile.getFileFolder(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 reload(Action& action)
  {
    if (view) {
      view ->reload(); 
    }
  }
  

  void detect(Action& action)
  {
    std::string filename((const char*)imageFile);
    printf("filename %s\n", (const char*)imageFile);
    const char* name = (const char*)imageFile;
    const char* bslash = strrchr((const char*)imageFile,'\\');
    if (bslash) {
      name = ++bslash;
    }
    //2019/06/18
    std::string save_image_filename = std::string(name) + ".saved";
    printf("save_image_filename %s\n", save_image_filename.c_str());

    std::string csv_filename = std::string(name) + ".csv";
    printf("csv_filename %s\n", csv_filename.c_str());
    
    //2019/06/18
    image image = detector->detect_image(filename.c_str(), save_image_filename.c_str(), csv_filename.c_str());

    cv::Mat mat = detector->image_to_mat(image);
    cv::Mat mbgr;
    cv::cvtColor(mat, mbgr, cv::COLOR_RGB2BGR);
    free_image(image);
    view->setImage(mbgr);
    
    listv->readCSVFile(csv_filename.c_str(), True);
    
  }


  void openFile(const char* filename)
  {
    try {
      listv-> clear();
      
      view -> loadImage(filename, CV_LOAD_IMAGE_COLOR);
      imageFile = filename;
      /*const char* fname = strrchr(filename, '\\');
      if (fname) {
        fname++;
      }
      
      imageFile = fname;
      */
      updateCaption();
  
      savedImageFile = "";
      
    } 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 confirm(Action& action)
  {
    int rc = MessageBox(NULL, "Are you sure to close this window?", "Confirmation", 
                MB_OKCANCEL|MB_ICONEXCLAMATION);
    if (rc == IDOK) {
      exit(action);
    }
  }


  const char** getListViewHeader(int& number)
  {
    static const char* LISTVIEW_HEADER[] = {"id ", "object ", "score", "  x ", "  y ", "  w ", "  h "};
    number = CountOf(LISTVIEW_HEADER);
    return LISTVIEW_HEADER;
  }

  
  void readIniFile()
  {
    // Read some YOLO configuration file names from the ini file ".\\YoloObjectDetector.ini".
    char buffer[256] = { 0 };
    
    const char* inifile = ".\\CustomYoloObjectDetector.ini";
    GetPrivateProfileString("DARKNET_ROOT","filename", "", buffer, sizeof(buffer), inifile);
    darknet_root    = buffer;
    printf("DARKNET_ROOT:%s\n", buffer);

    
    GetPrivateProfileString("CFG_FILE",    "filename", "", buffer, sizeof(buffer), inifile);
    cfg_filename    = buffer;
    printf("CFG_FILE:%s\n", buffer);
    
    GetPrivateProfileString("WEIGHT_FILE", "filename", "", buffer, sizeof(buffer), inifile);
    weight_filename = buffer;
    printf("WEIGHT_FILE:%s\n", buffer);
    
    GetPrivateProfileString("COCO_FILE",   "filename", "", buffer, sizeof(buffer), inifile);
    coco_filename   = buffer;
    printf("COCO_FILE:%s\n", buffer);
    
  }


public:
  MainView(OpenCVApplication& applet, const char* name, Args& args)
  :OpenCVApplicationView(applet, name, args)
  {
    
    try {
      //Default image file name
      imageFile = "..\\..\\images\\PoliceCar.jpg";

      readIniFile();

      detector = new Detector3( darknet_root, 
                                cfg_filename, 
                                weight_filename,
                                coco_filename);
      Args 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);
      
      ar.reset();
      ar.set(XmNexStyle, (LONG_PTR)WS_EX_CLIENTEDGE);
      ar.set(XmNstyle, (LONG_PTR)LVS_REPORT);

      listv = new ListView(this, "objects", ar);

      StringList header;
      int number = 0;
      const char** strings = getListViewHeader(number);
      for (int i = 0; i<number; i++) {
        header.add(strings[i]); 
      }
      
      listv->clear();
      listv->setColumn(&header);
       
      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(XmNfilter, FileDialog::getImageFilesFilter());
      filedlg.create(this, "OpenFile", ar);
    
      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()
  {
  }
  

  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,  1000);
    args.set(XmNheight, 500);
    MainView view(applet, name, args);
    view.realize();

    applet.run();
    
  } catch (SOL::Exception& ex) {
    caught(ex);
  }
}


Last modified: 18 Jun. 2019

Copyright (c) 2019 Antillia.com ALL RIGHTS RESERVED.