improved gaussian and added box blur
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "effects/video/gaussianblureffect.h"
|
||||
#include "effects/video/cropeffect.h"
|
||||
#include "effects/video/flipeffect.h"
|
||||
#include "effects/video/boxblureffect.h"
|
||||
|
||||
#include "effects/audio/paneffect.h"
|
||||
#include "effects/audio/volumeeffect.h"
|
||||
@@ -53,6 +54,7 @@ void init_effects() {
|
||||
video_effect_names[VIDEO_GAUSSIANBLUR_EFFECT] = "Gaussian Blur";
|
||||
video_effect_names[VIDEO_CROP_EFFECT] = "Crop";
|
||||
video_effect_names[VIDEO_FLIP_EFFECT] = "Flip";
|
||||
video_effect_names[VIDEO_BOXBLUR_EFFECT] = "Box Blur";
|
||||
|
||||
audio_effect_names[AUDIO_VOLUME_EFFECT] = "Volume";
|
||||
audio_effect_names[AUDIO_PAN_EFFECT] = "Pan";
|
||||
@@ -71,6 +73,7 @@ Effect* create_effect(int effect_id, Clip* c) {
|
||||
case VIDEO_GAUSSIANBLUR_EFFECT: return new GaussianBlurEffect(c); break;
|
||||
case VIDEO_CROP_EFFECT: return new CropEffect(c);
|
||||
case VIDEO_FLIP_EFFECT: return new FlipEffect(c);
|
||||
case VIDEO_BOXBLUR_EFFECT: return new BoxBlurEffect(c);
|
||||
}
|
||||
} else {
|
||||
switch (effect_id) {
|
||||
|
||||
@@ -29,6 +29,7 @@ enum VideoEffects {
|
||||
VIDEO_GAUSSIANBLUR_EFFECT,
|
||||
VIDEO_CROP_EFFECT,
|
||||
VIDEO_FLIP_EFFECT,
|
||||
VIDEO_BOXBLUR_EFFECT,
|
||||
VIDEO_EFFECT_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "boxblureffect.h"
|
||||
|
||||
#include "project/clip.h"
|
||||
|
||||
BoxBlurEffect::BoxBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_BOXBLUR_EFFECT), vert(QOpenGLShader::Vertex), frag(QOpenGLShader::Fragment) {
|
||||
enable_opengl = true;
|
||||
|
||||
radius_val = add_row("Radius:")->add_field(EFFECT_FIELD_DOUBLE);
|
||||
// iteration_val = add_row("Iterations:")->add_field(EFFECT_FIELD_DOUBLE);
|
||||
horiz_val = add_row("Horizontal:")->add_field(EFFECT_FIELD_BOOL);
|
||||
vert_val = add_row("Vertical:")->add_field(EFFECT_FIELD_BOOL);
|
||||
|
||||
radius_val->set_double_default_value(9);
|
||||
radius_val->set_double_minimum_value(0);
|
||||
|
||||
// iteration_val->set_double_default_value(1);
|
||||
// iteration_val->set_double_minimum_value(0);
|
||||
|
||||
horiz_val->set_bool_value(true);
|
||||
vert_val->set_bool_value(true);
|
||||
|
||||
vert.compileSourceFile(":/shaders/common.vert");
|
||||
frag.compileSourceFile(":/shaders/boxblureffect.frag");
|
||||
program.addShader(&vert);
|
||||
program.addShader(&frag);
|
||||
program.link();
|
||||
|
||||
connect(radius_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
// connect(iteration_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(horiz_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(vert_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
}
|
||||
|
||||
void BoxBlurEffect::process_gl(double timecode, GLTextureCoords &coords) {
|
||||
program.bind();
|
||||
|
||||
program.setUniformValue("resolution", parent_clip->getWidth(), parent_clip->getHeight());
|
||||
program.setUniformValue("radius", (GLfloat) radius_val->get_double_value(timecode));
|
||||
program.setUniformValue("horiz_blur", horiz_val->get_bool_value(timecode));
|
||||
program.setUniformValue("vert_blur", vert_val->get_bool_value(timecode));
|
||||
}
|
||||
|
||||
void BoxBlurEffect::clean_gl() {
|
||||
program.release();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef BOXBLUREFFECT_H
|
||||
#define BOXBLUREFFECT_H
|
||||
|
||||
#include "../effect.h"
|
||||
|
||||
class BoxBlurEffect : public Effect
|
||||
{
|
||||
public:
|
||||
BoxBlurEffect(Clip* c);
|
||||
|
||||
void process_gl(double timecode, GLTextureCoords &coords);
|
||||
void clean_gl();
|
||||
private:
|
||||
QOpenGLShaderProgram program;
|
||||
QOpenGLShader vert;
|
||||
QOpenGLShader frag;
|
||||
|
||||
EffectField* radius_val;
|
||||
EffectField* iteration_val;
|
||||
EffectField* horiz_val;
|
||||
EffectField* vert_val;
|
||||
};
|
||||
|
||||
#endif // BOXBLUREFFECT_H
|
||||
@@ -4,19 +4,18 @@
|
||||
|
||||
#include <QImage>
|
||||
|
||||
GaussianBlurEffect::GaussianBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_GAUSSIANBLUR_EFFECT), frag(QOpenGLShader::Fragment), vert(QOpenGLShader::Vertex), bound(false) {
|
||||
enable_opengl = true;
|
||||
enable_image = false;
|
||||
GaussianBlurEffect::GaussianBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_GAUSSIANBLUR_EFFECT), frag(QOpenGLShader::Fragment), vert(QOpenGLShader::Vertex) {
|
||||
enable_opengl = true;
|
||||
|
||||
kernelsz_val = add_row("Kernel Size:")->add_field(EFFECT_FIELD_DOUBLE);
|
||||
radius_val = add_row("Radius:")->add_field(EFFECT_FIELD_DOUBLE);
|
||||
sigma_val = add_row("Sigma:")->add_field(EFFECT_FIELD_DOUBLE);
|
||||
horiz_val = add_row("Horizontal:")->add_field(EFFECT_FIELD_BOOL);
|
||||
vert_val = add_row("Vertical:")->add_field(EFFECT_FIELD_BOOL);
|
||||
|
||||
kernelsz_val->set_double_minimum_value(0);
|
||||
radius_val->set_double_minimum_value(0);
|
||||
sigma_val->set_double_minimum_value(0);
|
||||
|
||||
kernelsz_val->set_double_default_value(9);
|
||||
radius_val->set_double_default_value(9);
|
||||
sigma_val->set_double_default_value(5.5);
|
||||
|
||||
horiz_val->set_bool_value(true);
|
||||
@@ -28,19 +27,17 @@ GaussianBlurEffect::GaussianBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, V
|
||||
program.addShader(&frag);
|
||||
program.link();
|
||||
|
||||
connect(kernelsz_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(radius_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(sigma_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(horiz_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(vert_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
|
||||
refresh();
|
||||
connect(vert_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
}
|
||||
|
||||
void GaussianBlurEffect::process_gl(double timecode, GLTextureCoords &coords) {
|
||||
program.bind();
|
||||
|
||||
program.setUniformValue("resolution", parent_clip->getWidth(), parent_clip->getHeight());
|
||||
program.setUniformValue("kernel_size", (GLfloat) kernelsz_val->get_double_value(timecode));
|
||||
program.setUniformValue("radius", (GLfloat) radius_val->get_double_value(timecode));
|
||||
program.setUniformValue("sigma", (GLfloat) sigma_val->get_double_value(timecode));
|
||||
program.setUniformValue("horiz_blur", horiz_val->get_bool_value(timecode));
|
||||
program.setUniformValue("vert_blur", vert_val->get_bool_value(timecode));
|
||||
|
||||
@@ -14,12 +14,10 @@ private:
|
||||
QOpenGLShader vert;
|
||||
QOpenGLShader frag;
|
||||
|
||||
EffectField* kernelsz_val;
|
||||
EffectField* radius_val;
|
||||
EffectField* sigma_val;
|
||||
EffectField* horiz_val;
|
||||
EffectField* vert_val;
|
||||
|
||||
bool bound;
|
||||
EffectField* vert_val;
|
||||
};
|
||||
|
||||
#endif // GAUSSIANBLUREFFECT_H
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#version 110
|
||||
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
uniform sampler2D image;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec2 resolution;
|
||||
uniform bool horiz_blur;
|
||||
uniform bool vert_blur;
|
||||
|
||||
void main(void) {
|
||||
if (radius == 0.0 || (!horiz_blur && !vert_blur)) {
|
||||
gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution);
|
||||
} else {
|
||||
float divider = 1.0 / ((radius*2.0)+1.0);
|
||||
if (horiz_blur && vert_blur) {
|
||||
divider *= divider;
|
||||
|
||||
gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution)*divider;
|
||||
|
||||
for (float i=1.0;i<=radius;i++) {
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-i, gl_FragCoord.y))/resolution)*(divider);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+i, gl_FragCoord.y))/resolution)*(divider);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y+i))/resolution)*(divider);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y-i))/resolution)*(divider);
|
||||
}
|
||||
|
||||
for (float x=1.0;x<=radius;x++) {
|
||||
for (float y=1.0;y<=radius;y++) {
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-x, gl_FragCoord.y-y))/resolution)*(divider);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+x, gl_FragCoord.y+y))/resolution)*(divider);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-x, gl_FragCoord.y+y))/resolution)*(divider);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+x, gl_FragCoord.y-y))/resolution)*(divider);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution)*(divider);
|
||||
|
||||
for (float i=1.0;i<=radius;i++) {
|
||||
if (horiz_blur) {
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-i, gl_FragCoord.y))/resolution)*(divider);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+i, gl_FragCoord.y))/resolution)*(divider);
|
||||
} else {
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y-i))/resolution)*(divider);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y+i))/resolution)*(divider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
uniform sampler2D image;
|
||||
|
||||
uniform float kernel_size;
|
||||
uniform float radius;
|
||||
uniform float sigma;
|
||||
uniform vec2 resolution;
|
||||
uniform bool horiz_blur;
|
||||
@@ -19,25 +19,35 @@ float gaussian2(float x, float y, float sigma) {
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
if (kernel_size == 0.0 || sigma == 0.0 || (!horiz_blur && !vert_blur)) {
|
||||
if (radius == 0.0 || sigma == 0.0 || (!horiz_blur && !vert_blur)) {
|
||||
gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution);
|
||||
} else {
|
||||
float half_kernel = floor(kernel_size*0.5);
|
||||
|
||||
float middleWeight = gaussian(0.0, sigma);
|
||||
float sum = middleWeight;
|
||||
|
||||
if (horiz_blur && vert_blur) {
|
||||
for (float x=0.0;x<half_kernel;x++) {
|
||||
for (float y=0.0;y<half_kernel;y++) {
|
||||
for (float i=1.0;i<=radius;i++) {
|
||||
sum += (4.0*gaussian2(i, 0.0, sigma));
|
||||
}
|
||||
|
||||
for (float x=1.0;x<=radius;x++) {
|
||||
for (float y=1.0;y<=radius;y++) {
|
||||
sum += (4.0*gaussian2(x, y, sigma));
|
||||
}
|
||||
}
|
||||
|
||||
gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution)*(middleWeight/sum);
|
||||
|
||||
for (float x=0.0;x<half_kernel;x++) {
|
||||
for (float y=0.0;y<half_kernel;y++) {
|
||||
for (float i=1.0;i<=radius;i++) {
|
||||
float weight = (gaussian2(i, 0.0, sigma)/sum);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-i, gl_FragCoord.y))/resolution)*(weight);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+i, gl_FragCoord.y))/resolution)*(weight);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y+i))/resolution)*(weight);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y-i))/resolution)*(weight);
|
||||
}
|
||||
|
||||
for (float x=1.0;x<=radius;x++) {
|
||||
for (float y=1.0;y<=radius;y++) {
|
||||
float weight = (gaussian2(x, y, sigma)/sum);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-x, gl_FragCoord.y-y))/resolution)*(weight);
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+x, gl_FragCoord.y+y))/resolution)*(weight);
|
||||
@@ -46,13 +56,13 @@ void main(void) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (float i=1.0;i<half_kernel;i++) {
|
||||
for (float i=1.0;i<=radius;i++) {
|
||||
sum += (2.0*gaussian(i, sigma));
|
||||
}
|
||||
|
||||
gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution)*(middleWeight/sum);
|
||||
|
||||
for (float i=0.0;i<half_kernel;i++) {
|
||||
for (float i=1.0;i<=radius;i++) {
|
||||
float weight = gaussian(i, sigma)/sum;
|
||||
if (horiz_blur) {
|
||||
gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-i, gl_FragCoord.y))/resolution)*(weight);
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
<file>inverteffect.frag</file>
|
||||
<file>chromakeyeffect.frag</file>
|
||||
<file>solideffect.frag</file>
|
||||
<file>boxblureffect.frag</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -76,7 +76,8 @@ SOURCES += \
|
||||
effects/video/gaussianblureffect.cpp \
|
||||
effects/video/cropeffect.cpp \
|
||||
effects/video/flipeffect.cpp \
|
||||
effects/audio/audionoiseeffect.cpp
|
||||
effects/audio/audionoiseeffect.cpp \
|
||||
effects/video/boxblureffect.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h \
|
||||
@@ -129,7 +130,8 @@ HEADERS += \
|
||||
effects/video/gaussianblureffect.h \
|
||||
effects/video/cropeffect.h \
|
||||
effects/video/flipeffect.h \
|
||||
effects/audio/audionoiseeffect.h
|
||||
effects/audio/audionoiseeffect.h \
|
||||
effects/video/boxblureffect.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
|
||||
Reference in New Issue
Block a user