10 changed files with 524 additions and 45 deletions
			
			
		@ -0,0 +1,37 @@ | 
				
			|||
#ifndef ENHANCE_H | 
				
			|||
#define ENHANCE_H | 
				
			|||
 | 
				
			|||
#include <QObject> | 
				
			|||
#include <QMetaType> | 
				
			|||
#include "model/processor/IProcessStrategy.h" | 
				
			|||
#include "utils/OpenCLHelper.h" | 
				
			|||
 | 
				
			|||
typedef struct Enhance_t | 
				
			|||
{ | 
				
			|||
	cl_int filterWidth; | 
				
			|||
	cl_int filterHeight; | 
				
			|||
	cl_int width; | 
				
			|||
	cl_int height; | 
				
			|||
}Enhance_t; | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class Enhance : public IProcessStrategy | 
				
			|||
{ | 
				
			|||
	Q_OBJECT | 
				
			|||
public: | 
				
			|||
   Q_INVOKABLE Enhance(const Context context, const QString kernelPath, const QObject *parent); | 
				
			|||
   virtual void cpuProcess(ScenGenOutput_t parameters) override; | 
				
			|||
   virtual void finalize() override; | 
				
			|||
 | 
				
			|||
private: | 
				
			|||
   KernelFunctor<Image2D, Image2D, Buffer, Enhance_t> _kernelFunctor; | 
				
			|||
   virtual Image* processKernel(Image *frames, Buffer* scratchPad) override; | 
				
			|||
 | 
				
			|||
   Enhance_t _kernelParameters; | 
				
			|||
 | 
				
			|||
   bool _run; | 
				
			|||
 | 
				
			|||
   Buffer* _filter; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
#endif // ENHANCE_H
 | 
				
			|||
@ -0,0 +1,41 @@ | 
				
			|||
#ifndef PERSIST_H | 
				
			|||
#define PERSIST_H | 
				
			|||
 | 
				
			|||
#include <QObject> | 
				
			|||
#include <QMetaType> | 
				
			|||
#include "model/processor/IProcessStrategy.h" | 
				
			|||
#include "utils/OpenCLHelper.h" | 
				
			|||
 | 
				
			|||
#define PERSIST_MAX_SIZE	8 | 
				
			|||
 | 
				
			|||
typedef struct Persist_t | 
				
			|||
{ | 
				
			|||
	cl_int persist; | 
				
			|||
	cl_int mode; | 
				
			|||
}Persist_t; | 
				
			|||
 | 
				
			|||
 | 
				
			|||
class Persist : public IProcessStrategy | 
				
			|||
{ | 
				
			|||
	Q_OBJECT | 
				
			|||
public: | 
				
			|||
   Q_INVOKABLE Persist(const Context context, const QString kernelPath, const QObject *parent); | 
				
			|||
   virtual void cpuProcess(ScenGenOutput_t parameters) override; | 
				
			|||
   virtual void finalize() override; | 
				
			|||
 | 
				
			|||
private: | 
				
			|||
   KernelFunctor<Image2D, Image2D, Image2D, Image2D, Persist_t> _kernelFunctor; | 
				
			|||
   virtual Image* processKernel(Image *frames, Buffer* scratchPad) override; | 
				
			|||
 | 
				
			|||
   Persist_t _kernelParameters; | 
				
			|||
 | 
				
			|||
   QVector<Image*> _queue; | 
				
			|||
   Image* _imageSum; | 
				
			|||
 | 
				
			|||
   bool _reCalc; | 
				
			|||
   quint64 _lastWidth; | 
				
			|||
   quint64 _lastHeight; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
 | 
				
			|||
#endif // PERSIST_H
 | 
				
			|||
@ -0,0 +1,85 @@ | 
				
			|||
// #define TEST | 
				
			|||
#define X	95 | 
				
			|||
#define Y	22 | 
				
			|||
 | 
				
			|||
//#define USE_DBL | 
				
			|||
#ifdef USE_DBL | 
				
			|||
#define TYPE_FLT  double | 
				
			|||
#define TYPE_INT  long | 
				
			|||
#define MASK      0xFFFF | 
				
			|||
#define SHIFT     16 | 
				
			|||
#define EPSILSON  4.94065645841247E-324 | 
				
			|||
#else | 
				
			|||
#define TYPE_FLT  float | 
				
			|||
#define TYPE_INT  int | 
				
			|||
#define MASK      0x00FF | 
				
			|||
#define SHIFT     8 | 
				
			|||
#define EPSILSON  1.401298E-45 | 
				
			|||
#endif | 
				
			|||
 | 
				
			|||
constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | | 
				
			|||
                                CLK_ADDRESS_CLAMP_TO_EDGE | | 
				
			|||
                                CLK_FILTER_LINEAR; | 
				
			|||
 | 
				
			|||
 | 
				
			|||
struct input { | 
				
			|||
  int persist; | 
				
			|||
  int mode; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
TYPE_FLT read_data(image2d_t input_frame, int x, int z) | 
				
			|||
{ | 
				
			|||
  int2 gid = (int2)(x, z); | 
				
			|||
  uint4 pixel = read_imageui(input_frame, sampler, gid); | 
				
			|||
  TYPE_INT temp =  (TYPE_INT)((TYPE_INT)pixel.x & MASK) |  | 
				
			|||
                    (TYPE_INT)(((TYPE_INT)pixel.y & MASK) << SHIFT) | | 
				
			|||
                    (TYPE_INT)(((TYPE_INT)pixel.z & MASK) << (SHIFT * 2)) |  | 
				
			|||
                    (TYPE_INT)(((TYPE_INT)pixel.w & MASK) << (SHIFT * 3)); | 
				
			|||
  TYPE_FLT raw_data = *((TYPE_FLT*)(&temp)); | 
				
			|||
  return raw_data; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
 | 
				
			|||
kernel void Persist(read_only image2d_t input_frame, read_write image2d_t output_frame, read_write image2d_t sum_frame, read_write image2d_t removed_frame, struct input params)  | 
				
			|||
{ | 
				
			|||
  int2 gid = (int2)(get_global_id(0), get_global_id(1)); | 
				
			|||
  TYPE_FLT input = read_data(input_frame, gid.x, gid.y); | 
				
			|||
  TYPE_FLT output_data = 0; | 
				
			|||
  TYPE_FLT sum = 0; | 
				
			|||
 | 
				
			|||
  if(params.mode == 0) | 
				
			|||
  { | 
				
			|||
    sum = input; | 
				
			|||
  } | 
				
			|||
  else if(params.mode == 1) | 
				
			|||
  { | 
				
			|||
    sum = read_data(sum_frame, gid.x, gid.y); | 
				
			|||
    sum += input; | 
				
			|||
  } | 
				
			|||
  else if(params.mode == 2) | 
				
			|||
  { | 
				
			|||
    sum = read_data(sum_frame, gid.x, gid.y); | 
				
			|||
    sub = read_data(removed_frame, gid.x, gid.y); | 
				
			|||
    sum = sum + input - sub; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  output_data = sum / params.persist; | 
				
			|||
  | 
				
			|||
  TYPE_INT out = *((TYPE_INT*)(&output_data)); | 
				
			|||
  uint4 pixel; | 
				
			|||
  pixel.x = (TYPE_INT)(out & MASK); | 
				
			|||
  pixel.y = (TYPE_INT)((out >> SHIFT) & MASK); | 
				
			|||
  pixel.z = (TYPE_INT)((out >> (SHIFT *2)) & MASK); | 
				
			|||
  pixel.w = (TYPE_INT)((out >> (SHIFT * 3)) & MASK); | 
				
			|||
 | 
				
			|||
  write_imageui(output_frame, gid, pixel); | 
				
			|||
 | 
				
			|||
  out = *((TYPE_INT*)(&sum)); | 
				
			|||
  pixel.x = (TYPE_INT)(out & MASK); | 
				
			|||
  pixel.y = (TYPE_INT)((out >> SHIFT) & MASK); | 
				
			|||
  pixel.z = (TYPE_INT)((out >> (SHIFT *2)) & MASK); | 
				
			|||
  pixel.w = (TYPE_INT)((out >> (SHIFT * 3)) & MASK); | 
				
			|||
 | 
				
			|||
  write_imageui(sum_frame, gid, pixel); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
@ -0,0 +1,164 @@ | 
				
			|||
#include "model/processor/strategies/Enhance.h" | 
				
			|||
#include "model/processor/BIP.h" | 
				
			|||
#include <QPixmap> | 
				
			|||
#include <QImage> | 
				
			|||
 | 
				
			|||
Enhance::Enhance(const Context context, | 
				
			|||
		 const QString kernelPath, | 
				
			|||
		 const QObject *parent = Q_NULLPTR) : | 
				
			|||
	IProcessStrategy(context, kernelPath, "Enhance", parent), | 
				
			|||
	_kernelFunctor(KernelFunctor<Image2D, Image2D, | 
				
			|||
				   Buffer, Enhance_t>(_kernel)) | 
				
			|||
{ | 
				
			|||
	memset(&_kernelParameters, 0, sizeof (Enhance_t)); | 
				
			|||
	_filter = Q_NULLPTR; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void Enhance::cpuProcess(ScenGenOutput_t parameters) | 
				
			|||
{ | 
				
			|||
	if(parameters.enhance.isUpdated || parameters.enhanceAlgorithm.isUpdated) | 
				
			|||
	{ | 
				
			|||
		_run = false; | 
				
			|||
		if(parameters.enhance.value == 0) | 
				
			|||
		{ | 
				
			|||
			return; | 
				
			|||
		} | 
				
			|||
 | 
				
			|||
		float *hpf; | 
				
			|||
		int *backgroundRecovery; | 
				
			|||
 | 
				
			|||
		//sharpen
 | 
				
			|||
		if(parameters.enhanceAlgorithm.value == 0) | 
				
			|||
		{ | 
				
			|||
			auto alpha = 0.25f * (parameters.enhance.value - 1); | 
				
			|||
 | 
				
			|||
			_kernelParameters.filterWidth = 3; | 
				
			|||
			_kernelParameters.filterHeight = 3; | 
				
			|||
 | 
				
			|||
			hpf = new float[9]; | 
				
			|||
			backgroundRecovery = new int[9]; | 
				
			|||
 | 
				
			|||
			auto factor = 4 / (alpha + 1); | 
				
			|||
			int index = 0; | 
				
			|||
 | 
				
			|||
			hpf[index++] = factor * (alpha / 4); | 
				
			|||
			hpf[index++] = factor * ((1 - alpha) / 4); | 
				
			|||
			hpf[index++] = factor * (alpha / 4); | 
				
			|||
 | 
				
			|||
			hpf[index++] = factor * ((1 - alpha) / 4); | 
				
			|||
			hpf[index++] = factor * -1; | 
				
			|||
			hpf[index++] = factor * ((1 - alpha) / 4); | 
				
			|||
 | 
				
			|||
			hpf[index++] = factor * (alpha / 4); | 
				
			|||
			hpf[index++] = factor * ((1 - alpha) / 4); | 
				
			|||
			hpf[index++] = factor * (alpha / 4); | 
				
			|||
 | 
				
			|||
			index = 0; | 
				
			|||
 | 
				
			|||
			memset(backgroundRecovery, 0, 9 * sizeof (int)); | 
				
			|||
			backgroundRecovery[4] = 1; | 
				
			|||
 | 
				
			|||
			_run = true; | 
				
			|||
		} | 
				
			|||
		//log
 | 
				
			|||
		else if(parameters.enhanceAlgorithm.value == 1) | 
				
			|||
		{ | 
				
			|||
			_kernelParameters.filterWidth = 5; | 
				
			|||
			_kernelParameters.filterHeight = 5; | 
				
			|||
 | 
				
			|||
			hpf = new float[25]; | 
				
			|||
			backgroundRecovery = new int[25]; | 
				
			|||
 | 
				
			|||
			auto sigma = 0.5f + 0.25f * (parameters.enhance.value - 1); | 
				
			|||
			float sumHg = 0; | 
				
			|||
			float h[25]; | 
				
			|||
 | 
				
			|||
			for(int i = -2; i <= 2; i++) | 
				
			|||
			{ | 
				
			|||
				for(int j = -2; j <= 2; j++) | 
				
			|||
				{ | 
				
			|||
					float temp = expf(-(powf(i, 2) + powf(j, 2)) | 
				
			|||
													 / 2 / powf(sigma, 2)); | 
				
			|||
					h[(i + 2) * 5 + (j + 2)] = (powf(i, 2) + powf(j, 2) - 2 * powf(sigma, 2)) * | 
				
			|||
							temp; | 
				
			|||
 | 
				
			|||
					sumHg += temp; | 
				
			|||
				} | 
				
			|||
			} | 
				
			|||
 | 
				
			|||
			for(int i = 0; i < 25 ; i++) | 
				
			|||
			{ | 
				
			|||
				hpf[i] = h[i] / powf(sigma, 4) / sumHg; | 
				
			|||
			} | 
				
			|||
 | 
				
			|||
			memset(backgroundRecovery, 0, 25 * sizeof (int)); | 
				
			|||
			backgroundRecovery[12] = 1; | 
				
			|||
 | 
				
			|||
			_run = true; | 
				
			|||
		} | 
				
			|||
 | 
				
			|||
		if(_run) | 
				
			|||
		{ | 
				
			|||
			auto filterSize = _kernelParameters.filterWidth * _kernelParameters.filterHeight; | 
				
			|||
			float filter[filterSize]; | 
				
			|||
			for(int i = 0; i < filterSize ; i++) | 
				
			|||
			{ | 
				
			|||
				filter[i] = backgroundRecovery[i] - hpf[i]; | 
				
			|||
			} | 
				
			|||
 | 
				
			|||
			delete [] hpf; | 
				
			|||
			delete [] backgroundRecovery; | 
				
			|||
 | 
				
			|||
			if(_filter) | 
				
			|||
				delete  _filter; | 
				
			|||
 | 
				
			|||
			_filter = _openCLHelper.array2CLBuffer(_CLContext, filterSize * sizeof (float)); | 
				
			|||
			BIP::getInstance()->CLQueue.enqueueWriteBuffer(*_filter, CL_TRUE, | 
				
			|||
														   0, filterSize * sizeof (float), | 
				
			|||
														   filter); | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void Enhance::finalize() | 
				
			|||
{ | 
				
			|||
	if(_filter) | 
				
			|||
		delete  _filter; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
 | 
				
			|||
Image* Enhance::processKernel(Image *frames, Buffer* scratchPad) | 
				
			|||
{ | 
				
			|||
	if(_run) | 
				
			|||
	{ | 
				
			|||
		auto format = frames->getImageInfo<CL_IMAGE_FORMAT>(); | 
				
			|||
		auto width = frames->getImageInfo<CL_IMAGE_WIDTH>(); | 
				
			|||
		auto height = frames->getImageInfo<CL_IMAGE_HEIGHT>(); | 
				
			|||
 | 
				
			|||
		_kernelParameters.width = width; | 
				
			|||
		_kernelParameters.height = height; | 
				
			|||
 | 
				
			|||
		auto imageOutput = new Image2D(_CLContext, | 
				
			|||
								CL_MEM_READ_WRITE, | 
				
			|||
								ImageFormat(format.image_channel_order, format.image_channel_data_type), | 
				
			|||
								width, | 
				
			|||
								height); | 
				
			|||
		cl::EnqueueArgs eargs(BIP::getInstance()->CLQueue, cl::NDRange(width, height)); | 
				
			|||
		_openCLHelper.runKernelFunctor<Image2D, Image2D, Buffer, Enhance_t>(_kernelFunctor, | 
				
			|||
																					   eargs, | 
				
			|||
																					   *static_cast<Image2D*>(frames), | 
				
			|||
																					   *imageOutput, | 
				
			|||
																						*_filter, | 
				
			|||
																					   _kernelParameters); | 
				
			|||
 | 
				
			|||
 | 
				
			|||
		delete frames; | 
				
			|||
		return imageOutput; | 
				
			|||
	} | 
				
			|||
	else | 
				
			|||
	{ | 
				
			|||
		return frames; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
 | 
				
			|||
@ -0,0 +1,136 @@ | 
				
			|||
#include "model/processor/strategies/Persist.h" | 
				
			|||
#include "model/processor/BIP.h" | 
				
			|||
#include <QPixmap> | 
				
			|||
#include <QImage> | 
				
			|||
 | 
				
			|||
Persist::Persist(const Context context, | 
				
			|||
		 const QString kernelPath, | 
				
			|||
		 const QObject *parent = Q_NULLPTR) : | 
				
			|||
	IProcessStrategy(context, kernelPath, "Persist", parent), | 
				
			|||
	_kernelFunctor(KernelFunctor<Image2D, Image2D, | 
				
			|||
				   Image2D, Image2D, Persist_t>(_kernel)) | 
				
			|||
{ | 
				
			|||
	memset(&_kernelParameters, 0, sizeof (Persist_t)); | 
				
			|||
	_imageSum = Q_NULLPTR; | 
				
			|||
	_reCalc = true; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void Persist::cpuProcess(ScenGenOutput_t parameters) | 
				
			|||
{ | 
				
			|||
	if(parameters.persist.isUpdated) | 
				
			|||
	{ | 
				
			|||
		_kernelParameters.persist = parameters.persist.value; | 
				
			|||
		_reCalc = true; | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void Persist::finalize() | 
				
			|||
{ | 
				
			|||
	foreach (auto frame, _queue) | 
				
			|||
	{ | 
				
			|||
		delete frame; | 
				
			|||
	} | 
				
			|||
	_queue.clear(); | 
				
			|||
 | 
				
			|||
	if(_imageSum) | 
				
			|||
		delete _imageSum; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
 | 
				
			|||
Image* Persist::processKernel(Image *frames, Buffer* scratchPad) | 
				
			|||
{ | 
				
			|||
	Image* temp; | 
				
			|||
 | 
				
			|||
	if(_queue.length() < PERSIST_MAX_SIZE) | 
				
			|||
	{ | 
				
			|||
		_queue.push_front(frames); | 
				
			|||
		return frames; | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	if(_kernelParameters.persist != 1) | 
				
			|||
	{ | 
				
			|||
		auto format = frames->getImageInfo<CL_IMAGE_FORMAT>(); | 
				
			|||
		auto width = frames->getImageInfo<CL_IMAGE_WIDTH>(); | 
				
			|||
		auto height = frames->getImageInfo<CL_IMAGE_HEIGHT>(); | 
				
			|||
 | 
				
			|||
		//if width or height changes we should erase everything
 | 
				
			|||
		if(_lastWidth != width || _lastHeight != height) | 
				
			|||
		{ | 
				
			|||
			_reCalc = false; | 
				
			|||
 | 
				
			|||
			if(_imageSum) | 
				
			|||
				delete _imageSum; | 
				
			|||
 | 
				
			|||
			_imageSum = new Image2D(_CLContext, | 
				
			|||
								CL_MEM_READ_WRITE, | 
				
			|||
								ImageFormat(format.image_channel_order, format.image_channel_data_type), | 
				
			|||
								width, | 
				
			|||
								height); | 
				
			|||
 | 
				
			|||
			foreach (auto frame, _queue) | 
				
			|||
			{ | 
				
			|||
				delete frame; | 
				
			|||
			} | 
				
			|||
			_queue.clear(); | 
				
			|||
 | 
				
			|||
			_lastWidth = width; | 
				
			|||
			_lastHeight = height; | 
				
			|||
		} | 
				
			|||
 | 
				
			|||
 | 
				
			|||
		auto outputImage = new Image2D(_CLContext, | 
				
			|||
							CL_MEM_READ_WRITE, | 
				
			|||
							ImageFormat(format.image_channel_order, format.image_channel_data_type), | 
				
			|||
							width, | 
				
			|||
							height); | 
				
			|||
 | 
				
			|||
 | 
				
			|||
		cl::EnqueueArgs eargs(BIP::getInstance()->CLQueue, cl::NDRange(width, height)); | 
				
			|||
 | 
				
			|||
		if(_reCalc) | 
				
			|||
		{ | 
				
			|||
			_reCalc = false; | 
				
			|||
			for(auto i = 0; i < _kernelParameters.persist; i++) | 
				
			|||
			{ | 
				
			|||
				if(i == 0) | 
				
			|||
					_kernelParameters.mode = 0; | 
				
			|||
				else if(i < _kernelParameters.persist) | 
				
			|||
					_kernelParameters.mode = 1; | 
				
			|||
 | 
				
			|||
				_openCLHelper.runKernelFunctor<Image2D, Image2D, Image2D, Image2D, Persist_t>(_kernelFunctor, | 
				
			|||
												 eargs, | 
				
			|||
												 *static_cast<Image2D*>(_queue[i]), | 
				
			|||
												 *outputImage, | 
				
			|||
												 *static_cast<Image2D*>(_imageSum), | 
				
			|||
												 *static_cast<Image2D*>(_queue[_kernelParameters.persist - 1]), | 
				
			|||
												 _kernelParameters); | 
				
			|||
			} | 
				
			|||
		} | 
				
			|||
 | 
				
			|||
		_kernelParameters.mode = 2; | 
				
			|||
		_openCLHelper.runKernelFunctor<Image2D, Image2D, Image2D, Image2D, Persist_t>(_kernelFunctor, | 
				
			|||
												 eargs, | 
				
			|||
												 *static_cast<Image2D*>(frames), | 
				
			|||
												 *outputImage, | 
				
			|||
												 *static_cast<Image2D*>(_imageSum), | 
				
			|||
												 *static_cast<Image2D*>(_queue[_kernelParameters.persist - 1]), | 
				
			|||
												 _kernelParameters); | 
				
			|||
 | 
				
			|||
		temp = outputImage; | 
				
			|||
	} | 
				
			|||
	else | 
				
			|||
	{ | 
				
			|||
		temp =  frames; | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	delete _queue[PERSIST_MAX_SIZE - 1]; | 
				
			|||
	for(auto i = 0; i < PERSIST_MAX_SIZE - 1; i++) | 
				
			|||
	{ | 
				
			|||
		_queue[i + 1] = _queue[i]; | 
				
			|||
	} | 
				
			|||
 | 
				
			|||
	_queue[0] = frames; | 
				
			|||
 | 
				
			|||
 | 
				
			|||
	return temp; | 
				
			|||
} | 
				
			|||
					Loading…
					
					
				
		Reference in new issue