3.3.26 ImageSharpening

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 OpenCVImageView.

  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.

#include <oz++/motif/Label.h>
#include <oz++/motif/RowColumn.h>
#include <oz++/motif/LabeledTrackBar.h>
#include <oz++/opencv/OpenCVScaleComboBox.h>
#include <oz++/opencv/OpenCVMainView.h>
#include <oz++/opencv/OpenCVImageView.h>
#include <oz++/motif/FileOpenDialog.h>

namespace OZ {

class MainView :public OpenCVMainView {

private:
  ///////////////////////////////////////////////
  //Inner classes start.
  class OriginalImageView: public OpenCVImageView {
  private:
    cv::Mat originalImage; 
    cv::Mat scaledImage;
    
    virtual void display()
    {
       show(scaledImage);
    }
 
  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);
        int scalingRatio = (int)args.get(XmNimageScalingRatio);

        loadImage(filename, imageLoadingFlag, scalingRatio);
 
      } catch (OZ::Exception ex) {
        caught(ex);
      }
    } 

    ~OriginalImageView()
    {
    }
    
    void loadImage(const char* filename, 
        int imageLoadingFlag= CV_LOAD_IMAGE_COLOR,
                int scalingRatio=100)
    {
      try {
        originalImage = readImage(filename, imageLoadingFlag);
        scaleImage(originalImage, scaledImage, scalingRatio);
      } catch (OZ::Exception& ex) {
        caught(ex);
      }
    }    

    void rescale(int scalingRatio)
    {
      scaledImage.release();
      scaleImage(originalImage, scaledImage, scalingRatio);
    }
  };

  class SharpenedImageView: public OpenCVImageView {
  private:
    cv::Mat originalImage; 
    cv::Mat sharpenedImage; 
    cv::Mat scaledImage;

    //The scale image is displayed on this image view.
    virtual void display()
    {
       show(scaledImage);
    }
 
  public:
    SharpenedImageView(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);

        int scalingRatio = (int)args.get(XmNimageScalingRatio);
        loadImage(filename, imageLoadingFlag, scalingRatio);

      } catch (OZ::Exception ex) {
        caught(ex);
      }
    } 

    ~SharpenedImageView()
    {
    }
    
    void loadImage(const char* filename, 
        int imageLoadingFlag= CV_LOAD_IMAGE_COLOR,
                int scalingRatio=100)
    {
      try {
        originalImage = readImage(filename, imageLoadingFlag);
        sharpenedImage  = originalImage.clone();
        
      } catch (OZ::Exception& ex) {
        caught(ex);
      }
    }    

    void rescale(int scalingRatio)
    {
      scaledImage.release();
      scaleImage(sharpenedImage, scaledImage, scalingRatio);
    }

    void sharpen(int ksize, int sigma, int scalingRatio)
    {
      ksize = (ksize/2)*2 + 1;
      //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);
      
      sharpenedImage = newImage;
      scaleImage(sharpenedImage, scaledImage, scalingRatio);
    }
  };
  //Inner classes end.
    
private:

  StringT<char>                imageFile;
  int                          imageLoadingFlag;
  int                          imageScalingRatio; //percentage 

  SmartPtr<Label>              label;
  SmartPtr<OriginalImageView>  originalImage;
  SmartPtr<SharpenedImageView>   sharpenedImage;
  SmartPtr<RowColumn>          controlPane;
  SmartPtr<OpenCVScaleComboBox>  scaleComboBox;

  SmartPtr<LabeledTrackBar>    ksizeTrackBar;
  int                          ksize;

  SmartPtr<LabeledTrackBar>    sigmaTrackBar;
  int                          sigma;

  SmartPtr<FileOpenDialog>     fileDialog;

public:
  void scaleChanged(Action& action)
  {
    int val = scaleComboBox->getScale();

    if (val > 0 && imageScalingRatio != val) {
      imageScalingRatio = val;
      originalImage -> rescale(imageScalingRatio); 
      sharpenedImage -> rescale(imageScalingRatio); 
    }
  }  

  void ksizeChanged(Action& action)
  {
    ksize = (int)ksizeTrackBar->get(XmNvalue);
    printf("ksizeChanged ksize=%d\n", ksize);
    sharpenedImage -> sharpen(ksize, sigma, imageScalingRatio);
  }

  void sigmaChanged(Action& action)
  {
    sigma = sigmaTrackBar->get(XmNvalue);
    printf("sigmaChanged sigma=%d\n", sigma);
    
    sharpenedImage -> sharpen(ksize, sigma, imageScalingRatio);
  }

  void cancel(Action& action)
  {
    fileDialog->popdown();
  }

  void fileOpen(Action& action)
  {
    fileDialog->popup();
  }

  void updateLabel(const char* filename)
  {
     CompoundString cs(filename);
     label->set(XmNlabelString, cs);    
  }

  void ok(Action& action)
  {
    try {  
      imageFile  = fileDialog->getFileName();
      const char* filename = (const char*)imageFile;
      printf("filename: %s\n", filename);
      fileDialog->popdown();
    
      originalImage->invalidate();
      originalImage->loadImage(filename, 
        imageLoadingFlag, imageScalingRatio);

      originalImage->invalidate();
      sharpenedImage ->loadImage(filename, 
        imageLoadingFlag, imageScalingRatio); 

      sharpenedImage -> sharpen(ksize, sigma, imageScalingRatio);

      updateLabel(filename);

      resize(width(), height());
      flush();
    } catch (OZ::Exception& ex) {
       caught(ex);
    } 
  }

  void resize(Dimension w, Dimension h)
  {
    int CP_WIDTH = 200;
    int LB_HEIGHT = 30;
    int ww =  w-CP_WIDTH;
    int hh = h - LB_HEIGHT;
    if (label && originalImage && sharpenedImage && controlPane 
     ) {
      label        -> reshape(0, 0, w, LB_HEIGHT); 
      originalImage-> reshape(0, LB_HEIGHT, ww/2, hh);
      sharpenedImage -> reshape(ww/2, LB_HEIGHT, ww/2-1, hh);
     
      controlPane  -> reshape(ww-1, LB_HEIGHT, CP_WIDTH+1, hh);

      //The following two lines are a workaround to erase garbage.
      controlPane -> unmap();
      controlPane -> map();
    }

    flush();
  }

public:
  MainView(OpenCVApplication& applet, const char* name, Args& args)
  :OpenCVMainView(applet, name, args) 
  {
    BulletinBoard* bboard = getBulletinBoard();
    imageFile = "../images/YellowFlower.png";
    imageLoadingFlag = CV_LOAD_IMAGE_COLOR;
    imageScalingRatio = 60; //%

    try {
      Args ar;
      CompoundString fileNamecs((const char*)imageFile);
      ar.set(XmNlabelString, fileNamecs); 
      ar.set(XmNalignment, XmALIGNMENT_BEGINNING); 
      label = new Label(bboard, "", ar);

      ar.reset();
      ar.set(XmNimageFileName, (const char*)imageFile);
      ar.set(XmNimageLoadingFlag, imageLoadingFlag);
      ar.set(XmNimageScalingRatio, imageScalingRatio);

      originalImage = new OriginalImageView(bboard, "", ar);

      ar.reset();
      ar.set(XmNimageFileName, (const char*)imageFile);
      ar.set(XmNimageLoadingFlag, imageLoadingFlag);
      ar.set(XmNimageScalingRatio, imageScalingRatio);

      sharpenedImage   = new SharpenedImageView(bboard, "", ar);

      ar.reset();
      controlPane = new RowColumn(bboard, "", ar);
      const char* defaultScale = "60%";

      ar.reset();
      CompoundString scaler("Scale");
      ar.set(XmNlabelString, scaler);
      ar.set(XmNdefaultScale, defaultScale);
      scaleComboBox = new OpenCVScaleComboBox(controlPane, "", ar);
      scaleComboBox->addCallback(XmNselectionCallback, this,
        (Callback)&MainView::scaleChanged, NULL);

      ksize = 7;
      ar.reset();
      CompoundString ksizecs("KernelSize[0,31]");
      ar.set(XmNlabelString, scaler);
      ar.set(XmNminimum, 0);
      ar.set(XmNmaximum,  31);
      ar.set(XmNvalue,    ksize); 
      ar.set(XmNtitleString, ksizecs);
      ksizeTrackBar = new LabeledTrackBar(controlPane, "", ar);
      //ksizeTrackBar->addCallback(XmNdragCallback, this,
      ksizeTrackBar->addCallback(XmNvalueChangedCallback, this,
        (Callback)&MainView::ksizeChanged, NULL);

      ar.reset();
      CompoundString sigmacs("Sigma[0,20]");
      sigma = 12;
      ar.set(XmNlabelString, scaler);
      ar.set(XmNminimum, 0);
      ar.set(XmNmaximum, 20);
      ar.set(XmNvalue,   sigma );
      ar.set(XmNtitleString, sigmacs);
      sigmaTrackBar = new LabeledTrackBar(controlPane, "", ar);
      //sigmaTrackBar->addCallback(XmNdragCallback, this,
      sigmaTrackBar->addCallback(XmNvalueChangedCallback, this,
        (Callback)&MainView::sigmaChanged, NULL);

      sharpenedImage -> sharpen(ksize, sigma, imageScalingRatio);

      ar.reset();
      fileDialog = new FileOpenDialog(this, "FileOpenDialog", ar);
      fileDialog  -> getOkButton()
                  -> addCallback(XmNactivateCallback, this,
                          (Callback)&MainView::ok, NULL); 
      sendConfigureEvent(); 
    } catch(OZ::Exception& ex) {
      caught(ex);
    }
  }

  ~MainView()
  {
  }
};

}

//
int main(int argc, char** argv) 
{
  try {
    const char*  appclass = argv[0];
    OpenCVApplication applet(appclass, argc, argv);

    Args args;
    args.set(XmNwidth,  900);
    args.set(XmNheight, 380);
    MainView view(applet, argv[0], args);
    view.realize();

    applet.run();
    
  } catch (OZ::Exception& ex) {
    caught(ex);
  }
  return 0;
}




Last modified: 1 June 2017

 Last modified: 1 June 2017

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