| OZ++ Class: OpenCVImageView |
/******************************************************************************
*
* Copyright (c) 2017 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* OpenCVImageView.h
*
*****************************************************************************/
#pragma once
#include <oz++/Exception.h>
#include <oz++/motif/Pixelmap.h>
#include <oz++/motif/Canvas.h>
#include <oz++/opencv/OpenCVImageConverter.h>
namespace OZ {
class OpenCVImageView: public Canvas {
private:
Pixmap pixmap;
cv::Mat rgbImage;
public:
//Please redefine a virtual display method in your own class
//derived from this OpenView class.
virtual void display()
{
printf("OpenImageView::display\n");
}
virtual void scaleImage(cv::Mat& originalImage, cv::Mat& scaledImage,
int scalingRatio)
{
try {
if (scalingRatio < 1) {
scalingRatio = 10;
}
float ratio = (float)scalingRatio/100.0f;
cv::resize(originalImage, scaledImage, cv::Size(),
ratio, ratio);
//2017/05/18
invalidate();
refresh();
//
} catch (cv::Exception& ex) {
;
}
}
void resizeToImageSize(cv::Mat& image)
{
if (!image.empty()) {
Dimension w = image.cols;
Dimension h = image.rows;
resize(w, h);
}
}
cv::Mat readImage(const char* filename, int loadingFlag)
{
cv::Mat image = imread(filename, loadingFlag);
if (image.empty()) {
throw IException("Failed to imread: %s", filename);
}
return image;
}
void invalidate()
{
pixmap = None;
rgbImage.release();
}
void show(cv::Mat& mat)
{
if (!mat.empty()) {
if (pixmap == None) {
dprintf("show d =%d c=%d\n", mat.depth(), mat.channels());
if ( mat.channels() == 1) {
// if mat is grayscale, we convert to rgbImage
dprintf("Convert grayscale image to rgb image\n");
rgbImage.release();
cvtColor(mat, rgbImage, CV_GRAY2RGB);
pixmap = OpenCVImageConverter::convertToPixmap(this, rgbImage);
} else if ( mat.channels() ==3) {
// mat is rgbImage
pixmap = OpenCVImageConverter::convertToPixmap(this, mat);
} else {
throw IException("Unsupported cv::Mat image");
}
}
if (pixmap != None) {
DC dc(this);
Display* display = dc.getDisplay();
Drawable src = pixmap;
Drawable dst = dc.getDrawable();
GC gc = dc.getGC();
dc.copyArea(src, 0, 0, width(), height(), 0, 0);
//flush(); //XFlush
}
}
}
virtual void expose(Action& action)
{
//Call a virtual display method to display OpenGL figures.
display();
//flush(); //XFlush
}
void reshape(int x, int y, int w, int h)
{
View::resize(x, y, w, h, 0);
}
public:
OpenCVImageView(View* parent, const char* name, Args& args)
:Canvas(parent, name, args.set(XmNtraversalOn,False))
,pixmap(None)
{
}
~OpenCVImageView()
{
rgbImage.release();
}
virtual void save(const char* filename, const cv::Mat& image)
{
if (!image.empty()) {
if (!imwrite(filename, image)) {
throw IException("Failed to write image file: %s", filename);
}
}
}
void rescale(cv::Mat& image, cv::Mat& scaledImage, int scalingRatio)
{
if (scalingRatio < 1) {
scalingRatio = 10;
}
float ratio = (float)scalingRatio/100.0f;
cv::resize(image, scaledImage, cv::Size(),
ratio, ratio);
}
void refresh()
{
sendExposeEvent();
}
};
}