-
-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
219 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
set (SOURCES euclid_eraser.cpp) | ||
set (TARGET euclid_eraser) | ||
|
||
if (MSVC) | ||
set (SOURCES ${SOURCES} ${FREI0R_1_1_DEF}) | ||
endif (MSVC) | ||
|
||
add_library (${TARGET} MODULE ${SOURCES}) | ||
set_target_properties (${TARGET} PROPERTIES PREFIX "") | ||
|
||
install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
// Copyright (C) 2024 Erik H. Beck, [email protected] | ||
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html | ||
|
||
/* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
* 02110-1301, USA | ||
* | ||
* Also see: | ||
* | ||
* https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html | ||
* | ||
*/ | ||
|
||
/** This is the source file for the euclid eraser two-input mixer for | ||
frei0r. It uses euclidean distance to remove a static background | ||
from a video. See file ./euclid_eraser.md for more info | ||
*/ | ||
|
||
#include <math.h> | ||
#include "frei0r.hpp" | ||
#include "frei0r/math.h" | ||
|
||
#define NBYTES 4 | ||
#define CHANNELS 3 // Actually 4; 0-3 | ||
|
||
double euclidDistance(uint8_t x_r, uint8_t x_g, uint8_t x_b, | ||
uint8_t y_r, uint8_t y_g, uint8_t y_b) | ||
{ | ||
//calculating color channel differences for next steps | ||
double red_d = x_r - y_r; | ||
double green_d = x_g - y_g; | ||
double blue_d = x_b - y_b; | ||
|
||
double sq_sum, dist; | ||
|
||
//calculating Euclidean distance | ||
sq_sum = pow(red_d, 2) + pow(green_d, 2) + pow (blue_d, 2); | ||
dist = sqrt(sq_sum); | ||
|
||
return dist; | ||
} | ||
|
||
|
||
class euclid_eraser : public frei0r::mixer2 | ||
{ | ||
|
||
public: | ||
euclid_eraser(unsigned int width, unsigned int height) | ||
{ | ||
threshold = 5.6; // Default distance threshold value | ||
register_param(threshold, "threshold", "Matching Threshold"); | ||
} | ||
|
||
void update(double time, | ||
uint32_t* out, | ||
const uint32_t* in1, | ||
const uint32_t* in2) | ||
{ | ||
|
||
const uint8_t *src1 = reinterpret_cast<const uint8_t*>(in1); //frst track (0) | ||
const uint8_t *src2 = reinterpret_cast<const uint8_t*>(in2); //second trk (1) | ||
uint8_t *dst = reinterpret_cast<uint8_t*>(out); | ||
|
||
double e_dist; | ||
|
||
uint32_t sizeCounter = size; | ||
uint32_t b; | ||
|
||
while (sizeCounter--) | ||
{ | ||
|
||
// Loop over rgb | ||
// Copy pixels from src2 to destination | ||
|
||
for (b=0; b<3; b++) | ||
{ | ||
dst[b]=src2[b]; | ||
} | ||
e_dist=euclidDistance(src1[0],src1[1],src1[2], | ||
src2[0],src2[1],src2[2]); | ||
|
||
if (e_dist <= euclid_eraser::threshold) { | ||
// Make alpha channel for pixel fully transparent | ||
dst[3]=0; | ||
} | ||
else { | ||
// Make alpha channel for the pixel fully opaque | ||
dst[3]=255; | ||
} | ||
|
||
src1 += NBYTES; | ||
src2 += NBYTES; | ||
dst += NBYTES; | ||
} | ||
|
||
} | ||
private: | ||
double threshold; | ||
|
||
}; | ||
|
||
frei0r::construct<euclid_eraser> plugin("euclid_eraser", | ||
"Erasing backgrounds with euclidian distance", | ||
"Erik H. Beck", | ||
0,1, | ||
F0R_COLOR_MODEL_RGBA8888); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Euclid Eraser Notes # | ||
|
||
## Overview ## | ||
This is about the Euclid Eraser mixer. | ||
|
||
|
||
## Description ## | ||
|
||
This class is intended to operate as a mixer, taking two inputs and | ||
yielding one output. | ||
|
||
The first input is a reference input, such as a single image or a | ||
stretched video of a single image. | ||
|
||
The second input is the video stream to operate on. | ||
|
||
The output is a clone of the RGB data of the second input, but with | ||
the alpha channel modified. | ||
|
||
This mixer takes the (first) reference input, such as a static | ||
background, and removes it from every frame in the video stream of the | ||
second input. | ||
|
||
The alpha channel on the output is based on the euclidian distance of | ||
the two input coordinates in 3-d RGB space. If the calculated distance | ||
betwen the two inputs for a given pixel is less than a provided | ||
(variable) threshold amount, that indicates the pixel in the | ||
background (reference) image is the same or similar enough to the | ||
operational (second) input that is part of the background to be | ||
removed, and the transparency is set to fully transparent via the | ||
alpha channel (set to 0). | ||
|
||
If the calcuated distance exceeds the threshold, then that pixel is | ||
part of the foreground image to be retained, and the transparency | ||
of it is set to be fully opaque (alpha channel for that pixel set | ||
to 255). | ||
|
||
## Basic Algorithm ## | ||
The basic comparison algorithm is: | ||
|
||
|
||
x is reference image | ||
y is comparison image to remove reference image from | ||
|
||
|
||
``` | ||
float euclidDistance (int x_r, int x_g, int x_b, int y_r, int y_g, int y_b) | ||
{ | ||
//calculating color channel differences for next steps | ||
float red_d = x_r - y_r; | ||
float green_d = x_g - y_g; | ||
float blue_d = x_b - y_b; | ||
float sq_sum, dist; | ||
//calculating Euclidean distance | ||
sq_sum = pow(red_d, 2) + pow(green_d, 2) + pow (blue_d) | ||
dist = sqrt(sq_sum); | ||
return dist; | ||
} | ||
``` | ||
|
||
## Note ## | ||
|
||
Here's a handy reminder on how the bits map up. | ||
|
||
``` | ||
red_src1 = src1[0]; | ||
green_src1 = src1[1]; | ||
blue_src1 = src1[2]; | ||
alpha_src1 = src1[3] | ||
red_src2 = src2[0]; | ||
green_src2 = src2[1]; | ||
blue_src2 = src2[2]; | ||
alpha_src2 = src2[3] | ||
``` | ||
## Further Work ## | ||
|
||
Some potential improvements are: | ||
|
||
- Faster performance (math calculations, others) | ||
- Options beyond binary for alpha | ||
|
||
|
||
|
||
|