4.22 How to sharpen an image in OpenCV?

The following ImageSharpening is a simple example to sharpen an slightly blurred building image.
The left pane is an original image, and the right pane is a sharpened image created by manipulating KernelSize and Sigma trackbar controls.

In this example, we sharpen an image by using the following two OpenCV APIs in blur method of BlurredImageView class derived from OpenCVNamedWindow.

  void GaussianBlur(const Mat& src, Mat& dst, Size ksize, 
            double sigmaX, 
            double sigmaY  = 0, 
            int borderType = BORDER_DEFAULT);
                  
  void addWeighted(InputArray src1, double alpha, InputArray src2, 
           double beta, double gamma, OutputArray dst, int dtype=-1)





/*
 * ImageSharpening.cpp 
 * Copyright (c) 2017 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */

//2017/03/30
// See: "http://docs.opencv.org/2.4/doc/tutorials/core/adding_images/adding_images.html"
//  Adding (blending) two images using OpenCV

#define _CONSOLE_

#include <sol/ModuleFileName.h>
#include <sol/Label.h>
#include <sol/TrackBar.h>
#include <sol/FileDialog.h>
#include <sol/opencv/OpenCVApplicationView.h>
#include <sol/opencv/OpenCVNamedWindow.h>

namespace SOL {

class MainView :public OpenCVApplicationView {

private:
  ////////////////////////////////////////////////////////////////////////////////////////
  //Inner class starts.
  class OriginalImageView :public OpenCVNamedWindow {
  private:
    cv::Mat originalImage;
    
    void display()
    {
      show(originalImage);
    }
    
  public:
    OriginalImageView(View* parent, const char* name, Args& args)
    :OpenCVNamedWindow(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)
    {
      try {
        originalImage = readImage(filename, imageLoadingFlag);
      refresh();

      } catch (Exception& ex) {
        caught(ex);
      }
    }
    
  };
  
  class BlurredImageView :public OpenCVNamedWindow {
  private:
    cv::Mat originalImage;
    cv::Mat blurredImage;
    
    void display()
    {
      show(blurredImage);
    }
    
  public:
    BlurredImageView(View* parent, const char* name, Args& args)
    :OpenCVNamedWindow(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);
      }
    }
    
    ~BlurredImageView()
    {
    }
    
    void loadImage(const char* filename, int imageLoadingFlag= CV_LOAD_IMAGE_COLOR)
    {
      try {
        originalImage = readImage(filename, imageLoadingFlag);
        blurredImage = originalImage;
      } catch (Exception& ex) {
        caught(ex);
      }
    }
    
    void blur(int ksize, int sigma)
    {
      //void GaussianBlur(const Mat& src, Mat& dst, Size ksize, 
      //       double sigmaX, 
      //       double sigmaY  = 0, 
      //       int borderType = BORDER_DEFAULT)
      cv::Mat newImage = cv::Mat::zeros(originalImage.size(), originalImage.type() );
      cv::GaussianBlur(originalImage, newImage, cv::Size(ksize, ksize), 
            (double)sigma, //sigmaX, 
            (double)sigma, //sigmaY
            BORDER_DEFAULT);
      
      // void addWeighted(InputArray src1, double alpha, InputArray src2, 
      //             double beta, double gamma, OutputArray dst, int dtype=-1)
      double alpha = 2.5;
      double beta  = 1.0 - alpha;
      cv::addWeighted(originalImage, alpha, newImage, beta, 0.0, newImage);
      
      blurredImage = newImage;
      refresh();
    }
  };
  //Inner class ends.
  ////////////////////////////////////////////////////////////////////////////////////////
  
  
  StringT<char>        imageFile;
  
  SmartPtr<OriginalImageView>  originalImage;
  SmartPtr<BlurredImageView> blurredImage;
    
  SmartPtr<Label>       ksizeLabel;
  SmartPtr<TrackBar>    ksizeTrackBar;
  SmartPtr<Label>       sigmaLabel;  
  SmartPtr<TrackBar>    sigmaTrackBar;
  FileDialog            filedlg;
  Profile               profile;

  void updateCaption(int ksize, int sigma)
  {
    char caption[1024];
    sprintf_s(caption, CountOf(caption), "%s - %s  ksize: %d  sigma: %d", (const char*)imageFile, 
      getAppName(), 
      ksize, sigma);
    setText(caption);
  }

  //Horizontal Scroll event by TrackBars
  long horizScroll(Event& event)
  {
    int ksize = ksizeTrackBar->getPos();
    int sigma = sigmaTrackBar->getPos();

    ksize = (ksize/2)*2 +1;
    
    blurredImage -> blur(ksize, sigma);
    updateCaption(ksize, sigma);
    
    return 1;
  }
  
  void resize(int w, int h)
  {
    if (originalImage && blurredImage &&  ksizeTrackBar && sigmaTrackBar) {
      originalImage   -> reshape(2,            2,  (w-140)/2-1,    h-4);
      blurredImage    -> reshape((w-140)/2+1,  2,  (w-140)/2-1,    h-4);
      ksizeLabel      -> reshape(w-135 + 10,  10, 120, 30);
      ksizeTrackBar   -> reshape(w-135 + 10,  40, 120, 60);
      sigmaLabel      -> reshape(w-135 + 10, 110, 120, 30);
      sigmaTrackBar   -> reshape(w-135 + 10, 140, 120, 60);
    }
  }

  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\\YellowFlower.png";
      
      int  imageLoadingFlag = CV_LOAD_IMAGE_COLOR;
      Args ar;
      ar.set(XmNimageFileName, imageFile);
      ar.set(XmNimageLoadingFlag, imageLoadingFlag);
      originalImage = new OriginalImageView(this, "cvwindow1", ar); 

      ar.reset();
      ar.set(XmNimageFileName, imageFile);
      ar.set(XmNimageLoadingFlag, imageLoadingFlag);
      blurredImage = new BlurredImageView(this, "cvwindow2", ar); 

      ar.reset();
      ksizeLabel = new Label(this, "KernelSize [0, 31]", ar); 

      ar.reset();
      sigmaLabel = new Label(this, "Sigma [0, 30]", ar); 

      int ksize = 10;
      int sigma = 12;
      ar.reset();
      ar.set(XmNstyle, TBS_AUTOTICKS | TBS_ENABLESELRANGE); 
      ksizeTrackBar = new TrackBar(this, "", ar);
      ksizeTrackBar -> setRange(0, 31);
      ksizeTrackBar -> setPos(ksize);

      ar.reset();
      ar.set(XmNstyle, TBS_AUTOTICKS |TBS_ENABLESELRANGE); 
      sigmaTrackBar = new TrackBar(this, "", ar);
      sigmaTrackBar -> setRange(0, 30);
      sigmaTrackBar -> setPos(sigma);
      
      addCallback(XmNmenuCallback, IDM_EXIT, this,
          (Callback)&MainView::confirm, NULL);

      ksize = (ksize/2)*2 +1;
      blurredImage -> blur(ksize, sigma);
   
      updateCaption(ksize, sigma);  

      ar.reset();
      ar.set(XmNfilter, FileDialog::getImageFilesFilter());
      filedlg.create(this, "OpenFile", ar);
      
    } catch (Exception& ex) {
      caught(ex);
    }
  }

  ~MainView()
  {
  }

  void saveFileFolder(const char* filePath)
  {
    if (strlen(filePath)>0) {
    
      Folder folder(filePath);
      String dirOnly = "";
    
      folder.getDirectory(dirOnly);
      const char* dir = (const char*)dirOnly;
      profile.setFileFolder(dir);
    }
  }

  void open(Action& action)
  {
    Args ar;
    
    char dir[MAX_PATH] = { 0 };
    if (profile.getFileFolder(dir, CountOf(dir))) {
      ar.set(XmNdirectory, dir);
      filedlg.setValues(ar);
    }
    
    try {    
      if(filedlg.open()) {
    
        const char* filename = filedlg.getFileName();
        saveFileFolder(filename);
        
        originalImage -> loadImage(filename);
        blurredImage -> loadImage(filename);
        const char* fname = strrchr(filename, '\\');
        if (fname) {
          fname++;
        }
        imageFile = fname;

        post(WM_HSCROLL, 0, 0);
      }
    } 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,  900);
    args.set(XmNheight, 440);
    MainView view(applet, name, args);
    view.realize();

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



Last modified: 1 Apr. 2017

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