CHECK_LIB([DL], [dl], [dlopen])])
CHECK_WANT([EXR], [auto], [use exr], [])
-CHECK_WANT([FINDOBJECT], [no], [findobject=sys/sta/dyn], [
- WANT_FINDOBJECT="$withval"
+CHECK_WANT([OPENCV], [no], [opencv=sys/sta/dyn,git/tar=url], [
+ WANT_OPENCV="$withval"
])
CHECK_WANT([NUMA], [auto], [system has libnuma], [
echo " using: with-browser = $WANT_CIN_BROWSER"
echo " using: with-plugin-dir = $WANT_PLUGIN_DIR"
echo " using: with-ladspa-dir = $WANT_LADSPA_DIR"
-echo " using: with-findobject = $WANT_FINDOBJECT"
+echo " using: with-opencv = $WANT_OPENCV"
echo ""
echo " using: single-user = $WANT_CINBIN_BUILD"
echo " using: static-build = $WANT_STATIC_BUILD"
ifeq ($(WANT_DVB), yes)
LIVEDVB = liveaudio livevideo
endif
-ifneq ($(WANT_FINDOBJECT), no)
-FINDOBJECT = findobject
+ifneq ($(WANT_OPENCV), no)
+want_var:=$(WANT_OPENCV)
+include $(TOPDIR)/opencv_build
+OPENCV_OBJS := findobj flowobj gaborobj moveobj
+$(OPENCV_OBJS): opencv
endif
# burn must come before any other effecttv plugin
# parametric must come before fourier plugins
# motion must come before perspective
-DIRS = \
+DIRS = $(OPENCV_OBJS) \
1080to480 \
1080to540 \
720to480 \
echo \
echocancel \
fieldframe \
- $(FINDOBJECT) \
flash \
flip \
framefield \
--- /dev/null
+default: all
+
+TOPDIR?=../..
+include $(TOPDIR)/plugin_defs
+
+PLUGIN = findobj
+
+OBJS := \
+ $(OBJDIR)/findobj.o \
+ $(OBJDIR)/findobjwindow.o \
+
+want_var:=$(WANT_OPENCV)
+include $(TOPDIR)/opencv_build
+include $(TOPDIR)/plugin_config
+
+all: opencv
+ +make $(OUTPUT)
+
+$(OBJDIR)/findobj.o: findobj.C findobj.h findobjwindow.h
+$(OBJDIR)/findobjwindow.o: findobjwindow.C findobj.h findobjwindow.h
+
#include "clip.h"
#include "filexml.h"
#include "language.h"
-#include "findobject.h"
-#include "findobjectwindow.h"
+#include "findobj.h"
+#include "findobjwindow.h"
#include "mutex.h"
#include "overlayframe.h"
#include <exception>
#include <unistd.h>
-REGISTER_PLUGIN(FindObjectMain)
+REGISTER_PLUGIN(FindObjMain)
-FindObjectConfig::FindObjectConfig()
+FindObjConfig::FindObjConfig()
{
algorithm = NO_ALGORITHM;
use_flann = 1;
blend = 100;
}
-void FindObjectConfig::boundaries()
+void FindObjConfig::boundaries()
{
bclamp(object_x, 0, 100); bclamp(object_y, 0, 100);
bclamp(object_w, 0, 100); bclamp(object_h, 0, 100);
bclamp(blend, MIN_BLEND, MAX_BLEND);
}
-int FindObjectConfig::equivalent(FindObjectConfig &that)
+int FindObjConfig::equivalent(FindObjConfig &that)
{
int result =
algorithm == that.algorithm &&
return result;
}
-void FindObjectConfig::copy_from(FindObjectConfig &that)
+void FindObjConfig::copy_from(FindObjConfig &that)
{
algorithm = that.algorithm;
use_flann = that.use_flann;
blend = that.blend;
}
-void FindObjectConfig::interpolate(FindObjectConfig &prev, FindObjectConfig &next,
+void FindObjConfig::interpolate(FindObjConfig &prev, FindObjConfig &next,
int64_t prev_frame, int64_t next_frame, int64_t current_frame)
{
copy_from(prev);
}
-FindObjectMain::FindObjectMain(PluginServer *server)
+FindObjMain::FindObjMain(PluginServer *server)
: PluginVClient(server)
{
affine = 0;
init_border = 1;
}
-FindObjectMain::~FindObjectMain()
+FindObjMain::~FindObjMain()
{
delete affine;
delete overlayer;
}
-const char* FindObjectMain::plugin_title() { return _("Find Object"); }
-int FindObjectMain::is_realtime() { return 1; }
-int FindObjectMain::is_multichannel() { return 1; }
+const char* FindObjMain::plugin_title() { return _("Find Object"); }
+int FindObjMain::is_realtime() { return 1; }
+int FindObjMain::is_multichannel() { return 1; }
-NEW_WINDOW_MACRO(FindObjectMain, FindObjectWindow)
-LOAD_CONFIGURATION_MACRO(FindObjectMain, FindObjectConfig)
+NEW_WINDOW_MACRO(FindObjMain, FindObjWindow)
+LOAD_CONFIGURATION_MACRO(FindObjMain, FindObjConfig)
-void FindObjectMain::update_gui()
+void FindObjMain::update_gui()
{
if( !thread ) return;
if( !load_configuration() ) return;
- FindObjectWindow *window = (FindObjectWindow*)thread->window;
- window->lock_window("FindObjectMain::update_gui");
- window->algorithm->set_text(FindObjectAlgorithm::to_text(config.algorithm));
+ FindObjWindow *window = (FindObjWindow*)thread->window;
+ window->lock_window("FindObjMain::update_gui");
+ window->algorithm->set_text(FindObjAlgorithm::to_text(config.algorithm));
window->use_flann->update(config.use_flann);
window->object_x->update(config.object_x);
window->object_x_text->update((float)config.object_x);
window->unlock_window();
}
-void FindObjectMain::save_data(KeyFrame *keyframe)
+void FindObjMain::save_data(KeyFrame *keyframe)
{
FileXML output;
// cause data to be stored directly in text
output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
- output.tag.set_title("FINDOBJECT");
+ output.tag.set_title("FINDOBJ");
output.tag.set_property("ALGORITHM", config.algorithm);
output.tag.set_property("USE_FLANN", config.use_flann);
output.tag.set_property("OBJECT_X", config.object_x);
output.tag.set_property("SCENE_LAYER", config.scene_layer);
output.tag.set_property("BLEND", config.blend);
output.append_tag();
- output.tag.set_title("/FINDOBJECT");
+ output.tag.set_title("/FINDOBJ");
output.append_tag();
output.append_newline();
output.terminate_string();
}
-void FindObjectMain::read_data(KeyFrame *keyframe)
+void FindObjMain::read_data(KeyFrame *keyframe)
{
FileXML input;
int result = 0;
while( !(result = input.read_tag()) ) {
- if( input.tag.title_is("FINDOBJECT") ) {
+ if( input.tag.title_is("FINDOBJ") ) {
config.algorithm = input.tag.get_property("ALGORITHM", config.algorithm);
config.use_flann = input.tag.get_property("USE_FLANN", config.use_flann);
config.object_x = input.tag.get_property("OBJECT_X", config.object_x);
config.boundaries();
}
-void FindObjectMain::draw_line(VFrame *vframe, int x1, int y1, int x2, int y2)
+void FindObjMain::draw_line(VFrame *vframe, int x1, int y1, int x2, int y2)
{
vframe->draw_line(x1, y1, x2, y2);
}
-void FindObjectMain::draw_rect(VFrame *vframe, int x1, int y1, int x2, int y2)
+void FindObjMain::draw_rect(VFrame *vframe, int x1, int y1, int x2, int y2)
{
draw_line(vframe, x1, y1, x2, y1);
draw_line(vframe, x2, y1 + 1, x2, y2);
draw_line(vframe, x1, y2 - 1, x1, y1 + 1);
}
-void FindObjectMain::draw_circle(VFrame *vframe, int x, int y, int r)
+void FindObjMain::draw_circle(VFrame *vframe, int x, int y, int r)
{
int x1 = x-r, x2 = x+r;
int y1 = y-r, y2 = y+r;
vframe->draw_smooth(x,y2, x1,y2, x1,y);
}
-void FindObjectMain::filter_matches(ptV &p1, ptV &p2, double ratio)
+void FindObjMain::filter_matches(ptV &p1, ptV &p2, double ratio)
{
DMatches::iterator it;
for( it=pairs.begin(); it!=pairs.end(); ++it ) {
}
}
-void FindObjectMain::to_mat(Mat &mat, int mcols, int mrows,
+void FindObjMain::to_mat(Mat &mat, int mcols, int mrows,
VFrame *inp, int ix,int iy, BC_CModel mcolor_model)
{
int mcomp = BC_CModels::components(mcolor_model);
// vfrm.write_png(vfn);
}
-void FindObjectMain::detect(Mat &mat, KeyPointV &keypts,Mat &descrs)
+void FindObjMain::detect(Mat &mat, KeyPointV &keypts,Mat &descrs)
{
keypts.clear();
descrs.release();
} catch(std::exception e) { printf(_("detector exception: %s\n"), e.what()); }
}
-void FindObjectMain::match()
+void FindObjMain::match()
{
pairs.clear();
try {
} catch(std::exception e) { printf(_("match execption: %s\n"), e.what()); }
}
-Ptr<DescriptorMatcher> FindObjectMain::flann_kdtree_matcher()
+Ptr<DescriptorMatcher> FindObjMain::flann_kdtree_matcher()
{ // trees=5
const Ptr<flann::IndexParams>& indexParams =
makePtr<flann::KDTreeIndexParams>(5);
makePtr<flann::SearchParams>();
return makePtr<FlannBasedMatcher>(indexParams, searchParams);
}
-Ptr<DescriptorMatcher> FindObjectMain::flann_lshidx_matcher()
+Ptr<DescriptorMatcher> FindObjMain::flann_lshidx_matcher()
{ // table_number = 6#12, key_size = 12#20, multi_probe_level = 1#2
const Ptr<flann::IndexParams>& indexParams =
makePtr<flann::LshIndexParams>(6, 12, 1);
makePtr<flann::SearchParams>();
return makePtr<FlannBasedMatcher>(indexParams, searchParams);
}
-Ptr<DescriptorMatcher> FindObjectMain::bf_matcher_norm_l2()
+Ptr<DescriptorMatcher> FindObjMain::bf_matcher_norm_l2()
{
return BFMatcher::create(NORM_L2);
}
-Ptr<DescriptorMatcher> FindObjectMain::bf_matcher_norm_hamming()
+Ptr<DescriptorMatcher> FindObjMain::bf_matcher_norm_hamming()
{
return BFMatcher::create(NORM_HAMMING);
}
#ifdef _SIFT
-void FindObjectMain::set_sift()
+void FindObjMain::set_sift()
{
cvmodel = BC_GREY8;
detector = SIFT::create();
}
#endif
#ifdef _SURF
-void FindObjectMain::set_surf()
+void FindObjMain::set_surf()
{
cvmodel = BC_GREY8;
detector = SURF::create(800);
}
#endif
#ifdef _ORB
-void FindObjectMain::set_orb()
+void FindObjMain::set_orb()
{
cvmodel = BC_GREY8;
detector = ORB::create();
}
#endif
#ifdef _AKAZE
-void FindObjectMain::set_akaze()
+void FindObjMain::set_akaze()
{
cvmodel = BC_GREY8;
detector = AKAZE::create();
}
#endif
#ifdef _BRISK
-void FindObjectMain::set_brisk()
+void FindObjMain::set_brisk()
{
cvmodel = BC_GREY8;
detector = BRISK::create();
}
#endif
-void FindObjectMain::process_match()
+void FindObjMain::process_match()
{
if( config.algorithm == NO_ALGORITHM ) return;
if( !config.replace_object &&
// dst[0].x,dst[0].y, dst[1].x,dst[1].y, dst[2].x,dst[2].y, dst[3].x,dst[3].y);
}
-int FindObjectMain::process_buffer(VFrame **frame, int64_t start_position, double frame_rate)
+int FindObjMain::process_buffer(VFrame **frame, int64_t start_position, double frame_rate)
{
int prev_algorithm = config.algorithm;
int prev_use_flann = config.use_flann;
-#ifndef FINDOBJECT_H
-#define FINDOBJECT_H
+#ifndef FINDOBJ_H
+#define FINDOBJ_H
//#include "config.h"
#include "bchash.inc"
#include "filexml.inc"
#include "keyframe.inc"
-#include "findobject.inc"
+#include "findobj.inc"
#include "overlayframe.inc"
#include "pluginvclient.h"
#include "vframe.inc"
#define ALGORITHM_AKAZE 4
#define ALGORITHM_BRISK 5
-class FindObjectConfig
+class FindObjConfig
{
public:
- FindObjectConfig();
+ FindObjConfig();
- int equivalent(FindObjectConfig &that);
- void copy_from(FindObjectConfig &that);
- void interpolate(FindObjectConfig &prev, FindObjectConfig &next,
+ int equivalent(FindObjConfig &that);
+ void copy_from(FindObjConfig &that);
+ void interpolate(FindObjConfig &prev, FindObjConfig &next,
int64_t prev_frame, int64_t next_frame, int64_t current_frame);
void boundaries();
int blend;
};
-class FindObjectMain : public PluginVClient
+class FindObjMain : public PluginVClient
{
public:
- FindObjectMain(PluginServer *server);
- ~FindObjectMain();
+ FindObjMain(PluginServer *server);
+ ~FindObjMain();
int process_buffer(VFrame **frame, int64_t start_position, double frame_rate);
#ifdef _SIFT
void read_data(KeyFrame *keyframe);
void update_gui();
- PLUGIN_CLASS_MEMBERS2(FindObjectConfig)
+ PLUGIN_CLASS_MEMBERS2(FindObjConfig)
AffineEngine *affine;
OverlayFrame *overlayer;
*
*/
-#ifndef FINDOBJECT_INC
-#define FINDOBJECT_INC
+#ifndef FINDOBJ_INC
+#define FINDOBJ_INC
-class FindObjectConfig;
-class FindObjectMain;
+class FindObjConfig;
+class FindObjMain;
#endif
#include "bcdisplayinfo.h"
#include "clip.h"
#include "language.h"
-#include "findobject.h"
-#include "findobjectwindow.h"
+#include "findobj.h"
+#include "findobjwindow.h"
#include "theme.h"
-FindObjectWindow::FindObjectWindow(FindObjectMain *plugin)
+FindObjWindow::FindObjWindow(FindObjMain *plugin)
: PluginClientWindow(plugin, 340, 660, 340, 660, 0)
{
this->plugin = plugin;
}
-FindObjectWindow::~FindObjectWindow()
+FindObjWindow::~FindObjWindow()
{
}
-void FindObjectWindow::create_objects()
+void FindObjWindow::create_objects()
{
int x = 10, y = 10, x1 = x, x2 = get_w()/2;
plugin->load_configuration();
BC_Title *title;
add_subwindow(title = new BC_Title(x1, y, _("Algorithm:")));
- add_subwindow(algorithm = new FindObjectAlgorithm(plugin, this,
+ add_subwindow(algorithm = new FindObjAlgorithm(plugin, this,
x1 + title->get_w() + 10, y));
algorithm->create_objects();
y += algorithm->get_h() + plugin->get_theme()->widget_border;
- add_subwindow(use_flann = new FindObjectUseFlann(plugin, this, x, y));
+ add_subwindow(use_flann = new FindObjUseFlann(plugin, this, x, y));
y += use_flann->get_h() + plugin->get_theme()->widget_border + 20;
int x0 = x + 200;
add_subwindow(title = new BC_Title(x, y, _("Output/scene layer:")));
- scene_layer = new FindObjectLayer(plugin, this, x0, y,
+ scene_layer = new FindObjLayer(plugin, this, x0, y,
&plugin->config.scene_layer);
scene_layer->create_objects();
y += scene_layer->get_h() + plugin->get_theme()->widget_border;
add_subwindow(title = new BC_Title(x, y, _("Object layer:")));
- object_layer = new FindObjectLayer(plugin, this, x0, y,
+ object_layer = new FindObjLayer(plugin, this, x0, y,
&plugin->config.object_layer);
object_layer->create_objects();
y += object_layer->get_h() + plugin->get_theme()->widget_border;
add_subwindow(title = new BC_Title(x, y, _("Replacement object layer:")));
- replace_layer = new FindObjectLayer(plugin, this, x0, y,
+ replace_layer = new FindObjLayer(plugin, this, x0, y,
&plugin->config.replace_layer);
replace_layer->create_objects();
y += replace_layer->get_h() + plugin->get_theme()->widget_border + 10;
int y1 = y;
add_subwindow(new BC_Title(x1, y + 10, _("Scene X:")));
y += title->get_h() + 15;
- add_subwindow(scene_x = new FindObjectScanFloat(plugin, this,
+ add_subwindow(scene_x = new FindObjScanFloat(plugin, this,
x1, y, &plugin->config.scene_x));
- add_subwindow(scene_x_text = new FindObjectScanFloatText(plugin, this,
+ add_subwindow(scene_x_text = new FindObjScanFloatText(plugin, this,
x1 + scene_x->get_w() + 10, y + 10, &plugin->config.scene_x));
scene_x->center_text = scene_x_text;
scene_x_text->center = scene_x;
y += 40;
add_subwindow(title = new BC_Title(x1, y + 10, _("Scene Y:")));
y += title->get_h() + 15;
- add_subwindow(scene_y = new FindObjectScanFloat(plugin, this,
+ add_subwindow(scene_y = new FindObjScanFloat(plugin, this,
x1, y, &plugin->config.scene_y));
- add_subwindow(scene_y_text = new FindObjectScanFloatText(plugin, this,
+ add_subwindow(scene_y_text = new FindObjScanFloatText(plugin, this,
x1 + scene_y->get_w() + 10, y + 10, &plugin->config.scene_y));
scene_y->center_text = scene_y_text;
scene_y_text->center = scene_y;
y += 40;
add_subwindow(new BC_Title(x1, y + 10, _("Scene W:")));
y += title->get_h() + 15;
- add_subwindow(scene_w = new FindObjectScanFloat(plugin, this,
+ add_subwindow(scene_w = new FindObjScanFloat(plugin, this,
x1, y, &plugin->config.scene_w));
- add_subwindow(scene_w_text = new FindObjectScanFloatText(plugin, this,
+ add_subwindow(scene_w_text = new FindObjScanFloatText(plugin, this,
x1 + scene_w->get_w() + 10, y + 10, &plugin->config.scene_w));
scene_w->center_text = scene_w_text;
scene_w_text->center = scene_w;
y += 40;
add_subwindow(title = new BC_Title(x1, y + 10, _("Scene H:")));
y += title->get_h() + 15;
- add_subwindow(scene_h = new FindObjectScanFloat(plugin, this,
+ add_subwindow(scene_h = new FindObjScanFloat(plugin, this,
x1, y, &plugin->config.scene_h));
- add_subwindow(scene_h_text = new FindObjectScanFloatText(plugin, this,
+ add_subwindow(scene_h_text = new FindObjScanFloatText(plugin, this,
x1 + scene_h->get_w() + 10, y + 10,
&plugin->config.scene_h));
scene_h->center_text = scene_h_text;
y = y1;
add_subwindow(new BC_Title(x2, y + 10, _("Object X:")));
y += title->get_h() + 15;
- add_subwindow(object_x = new FindObjectScanFloat(plugin, this,
+ add_subwindow(object_x = new FindObjScanFloat(plugin, this,
x2, y, &plugin->config.object_x));
- add_subwindow(object_x_text = new FindObjectScanFloatText(plugin, this,
+ add_subwindow(object_x_text = new FindObjScanFloatText(plugin, this,
x2 + object_x->get_w() + 10, y + 10, &plugin->config.object_x));
object_x->center_text = object_x_text;
object_x_text->center = object_x;
y += 40;
add_subwindow(title = new BC_Title(x2, y + 10, _("Object Y:")));
y += title->get_h() + 15;
- add_subwindow(object_y = new FindObjectScanFloat(plugin, this,
+ add_subwindow(object_y = new FindObjScanFloat(plugin, this,
x2, y, &plugin->config.object_y));
- add_subwindow(object_y_text = new FindObjectScanFloatText(plugin, this,
+ add_subwindow(object_y_text = new FindObjScanFloatText(plugin, this,
x2 + object_y->get_w() + 10, y + 10, &plugin->config.object_y));
object_y->center_text = object_y_text;
object_y_text->center = object_y;
y += 40;
add_subwindow(new BC_Title(x2, y + 10, _("Object W:")));
y += title->get_h() + 15;
- add_subwindow(object_w = new FindObjectScanFloat(plugin, this,
+ add_subwindow(object_w = new FindObjScanFloat(plugin, this,
x2, y, &plugin->config.object_w));
- add_subwindow(object_w_text = new FindObjectScanFloatText(plugin, this,
+ add_subwindow(object_w_text = new FindObjScanFloatText(plugin, this,
x2 + object_w->get_w() + 10, y + 10, &plugin->config.object_w));
object_w->center_text = object_w_text;
object_w_text->center = object_w;
y += 40;
add_subwindow(title = new BC_Title(x2, y + 10, _("Object H:")));
y += title->get_h() + 15;
- add_subwindow(object_h = new FindObjectScanFloat(plugin, this,
+ add_subwindow(object_h = new FindObjScanFloat(plugin, this,
x2, y, &plugin->config.object_h));
- add_subwindow(object_h_text = new FindObjectScanFloatText(plugin, this,
+ add_subwindow(object_h_text = new FindObjScanFloatText(plugin, this,
x2 + object_h->get_w() + 10, y + 10,
&plugin->config.object_h));
object_h->center_text = object_h_text;
object_h_text->center = object_h;
y += 40 + 15;
- add_subwindow(draw_keypoints = new FindObjectDrawKeypoints(plugin, this, x, y));
+ add_subwindow(draw_keypoints = new FindObjDrawKeypoints(plugin, this, x, y));
y += draw_keypoints->get_h() + plugin->get_theme()->widget_border;
- add_subwindow(draw_border = new FindObjectDrawBorder(plugin, this, x, y));
+ add_subwindow(draw_border = new FindObjDrawBorder(plugin, this, x, y));
y += draw_border->get_h() + plugin->get_theme()->widget_border;
- add_subwindow(replace_object = new FindObjectReplace(plugin, this, x, y));
+ add_subwindow(replace_object = new FindObjReplace(plugin, this, x, y));
y += replace_object->get_h() + plugin->get_theme()->widget_border;
- add_subwindow(draw_object_border = new FindObjectDrawObjectBorder(plugin, this, x, y));
+ add_subwindow(draw_object_border = new FindObjDrawObjectBorder(plugin, this, x, y));
y += draw_object_border->get_h() + plugin->get_theme()->widget_border;
add_subwindow(title = new BC_Title(x, y + 10, _("Object blend amount:")));
- add_subwindow(blend = new FindObjectBlend(plugin,
+ add_subwindow(blend = new FindObjBlend(plugin,
x + title->get_w() + plugin->get_theme()->widget_border, y,
&plugin->config.blend));
y += blend->get_h();
}
-FindObjectScanFloat::FindObjectScanFloat(FindObjectMain *plugin, FindObjectWindow *gui,
+FindObjScanFloat::FindObjScanFloat(FindObjMain *plugin, FindObjWindow *gui,
int x, int y, float *value)
: BC_FPot(x, y, *value, (float)0, (float)100)
{
set_precision(0.1);
}
-int FindObjectScanFloat::handle_event()
+int FindObjScanFloat::handle_event()
{
*value = get_value();
center_text->update(*value);
}
-FindObjectScanFloatText::FindObjectScanFloatText(FindObjectMain *plugin, FindObjectWindow *gui,
+FindObjScanFloatText::FindObjScanFloatText(FindObjMain *plugin, FindObjWindow *gui,
int x, int y, float *value)
: BC_TextBox(x, y, 75, 1, *value)
{
set_precision(1);
}
-int FindObjectScanFloatText::handle_event()
+int FindObjScanFloatText::handle_event()
{
*value = atof(get_text());
center->update(*value);
}
-FindObjectDrawBorder::FindObjectDrawBorder(FindObjectMain *plugin, FindObjectWindow *gui,
+FindObjDrawBorder::FindObjDrawBorder(FindObjMain *plugin, FindObjWindow *gui,
int x, int y)
: BC_CheckBox(x, y, plugin->config.draw_border, _("Draw border"))
{
this->plugin = plugin;
}
-int FindObjectDrawBorder::handle_event()
+int FindObjDrawBorder::handle_event()
{
plugin->config.draw_border = get_value();
plugin->send_configure_change();
}
-FindObjectDrawKeypoints::FindObjectDrawKeypoints(FindObjectMain *plugin, FindObjectWindow *gui,
+FindObjDrawKeypoints::FindObjDrawKeypoints(FindObjMain *plugin, FindObjWindow *gui,
int x, int y)
: BC_CheckBox(x, y, plugin->config.draw_keypoints, _("Draw keypoints"))
{
this->plugin = plugin;
}
-int FindObjectDrawKeypoints::handle_event()
+int FindObjDrawKeypoints::handle_event()
{
plugin->config.draw_keypoints = get_value();
plugin->send_configure_change();
}
-FindObjectReplace::FindObjectReplace(FindObjectMain *plugin, FindObjectWindow *gui,
+FindObjReplace::FindObjReplace(FindObjMain *plugin, FindObjWindow *gui,
int x, int y)
: BC_CheckBox(x, y, plugin->config.replace_object, _("Replace object"))
{
this->plugin = plugin;
}
-int FindObjectReplace::handle_event()
+int FindObjReplace::handle_event()
{
plugin->config.replace_object = get_value();
plugin->send_configure_change();
}
-FindObjectDrawObjectBorder::FindObjectDrawObjectBorder(FindObjectMain *plugin, FindObjectWindow *gui,
+FindObjDrawObjectBorder::FindObjDrawObjectBorder(FindObjMain *plugin, FindObjWindow *gui,
int x, int y)
: BC_CheckBox(x, y, plugin->config.draw_object_border, _("Draw object border"))
{
this->plugin = plugin;
}
-int FindObjectDrawObjectBorder::handle_event()
+int FindObjDrawObjectBorder::handle_event()
{
plugin->config.draw_object_border = get_value();
plugin->send_configure_change();
}
-FindObjectAlgorithm::FindObjectAlgorithm(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y)
+FindObjAlgorithm::FindObjAlgorithm(FindObjMain *plugin, FindObjWindow *gui, int x, int y)
: BC_PopupMenu(x, y, calculate_w(gui), to_text(plugin->config.algorithm))
{
this->plugin = plugin;
this->gui = gui;
}
-int FindObjectAlgorithm::handle_event()
+int FindObjAlgorithm::handle_event()
{
plugin->config.algorithm = from_text(get_text());
plugin->send_configure_change();
return 1;
}
-void FindObjectAlgorithm::create_objects()
+void FindObjAlgorithm::create_objects()
{
add_item(new BC_MenuItem(to_text(NO_ALGORITHM)));
#ifdef _SIFT
#endif
}
-int FindObjectAlgorithm::from_text(char *text)
+int FindObjAlgorithm::from_text(char *text)
{
#ifdef _SIFT
if(!strcmp(text, _("SIFT"))) return ALGORITHM_SIFT;
return NO_ALGORITHM;
}
-char* FindObjectAlgorithm::to_text(int mode)
+char* FindObjAlgorithm::to_text(int mode)
{
switch( mode ) {
#ifdef _SIFT
return _("Don't Calculate");
}
-int FindObjectAlgorithm::calculate_w(FindObjectWindow *gui)
+int FindObjAlgorithm::calculate_w(FindObjWindow *gui)
{
int result = 0;
result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(NO_ALGORITHM)));
}
-FindObjectUseFlann::FindObjectUseFlann(FindObjectMain *plugin, FindObjectWindow *gui,
+FindObjUseFlann::FindObjUseFlann(FindObjMain *plugin, FindObjWindow *gui,
int x, int y)
: BC_CheckBox(x, y, plugin->config.use_flann, _("Use FLANN"))
{
this->plugin = plugin;
}
-int FindObjectUseFlann::handle_event()
+int FindObjUseFlann::handle_event()
{
plugin->config.use_flann = get_value();
plugin->send_configure_change();
}
-FindObjectLayer::FindObjectLayer(FindObjectMain *plugin, FindObjectWindow *gui,
+FindObjLayer::FindObjLayer(FindObjMain *plugin, FindObjWindow *gui,
int x, int y, int *value)
: BC_TumbleTextBox(gui, *value, MIN_LAYER, MAX_LAYER, x, y, calculate_w(gui))
{
this->value = value;
}
-int FindObjectLayer::handle_event()
+int FindObjLayer::handle_event()
{
*value = atoi(get_text());
plugin->send_configure_change();
return 1;
}
-int FindObjectLayer::calculate_w(FindObjectWindow *gui)
+int FindObjLayer::calculate_w(FindObjWindow *gui)
{
int result = 0;
result = gui->get_text_width(MEDIUMFONT, "000");
}
-FindObjectBlend::FindObjectBlend(FindObjectMain *plugin,
+FindObjBlend::FindObjBlend(FindObjMain *plugin,
int x,
int y,
int *value)
this->value = value;
}
-int FindObjectBlend::handle_event()
+int FindObjBlend::handle_event()
{
*value = (int)get_value();
plugin->send_configure_change();
--- /dev/null
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#ifndef __FINDOBJWINDOW_H__
+#define __FINDOBJWINDOW_H__
+
+#include "guicast.h"
+#include "findobj.inc"
+
+class FindObjLayer;
+class FindObjScanFloat;
+class FindObjScanFloatText;
+class FindObjDrawBorder;
+class FindObjDrawKeypoints;
+class FindObjReplace;
+class FindObjDrawObjectBorder;
+class FindObjAlgorithm;
+class FindObjBlend;
+class FindObjWindow;
+
+class FindObjLayer : public BC_TumbleTextBox
+{
+public:
+ FindObjLayer(FindObjMain *plugin, FindObjWindow *gui,
+ int x, int y, int *value);
+ int handle_event();
+ static int calculate_w(FindObjWindow *gui);
+ FindObjMain *plugin;
+ FindObjWindow *gui;
+ int *value;
+};
+
+class FindObjScanFloat : public BC_FPot
+{
+public:
+ FindObjScanFloat(FindObjMain *plugin, FindObjWindow *gui, int x, int y, float *value);
+ int handle_event();
+ FindObjMain *plugin;
+ FindObjWindow *gui;
+ FindObjScanFloatText *center_text;
+ float *value;
+};
+
+class FindObjScanFloatText : public BC_TextBox
+{
+public:
+ FindObjScanFloatText(FindObjMain *plugin, FindObjWindow *gui, int x, int y, float *value);
+ int handle_event();
+ FindObjWindow *gui;
+ FindObjMain *plugin;
+ FindObjScanFloat *center;
+ float *value;
+};
+
+
+class FindObjDrawBorder : public BC_CheckBox
+{
+public:
+ FindObjDrawBorder(FindObjMain *plugin, FindObjWindow *gui, int x, int y);
+ int handle_event();
+ FindObjMain *plugin;
+ FindObjWindow *gui;
+};
+
+class FindObjDrawKeypoints : public BC_CheckBox
+{
+public:
+ FindObjDrawKeypoints(FindObjMain *plugin, FindObjWindow *gui, int x, int y);
+ int handle_event();
+ FindObjMain *plugin;
+ FindObjWindow *gui;
+};
+
+class FindObjReplace : public BC_CheckBox
+{
+public:
+ FindObjReplace(FindObjMain *plugin, FindObjWindow *gui, int x, int y);
+ int handle_event();
+ FindObjMain *plugin;
+ FindObjWindow *gui;
+};
+
+class FindObjDrawObjectBorder : public BC_CheckBox
+{
+public:
+ FindObjDrawObjectBorder(FindObjMain *plugin, FindObjWindow *gui, int x, int y);
+ int handle_event();
+ FindObjMain *plugin;
+ FindObjWindow *gui;
+};
+
+class FindObjAlgorithm : public BC_PopupMenu
+{
+public:
+ FindObjAlgorithm(FindObjMain *plugin, FindObjWindow *gui, int x, int y);
+ int handle_event();
+ void create_objects();
+ static int calculate_w(FindObjWindow *gui);
+ static int from_text(char *text);
+ static char* to_text(int mode);
+ FindObjMain *plugin;
+ FindObjWindow *gui;
+};
+
+class FindObjUseFlann : public BC_CheckBox
+{
+public:
+ FindObjUseFlann(FindObjMain *plugin, FindObjWindow *gui, int x, int y);
+ int handle_event();
+ FindObjMain *plugin;
+ FindObjWindow *gui;
+};
+
+class FindObjBlend : public BC_IPot
+{
+public:
+ FindObjBlend(FindObjMain *plugin, int x, int y, int *value);
+ int handle_event();
+ FindObjMain *plugin;
+ int *value;
+};
+
+class FindObjWindow : public PluginClientWindow
+{
+public:
+ FindObjWindow(FindObjMain *plugin);
+ ~FindObjWindow();
+ void create_objects();
+
+ FindObjAlgorithm *algorithm;
+ FindObjUseFlann *use_flann;
+ FindObjScanFloat *object_x, *object_y, *object_w, *object_h;
+ FindObjScanFloatText *object_x_text, *object_y_text, *object_w_text, *object_h_text;
+ FindObjScanFloat *scene_x, *scene_y, *scene_w, *scene_h;
+ FindObjScanFloatText *scene_x_text, *scene_y_text, *scene_w_text, *scene_h_text;
+ FindObjDrawKeypoints *draw_keypoints;
+ FindObjDrawBorder *draw_border;
+ FindObjReplace *replace_object;
+ FindObjDrawObjectBorder *draw_object_border;
+ FindObjLayer *object_layer;
+ FindObjLayer *scene_layer;
+ FindObjLayer *replace_layer;
+ FindObjBlend *blend;
+ FindObjMain *plugin;
+};
+
+#endif
*
*/
-#ifndef FINDOBJECTWINDOW_INC
-#define FINDOBJECTWINDOW_INC
+#ifndef FINDOBJWINDOW_INC
+#define FINDOBJWINDOW_INC
-class FindObjectLayer;
-class FindObjectScanFloat;
-class FindObjectScanFloatText;
-class FindObjectDrawBorder;
-class FindObjectDrawKeypoints;
-class FindObjectReplace;
-class FindObjectDrawObjectBorder;
-class FindObjectAlgorithm;
-class FindObjectUseFlann;
-class FindObjectBlend;
-class FindObjectWindow;
+class FindObjLayer;
+class FindObjScanFloat;
+class FindObjScanFloatText;
+class FindObjDrawBorder;
+class FindObjDrawKeypoints;
+class FindObjReplace;
+class FindObjDrawObjectBorder;
+class FindObjAlgorithm;
+class FindObjUseFlann;
+class FindObjBlend;
+class FindObjWindow;
#endif
+++ /dev/null
-default: all
-
-TOPDIR?=../..
-include $(TOPDIR)/plugin_defs
-
-PLUGIN = findobject
-
-OBJS := \
- $(OBJDIR)/findobject.o \
- $(OBJDIR)/findobjectwindow.o \
-
-want_var:=$(WANT_FINDOBJECT)
-include $(TOPDIR)/opencv_build
-include $(TOPDIR)/plugin_config
-
-all: opencv
- +make $(OUTPUT)
-
-$(OBJDIR)/findobject.o: findobject.C findobject.h findobjectwindow.h
-$(OBJDIR)/findobjectwindow.o: findobjectwindow.C findobject.h findobjectwindow.h
-
+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-
-#ifndef __FINDOBJECTWINDOW_H__
-#define __FINDOBJECTWINDOW_H__
-
-#include "guicast.h"
-#include "findobject.inc"
-
-class FindObjectLayer;
-class FindObjectScanFloat;
-class FindObjectScanFloatText;
-class FindObjectDrawBorder;
-class FindObjectDrawKeypoints;
-class FindObjectReplace;
-class FindObjectDrawObjectBorder;
-class FindObjectAlgorithm;
-class FindObjectBlend;
-class FindObjectWindow;
-
-class FindObjectLayer : public BC_TumbleTextBox
-{
-public:
- FindObjectLayer(FindObjectMain *plugin, FindObjectWindow *gui,
- int x, int y, int *value);
- int handle_event();
- static int calculate_w(FindObjectWindow *gui);
- FindObjectMain *plugin;
- FindObjectWindow *gui;
- int *value;
-};
-
-class FindObjectScanFloat : public BC_FPot
-{
-public:
- FindObjectScanFloat(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y, float *value);
- int handle_event();
- FindObjectMain *plugin;
- FindObjectWindow *gui;
- FindObjectScanFloatText *center_text;
- float *value;
-};
-
-class FindObjectScanFloatText : public BC_TextBox
-{
-public:
- FindObjectScanFloatText(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y, float *value);
- int handle_event();
- FindObjectWindow *gui;
- FindObjectMain *plugin;
- FindObjectScanFloat *center;
- float *value;
-};
-
-
-class FindObjectDrawBorder : public BC_CheckBox
-{
-public:
- FindObjectDrawBorder(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
- int handle_event();
- FindObjectMain *plugin;
- FindObjectWindow *gui;
-};
-
-class FindObjectDrawKeypoints : public BC_CheckBox
-{
-public:
- FindObjectDrawKeypoints(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
- int handle_event();
- FindObjectMain *plugin;
- FindObjectWindow *gui;
-};
-
-class FindObjectReplace : public BC_CheckBox
-{
-public:
- FindObjectReplace(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
- int handle_event();
- FindObjectMain *plugin;
- FindObjectWindow *gui;
-};
-
-class FindObjectDrawObjectBorder : public BC_CheckBox
-{
-public:
- FindObjectDrawObjectBorder(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
- int handle_event();
- FindObjectMain *plugin;
- FindObjectWindow *gui;
-};
-
-class FindObjectAlgorithm : public BC_PopupMenu
-{
-public:
- FindObjectAlgorithm(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
- int handle_event();
- void create_objects();
- static int calculate_w(FindObjectWindow *gui);
- static int from_text(char *text);
- static char* to_text(int mode);
- FindObjectMain *plugin;
- FindObjectWindow *gui;
-};
-
-class FindObjectUseFlann : public BC_CheckBox
-{
-public:
- FindObjectUseFlann(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
- int handle_event();
- FindObjectMain *plugin;
- FindObjectWindow *gui;
-};
-
-class FindObjectBlend : public BC_IPot
-{
-public:
- FindObjectBlend(FindObjectMain *plugin, int x, int y, int *value);
- int handle_event();
- FindObjectMain *plugin;
- int *value;
-};
-
-class FindObjectWindow : public PluginClientWindow
-{
-public:
- FindObjectWindow(FindObjectMain *plugin);
- ~FindObjectWindow();
- void create_objects();
-
- FindObjectAlgorithm *algorithm;
- FindObjectUseFlann *use_flann;
- FindObjectScanFloat *object_x, *object_y, *object_w, *object_h;
- FindObjectScanFloatText *object_x_text, *object_y_text, *object_w_text, *object_h_text;
- FindObjectScanFloat *scene_x, *scene_y, *scene_w, *scene_h;
- FindObjectScanFloatText *scene_x_text, *scene_y_text, *scene_w_text, *scene_h_text;
- FindObjectDrawKeypoints *draw_keypoints;
- FindObjectDrawBorder *draw_border;
- FindObjectReplace *replace_object;
- FindObjectDrawObjectBorder *draw_object_border;
- FindObjectLayer *object_layer;
- FindObjectLayer *scene_layer;
- FindObjectLayer *replace_layer;
- FindObjectBlend *blend;
- FindObjectMain *plugin;
-};
-
-#endif
--- /dev/null
+default: all
+
+TOPDIR?=../..
+include $(TOPDIR)/plugin_defs
+
+PLUGIN = flowobj
+
+OBJS := \
+ $(OBJDIR)/flowobj.o \
+ $(OBJDIR)/flowobjwindow.o \
+
+want_var:=$(WANT_OPENCV)
+include $(TOPDIR)/opencv_build
+include $(TOPDIR)/plugin_config
+
+all: opencv
+ +make $(OUTPUT)
+
+$(OBJDIR)/flowobj.o: flowobj.C flowobj.h flowobjwindow.h
+$(OBJDIR)/flowobjwindow.o: flowobjwindow.C flowobj.h flowobjwindow.h
+
--- /dev/null
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "clip.h"
+#include "filexml.h"
+#include "flowobj.h"
+#include "flowobjwindow.h"
+#include "language.h"
+#include "transportque.inc"
+
+REGISTER_PLUGIN(FlowObj)
+
+#define MAX_COUNT 250
+#define WIN_SIZE 20
+
+FlowObjConfig::FlowObjConfig()
+{
+ draw_vectors = 0;
+ do_stabilization = 1;
+ block_size = 20;
+ search_radius = 10;
+ settling_speed = 5;
+}
+
+int FlowObjConfig::equivalent(FlowObjConfig &that)
+{
+ return draw_vectors == that.draw_vectors &&
+ do_stabilization == that.do_stabilization &&
+ block_size == that.block_size &&
+ search_radius == that.search_radius &&
+ settling_speed == that.settling_speed;
+}
+
+void FlowObjConfig::copy_from(FlowObjConfig &that)
+{
+ draw_vectors = that.draw_vectors;
+ do_stabilization = that.do_stabilization;
+ block_size = that.block_size;
+ search_radius = that.search_radius;
+ settling_speed = that.settling_speed;
+}
+
+void FlowObjConfig::interpolate( FlowObjConfig &prev, FlowObjConfig &next,
+ long prev_frame, long next_frame, long current_frame)
+{
+ copy_from(next);
+}
+
+void FlowObjConfig::limits()
+{
+ bclamp(block_size, 5, 100);
+ bclamp(search_radius, 1, 100);
+ bclamp(settling_speed, 0, 100);
+}
+
+
+FlowObj::FlowObj(PluginServer *server)
+ : PluginVClient(server)
+{
+ flow_engine = 0;
+ overlay = 0;
+ accum = 0;
+ prev_position = next_position = -1;
+ x_accum = y_accum = 0;
+ angle_accum = 0;
+ prev_corners = 0;
+ next_corners = 0;
+}
+
+FlowObj::~FlowObj()
+{
+ delete flow_engine;
+ delete overlay;
+ delete prev_corners;
+ delete next_corners;
+}
+
+const char* FlowObj::plugin_title() { return N_("FlowObj"); }
+int FlowObj::is_realtime() { return 1; }
+
+NEW_WINDOW_MACRO(FlowObj, FlowObjWindow);
+LOAD_CONFIGURATION_MACRO(FlowObj, FlowObjConfig)
+
+void FlowObj::save_data(KeyFrame *keyframe)
+{
+ FileXML output;
+
+// cause data to be stored directly in text
+ output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+ output.tag.set_title("FLOWOBJ");
+ output.tag.set_property("DRAW_VECTORS", config.draw_vectors);
+ output.tag.set_property("DO_STABILIZATION", config.do_stabilization);
+ output.tag.set_property("BLOCK_SIZE", config.block_size);
+ output.tag.set_property("SEARCH_RADIUS", config.search_radius);
+ output.tag.set_property("SETTLING_SPEED", config.settling_speed);
+ output.append_tag();
+ output.append_newline();
+ output.tag.set_title("/FLOWOBJ");
+ output.append_tag();
+ output.append_newline();
+ output.terminate_string();
+}
+
+void FlowObj::read_data(KeyFrame *keyframe)
+{
+ FileXML input;
+ input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+
+ int result = 0;
+ while( !(result = input.read_tag()) ) {
+ if( input.tag.title_is("FLOWOBJ") ) {
+ config.draw_vectors = input.tag.get_property("DRAW_VECTORS", config.draw_vectors);
+ config.do_stabilization = input.tag.get_property("DO_STABILIZATION", config.do_stabilization);
+ config.block_size = input.tag.get_property("BLOCK_SIZE", config.block_size);
+ config.search_radius = input.tag.get_property("SEARCH_RADIUS", config.search_radius);
+ config.settling_speed = input.tag.get_property("SETTLING_SPEED", config.settling_speed);
+ config.limits();
+ }
+ else if( input.tag.title_is("/FLOWOBJ") )
+ result = 1;
+ }
+}
+
+void FlowObj::update_gui()
+{
+ if( !thread ) return;
+ if( !load_configuration() ) return;
+ thread->window->lock_window("FlowObj::update_gui");
+ FlowObjWindow *window = (FlowObjWindow*)thread->window;
+
+ window->vectors->update(config.draw_vectors);
+ window->do_stabilization->update(config.do_stabilization);
+ window->block_size->update(config.block_size);
+ window->search_radius->update(config.search_radius);
+ window->settling_speed->update(config.settling_speed);
+
+ thread->window->unlock_window();
+}
+
+void FlowObj::to_mat(Mat &mat, int mcols, int mrows,
+ VFrame *inp, int ix,int iy, int mcolor_model)
+{
+ int mcomp = BC_CModels::components(mcolor_model);
+ int mbpp = BC_CModels::calculate_pixelsize(mcolor_model);
+ int psz = mbpp / mcomp;
+ int mdepth = psz < 2 ? CV_8U : psz < 4 ? CV_16U : CV_32F;
+ if( mat.dims != 2 || mat.depth() != mdepth || mat.channels() != mcomp ||
+ mat.cols != mcols || mat.rows != mrows ) {
+ mat.release();
+ }
+ if( mat.empty() ) {
+ int type = CV_MAKETYPE(mdepth, mcomp);
+ mat.create(mrows, mcols, type);
+ }
+ uint8_t *mat_rows[mrows];
+ for( int y=0; y<mrows; ++y ) mat_rows[y] = mat.ptr(y);
+ uint8_t **inp_rows = inp->get_rows();
+ int ibpl = inp->get_bytes_per_line(), mbpl = mcols * mbpp;
+ int icolor_model = inp->get_color_model();
+ BC_CModels::transfer(mat_rows, mcolor_model, 0,0, mcols,mrows, mbpl,
+ inp_rows, icolor_model, ix,iy, mcols,mrows, ibpl, 0);
+// VFrame vfrm(mat_rows[0], -1, mcols,mrows, mcolor_model, mat_rows[1]-mat_rows[0]);
+// static int vfrm_no = 0; char vfn[64]; sprintf(vfn,"/tmp/idat/%06d.png", vfrm_no++);
+// vfrm.write_png(vfn);
+}
+
+void FlowObj::from_mat(VFrame *out, int ox, int oy, int ow, int oh, Mat &mat, int mcolor_model)
+{
+ int mbpp = BC_CModels::calculate_pixelsize(mcolor_model);
+ int mrows = mat.rows, mcols = mat.cols;
+ uint8_t *mat_rows[mrows];
+ for( int y=0; y<mrows; ++y ) mat_rows[y] = mat.ptr(y);
+ uint8_t **out_rows = out->get_rows();
+ int obpl = out->get_bytes_per_line(), mbpl = mcols * mbpp;
+ int ocolor_model = out->get_color_model();
+ BC_CModels::transfer(out_rows, ocolor_model, ox,oy, ow,oh, obpl,
+ mat_rows, mcolor_model, 0,0, mcols,mrows, mbpl, 0);
+// static int vfrm_no = 0; char vfn[64]; sprintf(vfn,"/tmp/odat/%06d.png", vfrm_no++);
+// out->write_png(vfn);
+}
+
+
+int FlowObj::process_buffer(VFrame *frame, int64_t start_position, double frame_rate)
+{
+
+ //int need_reconfigure =
+ load_configuration();
+ input = get_input(0);
+ output = get_output(0);
+ width = input->get_w();
+ height = input->get_h();
+ color_model = input->get_color_model();
+
+ if( accum_matrix.empty() ) {
+ accum_matrix = Mat::eye(3,3, CV_64F);
+ }
+ if( !prev_corners ) prev_corners = new ptV();
+ if( !next_corners ) next_corners = new ptV();
+
+// Get the position of previous reference frame.
+ int64_t actual_previous_number = start_position;
+ int skip_current = 0;
+ if( get_direction() == PLAY_REVERSE ) {
+ if( ++actual_previous_number < get_source_start() + get_total_len() ) {
+ KeyFrame *keyframe = get_next_keyframe(start_position, 1);
+ if( keyframe->position > 0 &&
+ actual_previous_number >= keyframe->position )
+ skip_current = 1;
+ }
+ else
+ skip_current = 1;
+ }
+ else {
+ if( --actual_previous_number >= get_source_start() ) {
+ KeyFrame *keyframe = get_prev_keyframe(start_position, 1);
+ if( keyframe->position > 0 &&
+ actual_previous_number < keyframe->position)
+ skip_current = 1;
+ }
+ else
+ skip_current = 1;
+ }
+
+
+// move currrent image to previous position
+ if( next_position >= 0 && next_position == actual_previous_number ) {
+ Mat mat = prev_mat; prev_mat = next_mat; next_mat = mat;
+ ptV *pts = prev_corners; prev_corners = next_corners; next_corners = pts;
+ prev_position = next_position;
+ }
+ else
+// load previous image
+ if( actual_previous_number >= 0 ) {
+ read_frame(input, 0, actual_previous_number, frame_rate, 0);
+ to_mat(prev_mat, width,height, input, 0,0, BC_GREY8);
+ }
+
+ if( skip_current || prev_position != actual_previous_number ) {
+ skip_current = 1;
+ accum_matrix = Mat::eye(3,3, CV_64F);
+ }
+
+
+// load next image
+ next_position = start_position;
+ VFrame *iframe = new_temp(width,height, color_model);
+ read_frame(iframe, 0, start_position, frame_rate, 0);
+ input = iframe;
+ to_mat(next_mat, width,height, iframe, 0,0, BC_GREY8);
+
+ int corner_count = MAX_COUNT;
+ int block_size = config.block_size;
+ int min_distance = config.search_radius;
+
+ goodFeaturesToTrack(next_mat,
+ *next_corners, corner_count, 0.01, // quality_level
+ min_distance, noArray(), block_size,
+ 0, // use_harris
+ 0.04); // k
+
+ if( !next_mat.empty() && next_corners->size() > 3 ) {
+ cornerSubPix(next_mat, *next_corners, Size(WIN_SIZE, WIN_SIZE), Size(-1,-1),
+ cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03));
+ }
+
+ Mat flow;
+ if( !prev_mat.empty() && prev_corners->size() > 3 ) {
+// optical flow
+ calcOpticalFlowFarneback(prev_mat, next_mat, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
+ }
+
+ if( config.do_stabilization && !flow.empty() ) {
+ if( !flow_engine )
+ flow_engine = new FlowObjRemapEngine(this, PluginClient::smp);
+ flow_mat = &flow;
+ flow_engine->process_packages();
+ }
+ else
+ output->copy_from(input);
+
+ if( config.settling_speed > 0 ) {
+ if( accum && (accum->get_color_model() != color_model ||
+ accum->get_w() != width || accum->get_h() != height) ) {
+ delete accum; accum = 0;
+ }
+ if( !accum ) {
+ accum = new VFrame(width, height, color_model);
+ accum->clear_frame();
+ }
+ if( !overlay )
+ overlay = new OverlayFrame(PluginClient::smp + 1);
+ float alpha = 1 - config.settling_speed/100.;
+ overlay->overlay(accum, output,
+ 0,0, width,height, 0,0, width, height,
+ alpha, TRANSFER_NORMAL, NEAREST_NEIGHBOR);
+ output->copy_from(accum);
+ }
+
+ if( !flow.empty() && config.draw_vectors ) {
+ output->set_pixel_color(GREEN);
+ int nv = 24; float s = 2;
+ int gw = width/nv + 1, gh = height/nv + 1;
+ int sz = bmin(width,height) / 200 + 4;
+ for( int y=gh/2; y<height; y+=gh ) {
+ Point2f *row = (Point2f *)flow.ptr(y);
+ for( int x=gw/2; x<width; x+=gw ) {
+ Point2f *ds = row + x;
+ float x0 = x+.5, x1 = x+s*ds->x, y0 = y+.5, y1 = y+s*ds->y;
+ output->draw_arrow(x0,y0, x1,y1, sz);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+FlowObjRemapPackage::FlowObjRemapPackage()
+ : LoadPackage()
+{
+}
+
+FlowObjRemapUnit::FlowObjRemapUnit(FlowObjRemapEngine *engine, FlowObj *plugin)
+ : LoadClient(engine)
+{
+ this->plugin = plugin;
+}
+
+FlowObjRemapUnit::~FlowObjRemapUnit()
+{
+}
+
+void FlowObjRemapUnit::process_package(LoadPackage *package)
+{
+ FlowObjRemapPackage *pkg = (FlowObjRemapPackage*)package;
+ process_remap(pkg);
+}
+
+void FlowObjRemapUnit::process_remap(FlowObjRemapPackage *pkg)
+{
+ int row1 = pkg->row1;
+ int row2 = pkg->row2;
+ int w = plugin->width, h = plugin->height;
+ int w1 = w-1, h1 = h-1;
+ int color_model = plugin->color_model;
+ int bpp = BC_CModels::calculate_pixelsize(color_model);
+
+#define FLOW_OBJ_REMAP(type, components) { \
+ unsigned char **in_rows = plugin->input->get_rows(); \
+ type **out_rows = (type**)plugin->output->get_rows(); \
+ \
+ for( int y=row1; y<row2; ++y ) { \
+ Point2f *ipt = (Point2f *)plugin->flow_mat->ptr(y); \
+ type *out_row = out_rows[y]; \
+ for( int x=0; x<w; ++x,++ipt ) { \
+ int ix = x - ipt->x, iy = y - ipt->y; \
+ bclamp(ix, 0, w1); bclamp(iy, 0, h1); \
+ type *inp_row = (type *)(in_rows[iy] + ix*bpp); \
+ for( int i=0; i<components; ++i ) \
+ *out_row++ = *inp_row++; \
+ } \
+ } \
+}
+ switch( color_model ) {
+ case BC_RGB888: FLOW_OBJ_REMAP(unsigned char, 3); break;
+ case BC_RGBA8888: FLOW_OBJ_REMAP(unsigned char, 4); break;
+ case BC_RGB_FLOAT: FLOW_OBJ_REMAP(float, 3); break;
+ case BC_RGBA_FLOAT: FLOW_OBJ_REMAP(float, 4); break;
+ case BC_YUV888: FLOW_OBJ_REMAP(unsigned char, 3); break;
+ case BC_YUVA8888: FLOW_OBJ_REMAP(unsigned char, 4); break;
+ }
+}
+
+
+FlowObjRemapEngine::FlowObjRemapEngine(FlowObj *plugin, int cpus)
+ : LoadServer(cpus+1, cpus+1)
+{
+ this->plugin = plugin;
+}
+
+FlowObjRemapEngine::~FlowObjRemapEngine()
+{
+}
+
+void FlowObjRemapEngine::init_packages()
+{
+ int row1 = 0, row2 = 0, n = LoadServer::get_total_packages();
+ for( int i=0; i<n; row1=row2 ) {
+ FlowObjRemapPackage *package = (FlowObjRemapPackage*)LoadServer::get_package(i);
+ row2 = plugin->get_input()->get_h() * ++i / n;
+ package->row1 = row1; package->row2 = row2;
+ }
+}
+
+LoadClient* FlowObjRemapEngine::new_client()
+{
+ return new FlowObjRemapUnit(this, plugin);
+}
+
+LoadPackage* FlowObjRemapEngine::new_package()
+{
+ return new FlowObjRemapPackage();
+}
+
--- /dev/null
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef FLOWOBJ_H
+#define FLOWOBJ_H
+
+#include "pluginvclient.h"
+#include "loadbalance.h"
+#include "overlayframe.h"
+
+#include "opencv2/core/types.hpp"
+#include "opencv2/core/mat.hpp"
+#include "opencv2/calib3d.hpp"
+#include "opencv2/video/video.hpp"
+
+#include <vector>
+
+using namespace std;
+using namespace cv;
+
+//#define _RANSAC
+#ifdef _RANSAC
+#include <opencv2/videostab/motion_core.hpp>
+#include <opencv2/videostab/global_motion.hpp>
+
+using namespace videostab;
+#endif
+
+class FlowObjConfig;
+class FlowObjRemapPackage;
+class FlowObjRemapEngine;
+class FlowObjRemapUnit;
+class FlowObj;
+
+
+class FlowObjConfig
+{
+public:
+ FlowObjConfig();
+
+ int equivalent(FlowObjConfig &that);
+ void copy_from(FlowObjConfig &that);
+ void interpolate(FlowObjConfig &prev, FlowObjConfig &next,
+ long prev_frame, long next_frame, long current_frame);
+ void limits();
+ int draw_vectors;
+ int do_stabilization;
+ int settling_speed;
+// percent
+ int block_size;
+ int search_radius;
+};
+
+class FlowObjRemapPackage : public LoadPackage
+{
+public:
+ FlowObjRemapPackage();
+
+ int row1, row2;
+};
+
+class FlowObjRemapEngine : public LoadServer
+{
+public:
+ FlowObjRemapEngine(FlowObj *plugin, int cpus);
+ ~FlowObjRemapEngine();
+
+ void init_packages();
+ LoadClient* new_client();
+ LoadPackage* new_package();
+
+ FlowObj *plugin;
+};
+
+class FlowObjRemapUnit : public LoadClient
+{
+public:
+ FlowObjRemapUnit(FlowObjRemapEngine *engine, FlowObj *plugin);
+ ~FlowObjRemapUnit();
+
+ void process_package(LoadPackage *pkg);
+ void process_remap(FlowObjRemapPackage *pkg);
+
+ FlowObjRemapEngine *engine;
+ FlowObj *plugin;
+};
+
+class FlowObj : public PluginVClient
+{
+public:
+ FlowObj(PluginServer *server);
+ ~FlowObj();
+// required for all realtime plugins
+ PLUGIN_CLASS_MEMBERS2(FlowObjConfig)
+ int is_realtime();
+ void update_gui();
+ void save_data(KeyFrame *keyframe);
+ void read_data(KeyFrame *keyframe);
+ int process_buffer(VFrame *frame, int64_t start_position, double frame_rate);
+ void to_mat(Mat &mat, int mcols, int mrows,
+ VFrame *inp, int ix,int iy, int mcolor_model);
+ void from_mat(VFrame *out, int ox, int oy, int ow, int oh,
+ Mat &mat, int mcolor_model);
+
+ long prev_position, next_position;
+ int width, height, color_model;
+ VFrame *input, *output, *accum;
+
+ Mat *flow_mat;
+ FlowObjRemapEngine *flow_engine;
+ OverlayFrame *overlay;
+
+//opencv
+ typedef vector<Point2f> ptV;
+
+ BC_CModel cvmodel;
+ Mat accum_matrix;
+ double accum_matrix_mem[9];
+ double x_accum, y_accum, angle_accum;
+ Mat prev_mat, next_mat;
+ ptV *prev_corners, *next_corners;
+};
+
+#endif
--- /dev/null
+/*
+ * CINELERRA
+ * Copyright (C) 2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "bcdisplayinfo.h"
+#include "clip.h"
+#include "language.h"
+#include "flowobj.h"
+#include "flowobjwindow.h"
+#include "theme.h"
+
+FlowObjWindow::FlowObjWindow(FlowObj *plugin)
+ : PluginClientWindow(plugin, 320, 240, 320, 240, 0)
+{
+ this->plugin = plugin;
+}
+
+FlowObjWindow::~FlowObjWindow()
+{
+}
+
+void FlowObjWindow::create_objects()
+{
+ int x = 10, y = 10;
+ int margin = plugin->get_theme()->widget_border;
+ BC_Title *title;
+
+ add_subwindow(vectors = new FlowObjVectors(this, x, y));
+ y += vectors->get_h() + margin;
+ add_subwindow(do_stabilization = new FlowObjDoStabilization(this,
+ x, y));
+ y += do_stabilization->get_h() + margin;
+ add_subwindow(title = new BC_Title(x, y, _("Block size:")));
+ add_subwindow(block_size = new FlowObjBlockSize(this,
+ x + title->get_w() + margin, y));
+ y += block_size->get_h() + margin;
+ add_subwindow(title = new BC_Title(x, y, _("Search radius:")));
+ add_subwindow(search_radius = new FlowObjSearchRadius(this,
+ x + title->get_w() + margin, y));
+ y += search_radius->get_h() + margin;
+ add_subwindow(title = new BC_Title(x, y, _("Settling speed:")));
+ add_subwindow(settling_speed = new FlowObjSettling(this,
+ x + title->get_w() + margin, y));
+
+ show_window(1);
+}
+
+FlowObjVectors::FlowObjVectors(FlowObjWindow *gui, int x, int y)
+ : BC_CheckBox(x, y, gui->plugin->config.draw_vectors, _("Draw vectors"))
+{
+ this->gui = gui;
+}
+
+int FlowObjVectors::handle_event()
+{
+ gui->plugin->config.draw_vectors = get_value();
+ gui->plugin->send_configure_change();
+ return 1;
+}
+
+
+FlowObjDoStabilization::FlowObjDoStabilization(FlowObjWindow *gui, int x, int y)
+ : BC_CheckBox(x, y, gui->plugin->config.do_stabilization, _("Do stabilization"))
+{
+ this->gui = gui;
+}
+
+int FlowObjDoStabilization::handle_event()
+{
+ gui->plugin->config.do_stabilization = get_value();
+ gui->plugin->send_configure_change();
+ return 1;
+}
+
+
+FlowObjBlockSize::FlowObjBlockSize(FlowObjWindow *gui, int x, int y)
+ : BC_IPot(x, y, (int64_t)gui->plugin->config.block_size, (int64_t)5, (int64_t)100)
+{
+ this->gui = gui;
+}
+
+int FlowObjBlockSize::handle_event()
+{
+ gui->plugin->config.block_size = (int)get_value();
+ gui->plugin->send_configure_change();
+ return 1;
+}
+
+
+FlowObjSearchRadius::FlowObjSearchRadius(FlowObjWindow *gui, int x, int y)
+ : BC_IPot(x, y, (int64_t)gui->plugin->config.search_radius, (int64_t)1, (int64_t)100)
+{
+ this->gui = gui;
+}
+
+int FlowObjSearchRadius::handle_event()
+{
+ gui->plugin->config.search_radius = (int)get_value();
+ gui->plugin->send_configure_change();
+ return 1;
+}
+
+
+FlowObjSettling::FlowObjSettling(FlowObjWindow *gui, int x, int y)
+ : BC_IPot(x, y, (int64_t)gui->plugin->config.settling_speed, (int64_t)0, (int64_t)100)
+{
+ this->gui = gui;
+}
+
+int FlowObjSettling::handle_event()
+{
+ gui->plugin->config.settling_speed = (int)get_value();
+ gui->plugin->send_configure_change();
+ return 1;
+}
+
--- /dev/null
+/*
+ * CINELERRA
+ * Copyright (C) 2008-2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef FLOWOBJWINDOW_H
+#define FLOWOBJWINDOW_H
+
+
+#include "guicast.h"
+
+class FlowObj;
+class FlowObjWindow;
+
+
+class FlowObjVectors : public BC_CheckBox
+{
+public:
+ FlowObjVectors(FlowObjWindow *gui, int x, int y);
+ int handle_event();
+ FlowObjWindow *gui;
+};
+
+class FlowObjDoStabilization : public BC_CheckBox
+{
+public:
+ FlowObjDoStabilization(FlowObjWindow *gui, int x, int y);
+ int handle_event();
+ FlowObjWindow *gui;
+};
+
+class FlowObjBlockSize : public BC_IPot
+{
+public:
+ FlowObjBlockSize(FlowObjWindow *gui, int x, int y);
+ int handle_event();
+ FlowObjWindow *gui;
+};
+
+class FlowObjSearchRadius : public BC_IPot
+{
+public:
+ FlowObjSearchRadius(FlowObjWindow *gui, int x, int y);
+ int handle_event();
+ FlowObjWindow *gui;
+};
+
+class FlowObjMaxMovement : public BC_IPot
+{
+public:
+ FlowObjMaxMovement(FlowObjWindow *gui, int x, int y);
+ int handle_event();
+ FlowObjWindow *gui;
+};
+
+class FlowObjSettling : public BC_IPot
+{
+public:
+ FlowObjSettling(FlowObjWindow *gui, int x, int y);
+ int handle_event();
+ FlowObjWindow *gui;
+};
+
+class FlowObjWindow : public PluginClientWindow
+{
+public:
+ FlowObjWindow(FlowObj *plugin);
+ ~FlowObjWindow();
+
+ void create_objects();
+
+ FlowObj *plugin;
+ FlowObjVectors *vectors;
+ FlowObjDoStabilization *do_stabilization;
+ FlowObjBlockSize *block_size;
+ FlowObjSearchRadius *search_radius;
+// not implemented
+// FlowObjMaxMovement *max_movement;
+ FlowObjSettling *settling_speed;
+};
+
+#endif
--- /dev/null
+default: all
+
+TOPDIR?=../..
+include $(TOPDIR)/plugin_defs
+
+PLUGIN = gaborobj
+
+OBJS := \
+ $(OBJDIR)/gaborobj.o \
+ $(OBJDIR)/gaborobjwindow.o \
+
+want_var:=$(WANT_OPENCV)
+include $(TOPDIR)/opencv_build
+include $(TOPDIR)/plugin_config
+
+all: opencv
+ +make $(OUTPUT)
+
+$(OBJDIR)/gaborobj.o: gaborobj.C gaborobj.h gaborobjwindow.h
+$(OBJDIR)/gaborobjwindow.o: gaborobjwindow.C gaborobj.h gaborobjwindow.h
+
--- /dev/null
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "clip.h"
+#include "filexml.h"
+#include "gaborobj.h"
+#include "gaborobjwindow.h"
+#include "language.h"
+#include "mutex.h"
+
+REGISTER_PLUGIN(GaborObj)
+
+
+GaborObjConfig::GaborObjConfig()
+{
+}
+
+int GaborObjConfig::equivalent(GaborObjConfig &that)
+{
+ return 1;
+}
+
+void GaborObjConfig::copy_from(GaborObjConfig &that)
+{
+}
+
+void GaborObjConfig::interpolate( GaborObjConfig &prev, GaborObjConfig &next,
+ long prev_frame, long next_frame, long current_frame)
+{
+ copy_from(next);
+}
+
+void GaborObjConfig::limits()
+{
+}
+
+
+GaborObj::GaborObj(PluginServer *server)
+ : PluginVClient(server)
+{
+ int steps = 16;
+ Size ksize(31, 31);
+ for( int i=0; i<steps; ++i ) {
+ double theta = i * M_PI/steps;
+ Mat kern = getGaborKernel(ksize, 4.0, theta, 10.0, 0.5, 0, CV_32F);
+ float sum = 0;
+ for( int k=0; k<kern.rows; ++k ) {
+ float *kp = kern.ptr<float>(k);
+ for( int j=0; j<kern.cols; ++j ) sum += *kp++;
+ }
+ kern /= 1.5*sum;
+ filters.push_back(kern);
+ }
+ gabor_engine = 0;
+ remap_lock = new ::Mutex("GaborObj::remap_lock");
+}
+
+GaborObj::~GaborObj()
+{
+ delete gabor_engine;
+ delete remap_lock;
+}
+
+const char* GaborObj::plugin_title() { return N_("GaborObj"); }
+int GaborObj::is_realtime() { return 1; }
+
+NEW_WINDOW_MACRO(GaborObj, GaborObjWindow);
+LOAD_CONFIGURATION_MACRO(GaborObj, GaborObjConfig)
+
+void GaborObj::save_data(KeyFrame *keyframe)
+{
+ FileXML output;
+
+// cause data to be stored directly in text
+ output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+ output.tag.set_title("GABOROBJ");
+ output.append_tag();
+ output.append_newline();
+ output.tag.set_title("/GABOROBJ");
+ output.append_tag();
+ output.append_newline();
+ output.terminate_string();
+}
+
+void GaborObj::read_data(KeyFrame *keyframe)
+{
+ FileXML input;
+ input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+
+ int result = 0;
+ while( !(result = input.read_tag()) ) {
+ if( input.tag.title_is("GABOROBJ") ) {
+ config.limits();
+ }
+ else if( input.tag.title_is("/GABOROBJ") )
+ result = 1;
+ }
+}
+
+void GaborObj::update_gui()
+{
+ if( !thread ) return;
+ if( !load_configuration() ) return;
+ thread->window->lock_window("GaborObj::update_gui");
+ GaborObjWindow *window = (GaborObjWindow*)thread->window;
+ window->unlock_window();
+}
+
+void GaborObj::to_mat(Mat &mat, int mcols, int mrows,
+ VFrame *inp, int ix,int iy, int mcolor_model)
+{
+ int mcomp = BC_CModels::components(mcolor_model);
+ int mbpp = BC_CModels::calculate_pixelsize(mcolor_model);
+ int psz = mbpp / mcomp;
+ int mdepth = psz < 2 ? CV_8U : psz < 4 ? CV_16U : CV_32F;
+ if( mat.dims != 2 || mat.depth() != mdepth || mat.channels() != mcomp ||
+ mat.cols != mcols || mat.rows != mrows ) {
+ mat.release();
+ }
+ if( mat.empty() ) {
+ int type = CV_MAKETYPE(mdepth, mcomp);
+ mat.create(mrows, mcols, type);
+ }
+ uint8_t *mat_rows[mrows];
+ for( int y=0; y<mrows; ++y ) mat_rows[y] = mat.ptr(y);
+ uint8_t **inp_rows = inp->get_rows();
+ int ibpl = inp->get_bytes_per_line(), mbpl = mcols * mbpp;
+ int icolor_model = inp->get_color_model();
+ BC_CModels::transfer(mat_rows, mcolor_model, 0,0, mcols,mrows, mbpl,
+ inp_rows, icolor_model, ix,iy, mcols,mrows, ibpl, 0);
+// VFrame vfrm(mat_rows[0], -1, mcols,mrows, mcolor_model, mat_rows[1]-mat_rows[0]);
+// static int vfrm_no = 0; char vfn[64]; sprintf(vfn,"/tmp/idat/%06d.png", vfrm_no++);
+// vfrm.write_png(vfn);
+}
+
+void GaborObj::from_mat(VFrame *out, int ox, int oy, int ow, int oh, Mat &mat, int mcolor_model)
+{
+ int mbpp = BC_CModels::calculate_pixelsize(mcolor_model);
+ int mrows = mat.rows, mcols = mat.cols;
+ uint8_t *mat_rows[mrows];
+ for( int y=0; y<mrows; ++y ) mat_rows[y] = mat.ptr(y);
+ uint8_t **out_rows = out->get_rows();
+ int obpl = out->get_bytes_per_line(), mbpl = mcols * mbpp;
+ int ocolor_model = out->get_color_model();
+ BC_CModels::transfer(out_rows, ocolor_model, ox,oy, ow,oh, obpl,
+ mat_rows, mcolor_model, 0,0, mcols,mrows, mbpl, 0);
+// static int vfrm_no = 0; char vfn[64]; sprintf(vfn,"/tmp/odat/%06d.png", vfrm_no++);
+// out->write_png(vfn);
+}
+
+
+int GaborObj::process_buffer(VFrame *frame, int64_t start_position, double frame_rate)
+{
+
+ //int need_reconfigure =
+ load_configuration();
+ input = get_input(0);
+ output = get_output(0);
+ width = input->get_w();
+ height = input->get_h();
+ color_model = input->get_color_model();
+
+// load next image
+ VFrame *iframe = new_temp(width,height, color_model);
+ read_frame(iframe, 0, start_position, frame_rate, 0);
+ input = iframe;
+ to_mat(next_img, width,height, iframe, 0,0, color_model);
+ if( !gabor_engine )
+ gabor_engine = new GaborObjFilterEngine(this, PluginClient::smp + 1);
+
+ output->clear_frame();
+ gabor_engine->process_packages();
+ return 0;
+}
+
+
+GaborObjFilterPackage::GaborObjFilterPackage()
+ : LoadPackage()
+{
+}
+
+GaborObjFilterUnit::GaborObjFilterUnit(GaborObjFilterEngine *engine, GaborObj *plugin)
+ : LoadClient(engine)
+{
+ this->plugin = plugin;
+}
+
+GaborObjFilterUnit::~GaborObjFilterUnit()
+{
+}
+
+void GaborObjFilterUnit::process_package(LoadPackage *package)
+{
+ GaborObjFilterPackage *pkg = (GaborObjFilterPackage*)package;
+ process_filter(pkg);
+}
+
+void GaborObjFilterUnit::process_filter(GaborObjFilterPackage *pkg)
+{
+ int color_model = plugin->color_model;
+ int w = plugin->output->get_w(), h = plugin->output->get_h();
+ int ddepth = CV_8UC3;
+
+ switch( color_model ) {
+ case BC_RGB888: ddepth = CV_8UC3; break;
+ case BC_RGBA8888: ddepth = CV_8UC4; break;
+ case BC_RGB_FLOAT: ddepth = CV_32FC3; break;
+ case BC_RGBA_FLOAT: ddepth = CV_32FC4; break;
+ case BC_YUV888: ddepth = CV_8UC3; break;
+ case BC_YUVA8888: ddepth = CV_8UC4; break;
+ }
+
+ Mat &src = plugin->next_img, dst;
+ Mat &kern = plugin->filters[pkg->i];
+ filter2D(src, dst, ddepth, kern);
+
+#define GABOR_OBJ_REMAP(type, components) { \
+ type **out_rows = (type**)plugin->output->get_rows(); \
+ \
+ for( int y=0; y<h; ++y ) { \
+ type *out_row = out_rows[y]; \
+ type *dst_row = (type *)dst.ptr<type>(y); \
+ for( int x=0; x<w; ++x ) { \
+ for( int i=0; i<components; ++i ) { \
+ *out_row = bmax(*out_row, *dst_row); \
+ ++out_row; ++dst_row; \
+ } \
+ } \
+ } \
+}
+// technically, this is needed... but it really can slow it down.
+// plugin->remap_lock->lock("GaborObjFilterUnit::process_filter");
+ switch( color_model ) {
+ case BC_RGB888: GABOR_OBJ_REMAP(unsigned char, 3); break;
+ case BC_RGBA8888: GABOR_OBJ_REMAP(unsigned char, 4); break;
+ case BC_RGB_FLOAT: GABOR_OBJ_REMAP(float, 3); break;
+ case BC_RGBA_FLOAT: GABOR_OBJ_REMAP(float, 4); break;
+ case BC_YUV888: GABOR_OBJ_REMAP(unsigned char, 3); break;
+ case BC_YUVA8888: GABOR_OBJ_REMAP(unsigned char, 4); break;
+ }
+// plugin->remap_lock->unlock();
+}
+
+
+GaborObjFilterEngine::GaborObjFilterEngine(GaborObj *plugin, int cpus)
+ : LoadServer(cpus+1, plugin->filters.size())
+{
+ this->plugin = plugin;
+}
+
+GaborObjFilterEngine::~GaborObjFilterEngine()
+{
+}
+
+void GaborObjFilterEngine::init_packages()
+{
+ int n = LoadServer::get_total_packages();
+ for( int i=0; i<n; ++i ) {
+ GaborObjFilterPackage *pkg = (GaborObjFilterPackage*)LoadServer::get_package(i);
+ pkg->i = i;
+ }
+}
+
+LoadClient* GaborObjFilterEngine::new_client()
+{
+ return new GaborObjFilterUnit(this, plugin);
+}
+
+LoadPackage* GaborObjFilterEngine::new_package()
+{
+ return new GaborObjFilterPackage();
+}
+
--- /dev/null
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef GABOROBJ_H
+#define GABOROBJ_H
+
+#include "pluginvclient.h"
+#include "loadbalance.h"
+#include "mutex.inc"
+
+#include "opencv2/core/types.hpp"
+#include "opencv2/core/mat.hpp"
+#include "opencv2/calib3d.hpp"
+#include "opencv2/video/video.hpp"
+
+#include <vector>
+
+using namespace std;
+using namespace cv;
+
+
+class GaborObjConfig;
+class GaborObj;
+
+
+class GaborObjConfig
+{
+public:
+ GaborObjConfig();
+
+ int equivalent(GaborObjConfig &that);
+ void copy_from(GaborObjConfig &that);
+ void interpolate(GaborObjConfig &prev, GaborObjConfig &next,
+ long prev_frame, long next_frame, long current_frame);
+ void limits();
+};
+
+class GaborObjFilterPackage : public LoadPackage
+{
+public:
+ GaborObjFilterPackage();
+ int i;
+};
+
+class GaborObjFilterEngine : public LoadServer
+{
+public:
+ GaborObjFilterEngine(GaborObj *plugin, int cpus);
+ ~GaborObjFilterEngine();
+
+ void init_packages();
+ LoadClient* new_client();
+ LoadPackage* new_package();
+
+ GaborObj *plugin;
+};
+
+class GaborObjFilterUnit : public LoadClient
+{
+public:
+ GaborObjFilterUnit(GaborObjFilterEngine *engine, GaborObj *plugin);
+ ~GaborObjFilterUnit();
+
+ void process_package(LoadPackage *pkg);
+ void process_filter(GaborObjFilterPackage *pkg);
+
+ GaborObjFilterEngine *engine;
+ GaborObj *plugin;
+};
+
+class GaborObj : public PluginVClient
+{
+public:
+ GaborObj(PluginServer *server);
+ ~GaborObj();
+ PLUGIN_CLASS_MEMBERS2(GaborObjConfig)
+ int is_realtime();
+ void update_gui();
+ void save_data(KeyFrame *keyframe);
+ void read_data(KeyFrame *keyframe);
+ int process_buffer(VFrame *frame, int64_t start_position, double frame_rate);
+ void to_mat(Mat &mat, int mcols, int mrows,
+ VFrame *inp, int ix,int iy, int mcolor_model);
+ void from_mat(VFrame *out, int ox, int oy, int ow, int oh,
+ Mat &mat, int mcolor_model);
+
+ int width, height, color_model;
+ VFrame *input, *output, *accum;
+ ::Mutex *remap_lock;
+
+ Mat next_img;
+ vector<Mat> filters;
+ GaborObjFilterEngine *gabor_engine;
+};
+
+#endif
--- /dev/null
+/*
+ * CINELERRA
+ * Copyright (C) 2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "bcdisplayinfo.h"
+#include "clip.h"
+#include "language.h"
+#include "gaborobj.h"
+#include "gaborobjwindow.h"
+#include "theme.h"
+
+GaborObjWindow::GaborObjWindow(GaborObj *plugin)
+ : PluginClientWindow(plugin, 320, 240, 320, 240, 0)
+{
+ this->plugin = plugin;
+}
+
+GaborObjWindow::~GaborObjWindow()
+{
+}
+
+void GaborObjWindow::create_objects()
+{
+ int x = 10, y = 10;
+ BC_Title *title = new BC_Title(x, y, _("GaborObj"));
+ add_subwindow(title);
+ show_window(1);
+}
+
--- /dev/null
+/*
+ * CINELERRA
+ * Copyright (C) 2008-2014 Adam Williams <broadcast at earthling dot net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef GABOROBJWINDOW_H
+#define GABOROBJWINDOW_H
+
+
+#include "guicast.h"
+
+class GaborObj;
+class GaborObjWindow;
+
+class GaborObjWindow : public PluginClientWindow
+{
+public:
+ GaborObjWindow(GaborObj *plugin);
+ ~GaborObjWindow();
+
+ void create_objects();
+
+ GaborObj *plugin;
+};
+
+#endif
$(OBJDIR)/moveobj.o \
$(OBJDIR)/moveobjwindow.o \
-want_var:=$(WANT_FINDOBJECT)
+want_var:=$(WANT_OPENCV)
include $(TOPDIR)/opencv_build
include $(TOPDIR)/plugin_config
}
void MoveObj::to_mat(Mat &mat, int mcols, int mrows,
- VFrame *inp, int ix,int iy, BC_CModel mcolor_model)
+ VFrame *inp, int ix,int iy, int mcolor_model)
{
int mcomp = BC_CModels::components(mcolor_model);
int mbpp = BC_CModels::calculate_pixelsize(mcolor_model);
int psz = mbpp / mcomp;
- int mdepth = psz < 2 ? CV_8U : CV_16U;
+ int mdepth = psz < 2 ? CV_8U : psz < 4 ? CV_16U : CV_32F;
if( mat.dims != 2 || mat.depth() != mdepth || mat.channels() != mcomp ||
mat.cols != mcols || mat.rows != mrows ) {
mat.release();
to_mat(next_mat, w,h, iframe, 0,0, BC_GREY8);
int corner_count = MAX_COUNT;
- int search_radius = config.block_size;
+ int block_size = config.block_size;
int min_distance = config.search_radius;
goodFeaturesToTrack(next_mat,
*next_corners, corner_count, 0.01, // quality_level
- min_distance, noArray(), search_radius,
+ min_distance, noArray(), block_size,
0, // use_harris
0.04); // k
int process_buffer(VFrame *frame, int64_t start_position, double frame_rate);
AffineEngine *affine;
void to_mat(Mat &mat, int mcols, int mrows,
- VFrame *inp, int ix,int iy, BC_CModel mcolor_model);
+ VFrame *inp, int ix,int iy, int mcolor_model);
long prev_position, next_position;