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