robmor / watermeter Goto Github PK
View Code? Open in Web Editor NEWA simple linux app to track water usage via a webcam pointed at a water meter
A simple linux app to track water usage via a webcam pointed at a water meter
The Makefile introduced in 51d06e6 causes errors during linking on Ubuntu 20.04. These errors do not occur on up-to-date Arch Linux.
Errors in the linking stage occur after command:
g++ -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -latk-1.0
-lcairo-gobject -lgdk_pixbuf-2.0 -lgio-2.0 -lcairo -lgstapp-1.0
-lgstbase-1.0 -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0 -o watermeter
target/pipeline.o target/main.o target/app.o
Non-truncated errors to show that it affects every external library linked against:
/usr/bin/ld: target/pipeline.o: in function `gst_caps_unref':
pipeline.cpp:(.text+0x14): undefined reference to `gst_mini_object_unref'
/usr/bin/ld: target/pipeline.o: in function `gst_sample_unref':
pipeline.cpp:(.text+0x2f): undefined reference to `gst_mini_object_unref'
/usr/bin/ld: target/pipeline.o: in function `Pipeline::Pipeline()':
pipeline.cpp:(.text+0x4f): undefined reference to `gst_pipeline_new'
/usr/bin/ld: pipeline.cpp:(.text+0x6c): undefined reference to
`gst_element_factory_make'
/usr/bin/ld: pipeline.cpp:(.text+0x83): undefined reference to
`gst_element_factory_make'
/usr/bin/ld: pipeline.cpp:(.text+0x9a): undefined reference to
`gst_element_factory_make'
/usr/bin/ld: pipeline.cpp:(.text+0xba): undefined reference to
`gst_app_sink_set_max_buffers'
/usr/bin/ld: pipeline.cpp:(.text+0xcf): undefined reference to
`gst_app_sink_set_drop'
/usr/bin/ld: pipeline.cpp:(.text+0xf9): undefined reference to
`gst_caps_new_simple'
/usr/bin/ld: pipeline.cpp:(.text+0x114): undefined reference to
`gst_app_sink_set_caps'
/usr/bin/ld: pipeline.cpp:(.text+0x125): undefined reference to
`gst_pipeline_get_type'
/usr/bin/ld: pipeline.cpp:(.text+0x13a): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: pipeline.cpp:(.text+0x142): undefined reference to
`gst_pipeline_get_bus'
/usr/bin/ld: pipeline.cpp:(.text+0x15e): undefined reference to
`gst_bus_add_watch'
/usr/bin/ld: pipeline.cpp:(.text+0x16a): undefined reference to
`g_object_unref'
/usr/bin/ld: pipeline.cpp:(.text+0x177): undefined reference to
`gst_bin_get_type'
/usr/bin/ld: pipeline.cpp:(.text+0x18c): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: pipeline.cpp:(.text+0x1ad): undefined reference to
`gst_bin_add_many'
/usr/bin/ld: pipeline.cpp:(.text+0x1cf): undefined reference to
`gst_element_link_many'
/usr/bin/ld: pipeline.cpp:(.text+0x1e3): undefined reference to
`gst_element_set_state'
/usr/bin/ld: pipeline.cpp:(.text+0x203): undefined reference to
`gst_element_get_state'
/usr/bin/ld: target/pipeline.o: in function `Pipeline::~Pipeline()':
pipeline.cpp:(.text+0x230): undefined reference to `gst_element_set_state'
/usr/bin/ld: pipeline.cpp:(.text+0x23f): undefined reference to
`gst_object_unref'
/usr/bin/ld: pipeline.cpp:(.text+0x24f): undefined reference to
`gst_object_unref'
/usr/bin/ld: target/pipeline.o: in function `Pipeline::Capture()':
pipeline.cpp:(.text+0x28a): undefined reference to
`gst_app_sink_pull_sample'
/usr/bin/ld: pipeline.cpp:(.text+0x2b8): undefined reference to
`gst_sample_get_caps'
/usr/bin/ld: pipeline.cpp:(.text+0x2da): undefined reference to `g_print'
/usr/bin/ld: pipeline.cpp:(.text+0x2f8): undefined reference to
`gst_caps_get_structure'
/usr/bin/ld: pipeline.cpp:(.text+0x316): undefined reference to
`gst_structure_get_int'
/usr/bin/ld: pipeline.cpp:(.text+0x336): undefined reference to
`gst_structure_get_int'
/usr/bin/ld: pipeline.cpp:(.text+0x356): undefined reference to `g_print'
/usr/bin/ld: pipeline.cpp:(.text+0x36f): undefined reference to
`gst_sample_get_buffer'
/usr/bin/ld: pipeline.cpp:(.text+0x38b): undefined reference to
`gst_buffer_map'
/usr/bin/ld: pipeline.cpp:(.text+0x3de): undefined reference to
`gdk_pixbuf_new_from_data'
/usr/bin/ld: pipeline.cpp:(.text+0x3fc): undefined reference to
`gst_buffer_unmap'
/usr/bin/ld: pipeline.cpp:(.text+0x443): undefined reference to
`gst_app_sink_is_eos'
/usr/bin/ld: pipeline.cpp:(.text+0x45d): undefined reference to `g_print'
/usr/bin/ld: pipeline.cpp:(.text+0x470): undefined reference to `g_print'
/usr/bin/ld: target/pipeline.o: in function `BusHandler(_GstBus*,
_GstMessage*, void**)':
pipeline.cpp:(.text+0x4cb): undefined reference to `gst_message_parse_error'
/usr/bin/ld: pipeline.cpp:(.text+0x4eb): undefined reference to `g_print'
/usr/bin/ld: pipeline.cpp:(.text+0x4f7): undefined reference to
`g_error_free'
/usr/bin/ld: pipeline.cpp:(.text+0x503): undefined reference to `g_free'
/usr/bin/ld: target/main.o: in function `main':
main.cpp:(.text+0xfb): undefined reference to `g_print'
/usr/bin/ld: main.cpp:(.text+0x12a): undefined reference to `gst_init'
/usr/bin/ld: target/app.o: in function `App::App(bool, bool, bool)':
app.cpp:(.text+0x138): undefined reference to `gtk_application_new'
/usr/bin/ld: app.cpp:(.text+0x145): undefined reference to
`g_application_get_type'
/usr/bin/ld: app.cpp:(.text+0x15b): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x184): undefined reference to
`g_signal_connect_data'
/usr/bin/ld: target/app.o: in function `App::Run()':
app.cpp:(.text+0x1c3): undefined reference to `g_application_get_type'
/usr/bin/ld: app.cpp:(.text+0x1d9): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x1eb): undefined reference to
`g_application_run'
/usr/bin/ld: app.cpp:(.text+0x1fb): undefined reference to `g_object_unref'
/usr/bin/ld: target/app.o: in function `App::MakeWindow()':
app.cpp:(.text+0x244): undefined reference to `gtk_application_get_type'
/usr/bin/ld: app.cpp:(.text+0x25a): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x262): undefined reference to
`gtk_application_window_new'
/usr/bin/ld: app.cpp:(.text+0x26f): undefined reference to
`gtk_window_get_type'
/usr/bin/ld: app.cpp:(.text+0x285): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x297): undefined reference to
`gtk_window_set_default_size'
/usr/bin/ld: app.cpp:(.text+0x2c8): undefined reference to
`g_signal_connect_data'
/usr/bin/ld: app.cpp:(.text+0x2cd): undefined reference to
`gtk_drawing_area_new'
/usr/bin/ld: app.cpp:(.text+0x306): undefined reference to
`g_signal_connect_data'
/usr/bin/ld: app.cpp:(.text+0x337): undefined reference to
`g_signal_connect_data'
/usr/bin/ld: app.cpp:(.text+0x368): undefined reference to
`g_signal_connect_data'
/usr/bin/ld: app.cpp:(.text+0x399): undefined reference to
`g_signal_connect_data'
/usr/bin/ld: app.cpp:(.text+0x3b3): undefined reference to
`gtk_widget_set_size_request'
/usr/bin/ld: app.cpp:(.text+0x3c8): undefined reference to
`gtk_widget_add_events'
/usr/bin/ld: app.cpp:(.text+0x3d2): undefined reference to `gtk_label_new'
/usr/bin/ld: app.cpp:(.text+0x3e9): undefined reference to `gtk_box_new'
/usr/bin/ld: app.cpp:(.text+0x3fa): undefined reference to
`gtk_box_get_type'
/usr/bin/ld: app.cpp:(.text+0x40c): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x427): undefined reference to
`gtk_box_pack_start'
/usr/bin/ld: app.cpp:(.text+0x434): undefined reference to
`gtk_box_get_type'
/usr/bin/ld: app.cpp:(.text+0x446): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x461): undefined reference to
`gtk_box_pack_start'
/usr/bin/ld: app.cpp:(.text+0x466): undefined reference to
`gtk_container_get_type'
/usr/bin/ld: app.cpp:(.text+0x47c): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x48e): undefined reference to
`gtk_container_add'
/usr/bin/ld: app.cpp:(.text+0x49e): undefined reference to
`gtk_widget_show_all'
/usr/bin/ld: target/app.o: in function `App::Refresh()':
app.cpp:(.text+0x527): undefined reference to `gtk_label_get_type'
/usr/bin/ld: app.cpp:(.text+0x53d): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x548): undefined reference to
`gtk_label_set_text'
/usr/bin/ld: app.cpp:(.text+0x564): undefined reference to
`gtk_widget_get_window'
/usr/bin/ld: app.cpp:(.text+0x576): undefined reference to
`gdk_window_invalidate_rect'
/usr/bin/ld: target/app.o: in function
`App::ComputeImagePosition(double*, double*, double*)':
app.cpp:(.text+0x5be): undefined reference to `gdk_pixbuf_get_width'
/usr/bin/ld: app.cpp:(.text+0x5d1): undefined reference to
`gdk_pixbuf_get_height'
/usr/bin/ld: app.cpp:(.text+0x5e4): undefined reference to
`gtk_widget_get_allocated_width'
/usr/bin/ld: app.cpp:(.text+0x5f7): undefined reference to
`gtk_widget_get_allocated_height'
/usr/bin/ld: target/app.o: in function
`App::UpdateDrawingArea(_GtkWidget*, _cairo*, App*)':
app.cpp:(.text+0x7f9): undefined reference to `cairo_save'
/usr/bin/ld: app.cpp:(.text+0x811): undefined reference to
`cairo_set_source_rgb'
/usr/bin/ld: app.cpp:(.text+0x81d): undefined reference to
`gtk_widget_get_allocated_height'
/usr/bin/ld: app.cpp:(.text+0x832): undefined reference to
`gtk_widget_get_allocated_width'
/usr/bin/ld: app.cpp:(.text+0x853): undefined reference to `cairo_rectangle'
/usr/bin/ld: app.cpp:(.text+0x85f): undefined reference to `cairo_fill'
/usr/bin/ld: app.cpp:(.text+0x86b): undefined reference to `cairo_stroke'
/usr/bin/ld: app.cpp:(.text+0x889): undefined reference to `cairo_translate'
/usr/bin/ld: app.cpp:(.text+0x8a7): undefined reference to `cairo_scale'
/usr/bin/ld: app.cpp:(.text+0x8b7): undefined reference to
`gtk_widget_get_window'
/usr/bin/ld: app.cpp:(.text+0x8cf): undefined reference to
`gdk_cairo_surface_create_from_pixbuf'
/usr/bin/ld: app.cpp:(.text+0x8ee): undefined reference to
`cairo_set_source_surface'
/usr/bin/ld: app.cpp:(.text+0x8fa): undefined reference to `cairo_paint'
/usr/bin/ld: app.cpp:(.text+0x91a): undefined reference to
`cairo_set_source_rgb'
/usr/bin/ld: app.cpp:(.text+0x93d): undefined reference to `cairo_stroke'
/usr/bin/ld: app.cpp:(.text+0x95d): undefined reference to
`cairo_set_source_rgb'
/usr/bin/ld: app.cpp:(.text+0x980): undefined reference to `cairo_stroke'
/usr/bin/ld: app.cpp:(.text+0x98c): undefined reference to `cairo_restore'
/usr/bin/ld: target/app.o: in function `App::KeyPress(_GtkWidget*,
_GdkEventKey*, App*)':
app.cpp:(.text+0xa13): undefined reference to `g_source_remove'
/usr/bin/ld: app.cpp:(.text+0xa42): undefined reference to `g_source_remove'
/usr/bin/ld: app.cpp:(.text+0xafa): undefined reference to `g_source_remove'
/usr/bin/ld: app.cpp:(.text+0xb12): undefined reference to `g_timeout_add'
/usr/bin/ld: app.cpp:(.text+0xb3d): undefined reference to `g_source_remove'
/usr/bin/ld: app.cpp:(.text+0xb55): undefined reference to
`g_timeout_add_seconds'
/usr/bin/ld: app.cpp:(.text+0xbac): undefined reference to
`gtk_accelerator_get_default_mod_mask'
/usr/bin/ld: app.cpp:(.text+0xc52): undefined reference to
`gtk_accelerator_get_default_mod_mask'
/usr/bin/ld: target/app.o: in function `App::AskForReading()':
app.cpp:(.text+0xffd): undefined reference to `gtk_window_get_type'
/usr/bin/ld: app.cpp:(.text+0x1013): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x103f): undefined reference to
`gtk_dialog_new_with_buttons'
/usr/bin/ld: app.cpp:(.text+0x1048): undefined reference to
`gtk_dialog_get_type'
/usr/bin/ld: app.cpp:(.text+0x105a): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x1062): undefined reference to
`gtk_dialog_get_content_area'
/usr/bin/ld: app.cpp:(.text+0x1072): undefined reference to `gtk_label_new'
/usr/bin/ld: app.cpp:(.text+0x107b): undefined reference to `gtk_entry_new'
/usr/bin/ld: app.cpp:(.text+0x10ad): undefined reference to
`gtk_entry_get_type'
/usr/bin/ld: app.cpp:(.text+0x10bf): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x10ca): undefined reference to
`gtk_entry_set_text'
/usr/bin/ld: app.cpp:(.text+0x10cf): undefined reference to
`gtk_container_get_type'
/usr/bin/ld: app.cpp:(.text+0x10e1): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x10f3): undefined reference to
`gtk_container_add'
/usr/bin/ld: app.cpp:(.text+0x10f8): undefined reference to
`gtk_container_get_type'
/usr/bin/ld: app.cpp:(.text+0x110a): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x111c): undefined reference to
`gtk_container_add'
/usr/bin/ld: app.cpp:(.text+0x1128): undefined reference to
`gtk_widget_show_all'
/usr/bin/ld: app.cpp:(.text+0x112d): undefined reference to
`gtk_dialog_get_type'
/usr/bin/ld: app.cpp:(.text+0x113f): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x1147): undefined reference to `gtk_dialog_run'
/usr/bin/ld: app.cpp:(.text+0x114c): undefined reference to
`gtk_entry_get_type'
/usr/bin/ld: app.cpp:(.text+0x115e): undefined reference to
`g_type_check_instance_cast'
/usr/bin/ld: app.cpp:(.text+0x1166): undefined reference to
`gtk_entry_get_text'
/usr/bin/ld: app.cpp:(.text+0x118f): undefined reference to
`gtk_widget_destroy'
/usr/bin/ld: target/app.o: in function `App::FindNeedle()':
app.cpp:(.text+0x11f3): undefined reference to `gdk_pixbuf_get_colorspace'
/usr/bin/ld: app.cpp:(.text+0x1229): undefined reference to
`gdk_pixbuf_get_n_channels'
/usr/bin/ld: app.cpp:(.text+0x1260): undefined reference to
`gdk_pixbuf_get_width'
/usr/bin/ld: app.cpp:(.text+0x1276): undefined reference to
`gdk_pixbuf_get_height'
/usr/bin/ld: app.cpp:(.text+0x128c): undefined reference to
`gdk_pixbuf_get_rowstride'
/usr/bin/ld: app.cpp:(.text+0x12a2): undefined reference to
`gdk_pixbuf_read_pixels'
/usr/bin/ld: target/app.o: in function `App::ProcessFrame()':
app.cpp:(.text+0x19c2): undefined reference to `gdk_pixbuf_save'
/usr/bin/ld: target/app.o: in function `Circle::Draw(_cairo*)':
app.cpp:(.text._ZN6Circle4DrawEP6_cairo[_ZN6Circle4DrawEP6_cairo]+0x52):
undefined reference to `cairo_arc'
/usr/bin/ld: target/app.o: in function `Line::Draw(_cairo*)':
app.cpp:(.text._ZN4Line4DrawEP6_cairo[_ZN4Line4DrawEP6_cairo]+0x35):
undefined reference to `cairo_move_to'
/usr/bin/ld:
app.cpp:(.text._ZN4Line4DrawEP6_cairo[_ZN4Line4DrawEP6_cairo]+0x5b):
undefined reference to `cairo_line_to'
collect2: error: ld returned 1 exit status
make: *** [makefile:25: watermeter] Error 1
The initial reading appears to jump up by about 3 gallons after pressing space to start the analysis even though the dial does not move from its initial position.
So I think I may have stumbled across this problem earlier today and dismissed it:
Lines 368 to 377 in 79e737f
There's a problem with our redness metric: When it encounters a pixel that is purely red (i.e. no blue or green component to its color) it tries to compute (2 * r) / (b + g) but since b is zero and g is zero it divides (2*r) by zero resulting in infinity. That means any angle that has a purely red pixel will be chosen disregarding any other angles. We know this is happening because looking at the rows in hist.csv corresponding to images that have weird jumps we can see columns with 'inf' in them like row 1 column FR (and they also correspond to the angle that was jumped to). It turns out every single image that shows it's failing to find the needle also has an 'inf' in the row:
15:17:43 - Columns FR and RF
15:18:03 - Columns ND and RF
15:18:08 - Columns FX and MW
15:18:13 - Column RF
15:18:23 - Column RF
15:18:28 - Column RF
15:18:38 - Column RF
15:18:48 - Column FD and MW
Now there aren't any purely red pixels visible in these images but I think just through the inherent noise in the camera feed one is sneaking through every once in a while and messing up the reading.
But all this is good! We finally know what's causing the jitter! All we need to do is find a more robust redness metric...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.