Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit 66465fa

Browse files
committed
Remove unused code and update localization
1 parent c649fbe commit 66465fa

File tree

4 files changed

+95
-68
lines changed

4 files changed

+95
-68
lines changed

README.md

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
[![GitHub](https://img.shields.io/github/license/occ-ai/obs-detect)](https://github.com/occ-ai/obs-detect/blob/main/LICENSE)
66
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/occ-ai/obs-detect/push.yaml)](https://github.com/occ-ai/obs-detect/actions/workflows/push.yaml)
77
[![Total downloads](https://img.shields.io/github/downloads/occ-ai/obs-detect/total)](https://github.com/occ-ai/obs-detect/releases)
8-
![Flathub](https://img.shields.io/flathub/downloads/com.obsproject.Studio.Plugin.BackgroundRemoval?label=Flathub%20Installs)
98
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/occ-ai/obs-detect)](https://github.com/occ-ai/obs-detect/releases)
109
[![Discord](https://img.shields.io/discord/1200229425141252116)](https://discord.gg/KbjGU2vvUz)
1110

@@ -18,26 +17,78 @@ If you like this work, which is given to you completely free of charge, please c
1817
- https://github.com/sponsors/royshil
1918
- https://github.com/sponsors/umireon
2019

20+
This work uses the great contributions from [EdgeYOLO-ROS](https://github.com/fateshelled/EdgeYOLO-ROS) and [PINTO-Model-Zoo](https://github.com/PINTO0309/PINTO_model_zoo).
21+
2122
## Usage
2223

23-
<div align="center">
24-
<video src="https://github.com/occ-ai/obs-backgroundremoval/assets/1067855/5ba5aae2-7ea2-4c90-ad45-fba5ccde1a4e" width="320"></video>
25-
</div>
24+
- Add the "Detect" filter to any source with an image
25+
- Enable "Masking" or "Tracking"
26+
27+
Use Detect to track your pet, or blur out people in your video!
28+
29+
More information and usage tutorials to follow soon.
30+
31+
## Features
32+
33+
Current features:
34+
35+
- Detect over 80 categories of objects, using an efficient model ([EdgeYOLO](https://github.com/LSH9832/edgeyolo))
36+
- 3 Model sizes: Small, Medium and Large
37+
- Control detection threshold
38+
- Select object category filter (e.g. find only "Person")
39+
- Masking: Blur, Solid color, Transparent, output binary mask (combine with other plugins!)
40+
- Tracking: Single object / All objects, Zoom factor, smooth transition
41+
42+
Roadmap features:
43+
- Precise object mask, beyond bounding box
44+
- Implement SORT tracking for smoothness
45+
- Multiple object category selection (e.g. Dog + Cat + Duck)
46+
- Make available detection information for other plugins through settings
47+
- More real-time models choices
48+
49+
## Building
50+
51+
The plugin was built and tested on Mac OSX (Intel & Apple silicon), Windows and Linux.
52+
53+
Start by cloning this repo to a directory of your choice.
54+
55+
### Mac OSX
56+
57+
Using the CI pipeline scripts, locally you would just call the zsh script. By default this builds a universal binary for both Intel and Apple Silicon. To build for a specific architecture please see `.github/scripts/.build.zsh` for the `-arch` options.
58+
59+
```sh
60+
$ ./.github/scripts/build-macos -c Release
61+
```
62+
63+
#### Install
64+
The above script should succeed and the plugin files (e.g. `obs-ocr.plugin`) will reside in the `./release/Release` folder off of the root. Copy the `.plugin` file to the OBS directory e.g. `~/Library/Application Support/obs-studio/plugins`.
65+
66+
To get `.pkg` installer file, run for example
67+
```sh
68+
$ ./.github/scripts/package-macos -c Release
69+
```
70+
(Note that maybe the outputs will be in the `Release` folder and not the `install` folder like `pakage-macos` expects, so you will need to rename the folder from `build_x86_64/Release` to `build_x86_64/install`)
71+
72+
### Linux (Ubuntu)
73+
74+
Use the CI scripts again
75+
```sh
76+
$ ./.github/scripts/build-linux.sh
77+
```
2678

79+
Copy the results to the standard OBS folders on Ubuntu
80+
```sh
81+
$ sudo cp -R release/RelWithDebInfo/lib/* /usr/lib/x86_64-linux-gnu/
82+
$ sudo cp -R release/RelWithDebInfo/share/* /usr/share/
83+
```
84+
Note: The official [OBS plugins guide](https://obsproject.com/kb/plugins-guide) recommends adding plugins to the `~/.config/obs-studio/plugins` folder.
2785

86+
### Windows
2887

29-
### GitHub Actions Set Up
88+
Use the CI scripts again, for example:
3089

31-
To use code signing on GitHub Actions, the certificate and associated information need to be set up as _repository secrets_ in the GitHub repository's settings.
90+
```powershell
91+
> .github/scripts/Build-Windows.ps1 -Target x64
92+
```
3293

33-
* First, the locally stored developer certificate needs to be exported from the macOS keychain:
34-
* Using the Keychain app on macOS, export these your certificates (Application and Installer) public _and_ private keys into a single .p12 file **protected with a strong password**
35-
* Encode the .p12 file into its base64 representation by running `base64 <NAME_OF_YOUR_P12_FILE>`
36-
* Next, the certificate data and the password used to export it need to be set up as repository secrets:
37-
* `MACOS_SIGNING_APPLICATION_IDENTITY`: Name of the "Developer ID Application" signing certificate
38-
* `MACOS_SIGNING_INSTALLER_IDENTITY`: Name of "Developer ID Installer" signing certificate
39-
* `MACOS_SIGNING_CERT`: The base64 encoded `.p12` file
40-
* `MACOS_SIGNING_CERT_PASSWORD`: Password used to generate the .p12 certificate
41-
* To also enable notarization on GitHub Action runners, the following repository secrets are required:
42-
* `MACOS_NOTARIZATION_USERNAME`: Your Apple Developer account's _Apple ID_
43-
* `MACOS_NOTARIZATION_PASSWORD`: Your Apple Developer account's _generated app password_
94+
The build should exist in the `./release` folder off the root. You can manually install the files in the OBS directory.

data/locale/en-US.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ModelSize="Model Size"
1111
SmallFast="Small (Fast)"
1212
Medium="Medium"
1313
LargeSlow="Large (Accurate)"
14-
Preview="Preview"
14+
Preview="Preview detection boxes"
1515
ObjectCategory="Object Category"
1616
All="All"
1717
MaskingGroup="Masking Options"

src/FilterData.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ struct filter_data {
3030
obs_source_t *source;
3131
gs_texrender_t *texrender;
3232
gs_stagesurf_t *stagesurface;
33-
gs_effect_t *effect;
3433
gs_effect_t *kawaseBlurEffect;
3534
gs_effect_t *maskingEffect;
3635

src/detect-filter.cpp

Lines changed: 26 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static bool enable_advanced_settings(obs_properties_t *ppts, obs_property_t *p,
5050

5151
for (const char *prop_name :
5252
{"threshold", "useGPU", "preview", "numThreads", "object_category",
53-
"masking_group", "tracking_group"}) {
53+
"masking_group", "tracking_group", "model_size"}) {
5454
p = obs_properties_get(ppts, prop_name);
5555
obs_property_set_visible(p, enabled);
5656
}
@@ -136,35 +136,23 @@ obs_properties_t *detect_filter_properties(void *data)
136136
obs_data_get_bool(settings, "masking_group");
137137
obs_property_t *prop =
138138
obs_properties_get(props_, "masking_type");
139-
obs_property_set_visible(prop, enabled);
140139
obs_property_t *masking_color =
141140
obs_properties_get(props_, "masking_color");
142141
obs_property_t *masking_blur_radius =
143142
obs_properties_get(props_,
144143
"masking_blur_radius");
145-
if (enabled) {
146-
const char *masking_type = obs_data_get_string(
147-
settings, "masking_type");
148-
if (strcmp(masking_type, "solid_color") == 0) {
149-
obs_property_set_visible(masking_color,
150-
true);
151-
obs_property_set_visible(
152-
masking_blur_radius, false);
153-
} else if (strcmp(masking_type, "blur") == 0) {
154-
obs_property_set_visible(masking_color,
155-
false);
156-
obs_property_set_visible(
157-
masking_blur_radius, true);
158-
} else {
159-
obs_property_set_visible(masking_color,
160-
false);
161-
obs_property_set_visible(
162-
masking_blur_radius, false);
163-
}
164-
} else {
165-
obs_property_set_visible(masking_color, false);
144+
145+
obs_property_set_visible(prop, enabled);
146+
obs_property_set_visible(masking_color, false);
147+
obs_property_set_visible(masking_blur_radius, false);
148+
const char *masking_type_value =
149+
obs_data_get_string(settings, "masking_type");
150+
if (strcmp(masking_type_value, "solid_color") == 0) {
151+
obs_property_set_visible(masking_color,
152+
enabled);
153+
} else if (strcmp(masking_type_value, "blur") == 0) {
166154
obs_property_set_visible(masking_blur_radius,
167-
false);
155+
enabled);
168156
}
169157
return true;
170158
});
@@ -204,18 +192,14 @@ obs_properties_t *detect_filter_properties(void *data)
204192
obs_property_t *masking_blur_radius =
205193
obs_properties_get(props_,
206194
"masking_blur_radius");
195+
obs_property_set_visible(masking_color, false);
196+
obs_property_set_visible(masking_blur_radius, false);
197+
207198
if (strcmp(masking_type_value, "solid_color") == 0) {
208199
obs_property_set_visible(masking_color, true);
209-
obs_property_set_visible(masking_blur_radius,
210-
false);
211200
} else if (strcmp(masking_type_value, "blur") == 0) {
212-
obs_property_set_visible(masking_color, false);
213201
obs_property_set_visible(masking_blur_radius,
214202
true);
215-
} else {
216-
obs_property_set_visible(masking_color, false);
217-
obs_property_set_visible(masking_blur_radius,
218-
false);
219203
}
220204
return true;
221205
});
@@ -243,8 +227,8 @@ obs_properties_t *detect_filter_properties(void *data)
243227

244228
// add zoom factor slider
245229
obs_properties_add_float_slider(tracking_group_props, "zoom_factor",
246-
obs_module_text("ZoomFactor"), 1.0,
247-
10.0, 0.1);
230+
obs_module_text("ZoomFactor"), 0.0, 1.0,
231+
0.05);
248232

249233
// add object selection for zoom drop down: "Single", "All"
250234
obs_property_t *zoom_object = obs_properties_add_list(
@@ -257,16 +241,8 @@ obs_properties_t *detect_filter_properties(void *data)
257241
"all");
258242

259243
// Add a informative text about the plugin
260-
// replace the placeholder with the current version
261-
// use std::regex_replace instead of QString::arg because the latter doesn't work on Linux
262244
std::string basic_info = std::regex_replace(
263245
PLUGIN_INFO_TEMPLATE, std::regex("%1"), PLUGIN_VERSION);
264-
// Check for update
265-
// if (get_latest_version() != nullptr) {
266-
// basic_info += std::regex_replace(
267-
// PLUGIN_INFO_TEMPLATE_UPDATE_AVAILABLE, std::regex("%1"),
268-
// get_latest_version());
269-
// }
270246
obs_properties_add_text(props, "info", basic_info.c_str(),
271247
OBS_TEXT_INFO);
272248

@@ -295,7 +271,7 @@ void detect_filter_defaults(obs_data_t *settings)
295271
obs_data_set_default_string(settings, "masking_color", "#000000");
296272
obs_data_set_default_int(settings, "masking_blur_radius", 0);
297273
obs_data_set_default_bool(settings, "tracking_group", false);
298-
obs_data_set_default_double(settings, "zoom_factor", 1.0);
274+
obs_data_set_default_double(settings, "zoom_factor", 0.0);
299275
obs_data_set_default_string(settings, "zoom_object", "single");
300276
}
301277

@@ -402,6 +378,9 @@ void detect_filter_update(void *data, obs_data_t *settings)
402378

403379
// Load model
404380
try {
381+
if (tf->edgeyolo) {
382+
tf->edgeyolo.reset();
383+
}
405384
tf->edgeyolo = std::make_unique<
406385
edgeyolo_cpp::EdgeYOLOONNXRuntime>(
407386
tf->modelFilepath, tf->numThreads,
@@ -428,6 +407,7 @@ void detect_filter_update(void *data, obs_data_t *settings)
428407
obs_log(LOG_INFO, " Source: %s", obs_source_get_name(tf->source));
429408
obs_log(LOG_INFO, " Inference Device: %s", tf->useGPU.c_str());
430409
obs_log(LOG_INFO, " Num Threads: %d", tf->numThreads);
410+
obs_log(LOG_INFO, " Model Size: %s", tf->modelSize.c_str());
431411
obs_log(LOG_INFO, " Preview: %s", tf->preview ? "true" : "false");
432412
obs_log(LOG_INFO, " Threshold: %.2f", tf->conf_threshold);
433413
obs_log(LOG_INFO, " Object Category: %s",
@@ -483,7 +463,6 @@ void *detect_filter_create(obs_data_t *settings, obs_source_t *source)
483463

484464
tf->source = source;
485465
tf->texrender = gs_texrender_create(GS_BGRA, GS_ZS_NONE);
486-
tf->effect = obs_get_base_effect(OBS_EFFECT_OPAQUE);
487466

488467
char *kawaseBlurEffectPath = obs_module_file(KAWASE_BLUR_EFFECT_PATH);
489468
if (!kawaseBlurEffectPath) {
@@ -493,7 +472,7 @@ void *detect_filter_create(obs_data_t *settings, obs_source_t *source)
493472
}
494473
char *maskingEffectPath = obs_module_file(MASKING_EFFECT_PATH);
495474
if (!maskingEffectPath) {
496-
obs_log(LOG_ERROR, "Failed to get Kawase Blur effect path");
475+
obs_log(LOG_ERROR, "Failed to get masking effect path");
497476
tf->isDisabled = true;
498477
bfree(kawaseBlurEffectPath);
499478
return tf;
@@ -539,6 +518,8 @@ void detect_filter_destroy(void *data)
539518
if (tf->stagesurface) {
540519
gs_stagesurface_destroy(tf->stagesurface);
541520
}
521+
gs_effect_destroy(tf->kawaseBlurEffect);
522+
gs_effect_destroy(tf->maskingEffect);
542523
obs_leave_graphics();
543524
tf->~detect_filter();
544525
bfree(tf);
@@ -588,7 +569,6 @@ void detect_filter_video_tick(void *data, float seconds)
588569
objects = tf->edgeyolo->inference(frame);
589570
} catch (const Ort::Exception &e) {
590571
obs_log(LOG_ERROR, "ONNXRuntime Exception: %s", e.what());
591-
// TODO: Fall back to CPU if it makes sense
592572
} catch (const std::exception &e) {
593573
obs_log(LOG_ERROR, "%s", e.what());
594574
}
@@ -647,10 +627,8 @@ void detect_filter_video_tick(void *data, float seconds)
647627
// calculate an aspect ratio box around the object using its height
648628
float boxHeight = boundingBox.height;
649629
// calculate the zooming box size
650-
// when the zoom factor is 1, the zooming box is the same size as the bounding box
651-
// when the zoom factor is 10, the zooming box is the same size of the image
652630
float dh = (float)frame.rows - boxHeight;
653-
float buffer = dh * ((tf->zoomFactor - 1) / 9);
631+
float buffer = dh * (1.0f - tf->zoomFactor);
654632
float zh = boxHeight + buffer;
655633
float zw = zh * frameAspectRatio;
656634
// calculate the top left corner of the zooming box
@@ -662,7 +640,6 @@ void detect_filter_video_tick(void *data, float seconds)
662640
tf->trackingRect = cv::Rect2f(zx, zy, zw, zh);
663641
} else {
664642
// interpolate the zooming box to tf->trackingRect
665-
// the interpolation factor is (lostTracking) ? 0.1 : 0.5 to make the zooming box move smoothly
666643
float factor = lostTracking ? 0.01f : 0.05f;
667644
tf->trackingRect.x = tf->trackingRect.x +
668645
factor * (zx - tf->trackingRect.x);

0 commit comments

Comments
 (0)