[shotwell/wip/phako/enhanced-faces: 8/136] Facedetect process talks over DBus
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell/wip/phako/enhanced-faces: 8/136] Facedetect process talks over DBus
- Date: Thu, 11 Oct 2018 09:55:50 +0000 (UTC)
commit 4c84248b80ebf3a1f1eb05aa60625d9d8c5d0134
Author: NarendraMA <narendra_m_a yahoo com>
Date: Thu Jun 28 16:46:03 2018 +0530
Facedetect process talks over DBus
facedetect/org.gnome.ShotwellFaces1.xml | 6 +++
facedetect/shotwell-facedetect.cpp | 11 ++++-
src/AppDirs.vala | 3 +-
src/faces/Face.vala | 29 ++++++++++++
src/faces/FaceDetect.vala | 73 +++++++++++++++++++++++++++++
src/faces/FacesTool.vala | 81 ++++++++-------------------------
src/faces_opencv/faces_opencv.cpp | 8 ++--
src/meson.build | 4 +-
vapi/faces.vapi | 38 ----------------
9 files changed, 145 insertions(+), 108 deletions(-)
---
diff --git a/facedetect/org.gnome.ShotwellFaces1.xml b/facedetect/org.gnome.ShotwellFaces1.xml
index b621f56f..17d1ba1b 100644
--- a/facedetect/org.gnome.ShotwellFaces1.xml
+++ b/facedetect/org.gnome.ShotwellFaces1.xml
@@ -48,5 +48,11 @@
<arg type="d" name="threshold" direction="in" />
<arg type="a(sd)" name="labels" direction="out" />
</method>
+
+ <!--
+ Terminate
+ -->
+ <method name="Terminate">
+ </method>
</interface>
</node>
diff --git a/facedetect/shotwell-facedetect.cpp b/facedetect/shotwell-facedetect.cpp
index 9f3f52f2..a1f75f60 100644
--- a/facedetect/shotwell-facedetect.cpp
+++ b/facedetect/shotwell-facedetect.cpp
@@ -29,13 +29,13 @@ static gboolean on_handle_detect_faces(ShotwellFaces1 *object,
for (vector<FaceRect>::const_iterator r = rects.begin(); r != rects.end(); r++) {
GVariant *rect = g_variant_new("(dddd)", r->x, r->y, r->width, r->height);
g_variant_builder_add(builder, "(dddd)", rect);
+ g_debug("Returning %f,%f", r->x, r->y);
}
faces = g_variant_new("a(dddd)", builder);
g_variant_builder_unref (builder);
// Call return
shotwell_faces1_complete_detect_faces(object, invocation,
faces);
- g_free(faces);
return TRUE;
}
@@ -55,12 +55,21 @@ gboolean on_handle_recognise_face(ShotwellFaces1 *object,
return TRUE;
}
+gboolean on_handle_terminate(ShotwellFaces1 *object,
+ GDBusMethodInvocation *invocation) {
+ g_debug("Exiting...");
+ exit(0);
+ return TRUE;
+}
+
static void on_name_acquired(GDBusConnection *connection,
const gchar *name, gpointer user_data) {
ShotwellFaces1 *interface;
GError *error;
interface = shotwell_faces1_skeleton_new();
+ g_debug("Got name %s", name);
g_signal_connect(interface, "handle-detect-faces", G_CALLBACK (on_handle_detect_faces), NULL);
+ g_signal_connect(interface, "handle-terminate", G_CALLBACK (on_handle_terminate), NULL);
error = NULL;
!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(interface), connection,
"/org/gnome/shotwell/faces", &error);
}
diff --git a/src/AppDirs.vala b/src/AppDirs.vala
index 1515f05a..d42b7b32 100644
--- a/src/AppDirs.vala
+++ b/src/AppDirs.vala
@@ -330,7 +330,6 @@ class AppDirs {
}
#if ENABLE_FACES
-/*
public static File get_facedetect_bin() {
const string filename = "shotwell-facedetect";
File f = AppDirs.get_libexec_dir().get_parent().get_child("facedetect").get_child (filename);
@@ -339,7 +338,7 @@ class AppDirs {
}
return f;
}
- */
+
public static File get_haarcascade_file() {
File f =
File.new_for_path(AppDirs.get_exec_dir().get_parent().get_parent().get_child("facedetect").get_child("facedetect-haarcascade.xml").get_path());
if (f.query_exists()) {//testing meson builddir
diff --git a/src/faces/Face.vala b/src/faces/Face.vala
index 9be33c9d..722e1727 100644
--- a/src/faces/Face.vala
+++ b/src/faces/Face.vala
@@ -346,9 +346,18 @@ public class Face : DataSource, ContainerSource, Proxyable, Indexable {
// add them all at once to the SourceCollection
global.add_many(faces);
global.init_add_many_unlinked(unlinked);
+
+#if ENABLE_FACES
+ // Start the face detection background process
+ // FaceTool talks to it over DBus
+ start_facedetect_process();
+#endif
}
public static void terminate() {
+ try {
+ FaceDetect.interface.terminate();
+ } catch(Error e) {}
}
public static int compare_names(void *a, void *b) {
@@ -366,6 +375,26 @@ public class Face : DataSource, ContainerSource, Proxyable, Indexable {
public static bool equal_name_strings(void *a, void *b) {
return String.collated_equals(a, b);
}
+
+#if ENABLE_FACES
+ private static void start_facedetect_process() {
+ message("Launching facedetect process: %s", AppDirs.get_facedetect_bin().get_path());
+ // Start the watcher
+ FaceDetect.init();
+ // Start the background process
+ string[] argv = {AppDirs.get_facedetect_bin().get_path()};
+ int child_pid;
+ try {
+ GLib.Process.spawn_async(null, argv, null, GLib.SpawnFlags.SEARCH_PATH |
+ GLib.SpawnFlags.DO_NOT_REAP_CHILD, null, out child_pid);
+ message("Spawned facedetect, child pid: %d", (int)child_pid);
+ } catch (Error e) {
+ debug("Error spawning process: %s", e.message);
+ if (child_pid != 0)
+ GLib.Process.close_pid(child_pid);
+ }
+ }
+#endif
// Returns a Face for the name, creating a new empty one if it does not already exist.
// name should have already been prepared by prep_face_name.
diff --git a/src/faces/FaceDetect.vala b/src/faces/FaceDetect.vala
new file mode 100644
index 00000000..259d11e0
--- /dev/null
+++ b/src/faces/FaceDetect.vala
@@ -0,0 +1,73 @@
+/**
+ * Face detection and recognition functions
+ * Copyright 2018 Narendra A (narendra_m_a(at)yahoo(dot)com)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// DBus interface definition
+public struct FaceRect {
+ public double x;
+ public double y;
+ public double width;
+ public double height;
+}
+
+[DBus (name = "org.gnome.Shotwell.Faces1")]
+public interface FaceDetectInterface : Object {
+ public abstract FaceRect[] detect_faces(string inputName, string cascadeName, double scale)
+ throws IOError, DBusError;
+ public abstract void terminate() throws IOError, DBusError;
+}
+
+// Class to communicate with facedetect process over DBus
+public class FaceDetect {
+ public const string DBUS_NAME = "org.gnome.shotwell.faces";
+ public const string DBUS_PATH = "/org/gnome/shotwell/faces";
+ public static bool connected = false;
+
+ public static FaceDetectInterface interface;
+
+ public static void create_interface(DBusConnection connection, string bus_name, string owner) {
+ message("Dbus name %s available", bus_name);
+ if (bus_name == DBUS_NAME) {
+ try {
+ interface = Bus.get_proxy_sync (BusType.SESSION, DBUS_NAME, DBUS_PATH);
+ connected = true;
+ } catch(IOError e) {
+ }
+ }
+ }
+
+ public static void interface_gone(DBusConnection connection, string bus_name) {
+ message("Dbus name %s gone", bus_name);
+ connected = false;
+ }
+
+ public static void init() {
+ //Bus.watch_name(BusType.SYSTEM, DBUS_NAME, BusNameWatcherFlags.NONE, create_interface,
interface_gone);
+ try {
+ interface = Bus.get_proxy_sync(BusType.SESSION, DBUS_NAME, DBUS_PATH);
+ connected = true;
+ } catch(IOError e) {
+ }
+ }
+}
diff --git a/src/faces/FacesTool.vala b/src/faces/FacesTool.vala
index 7ff3e52c..00a8b7e0 100644
--- a/src/faces/FacesTool.vala
+++ b/src/faces/FacesTool.vala
@@ -314,8 +314,7 @@ public class FacesTool : EditingTools.EditingTool {
private class FaceDetectionJob : BackgroundJob {
private Gee.Queue<string> faces = null;
private string image_path;
- //private string output;
- public SpawnError? spawnError;
+ public string? spawnError;
public FaceDetectionJob(FacesToolWindow owner, string image_path,
CompletionCallback completion_callback, Cancellable cancellable,
@@ -326,66 +325,26 @@ public class FacesTool : EditingTools.EditingTool {
}
public override void execute() {
- Faces.FaceRect[] rects;
- debug("checking faces");
- Faces.detect_faces(image_path, AppDirs.get_haarcascade_file().get_path(), 4, out rects);
- faces = new Gee.PriorityQueue<string>();
- string serialized = "%s;%s".printf(
- FaceRectangle.SHAPE_TYPE,
- parse_serialized_geometry("x=%s&y=%s&width=%s&height=%s".printf(
- rects[0].x.to_string(), rects[0].y.to_string(), rects[0].width.to_string(),
rects[0].height.to_string())));
- debug("saw face %s", serialized);
- faces.add(serialized);
-
- /* try {
- string[] argv = {
- AppDirs.get_facedetect_bin().get_path(),
- "--cascade=" + AppDirs.get_haarcascade_file().get_path(),
- "--scale=1.2",
- image_path
- };
- Process.spawn_sync(null, argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out output);
-
- } catch (SpawnError e) {
- spawnError = e;
- critical(e.message);
-
+ if (!FaceDetect.connected) {
+ spawnError = "Face detect process not connected!\n";
return;
}
-
- string[] lines = output.split("\n");
- foreach (string line in lines) {
- if (line.length == 0)
- continue;
-
- string[] type_and_serialized = line.split(";");
- if (type_and_serialized.length != 2) {
- critical("Wrong serialized line in face detection program output.");
- assert_not_reached();
- }
-
- switch (type_and_serialized[0]) {
- case "face":
- StringBuilder serialized_geometry = new StringBuilder();
- serialized_geometry.append(FaceRectangle.SHAPE_TYPE);
- serialized_geometry.append(";");
- serialized_geometry.append(parse_serialized_geometry(type_and_serialized[1]));
-
- faces.add(serialized_geometry.str);
- break;
-
- case "warning":
- warning("%s\n", type_and_serialized[1]);
- break;
-
- case "error":
- critical("%s\n", type_and_serialized[1]);
- assert_not_reached();
-
- default:
- assert_not_reached();
- }
- } */
+ FaceRect[] rects;
+ try {
+ rects = FaceDetect.interface.detect_faces(image_path,
AppDirs.get_haarcascade_file().get_path(), 1.3);
+ } catch(Error e) {
+ spawnError = "DBus error: " + e.message + "!\n";
+ return;
+ }
+ faces = new Gee.PriorityQueue<string>();
+ for (int i = 0; i < rects.length; i++) {
+ string serialized = "%s;%s".printf(
+ FaceRectangle.SHAPE_TYPE,
+ parse_serialized_geometry("x=%s&y=%s&width=%s&height=%s".printf(
+ rects[i].x.to_string(), rects[i].y.to_string(), rects[i].width.to_string(),
rects[i].height.to_string())));
+ debug("saw face %s", serialized);
+ faces.add(serialized);
+ }
}
private string parse_serialized_geometry(string serialized_geometry) {
@@ -963,7 +922,7 @@ public class FacesTool : EditingTools.EditingTool {
if (face_detection.spawnError != null){
string spawnErrorMessage = _("Error trying to spawn face detection program:\n");
- AppWindow.error_message(spawnErrorMessage + face_detection.spawnError.message + "\n");
+ AppWindow.error_message(spawnErrorMessage + face_detection.spawnError + "\n");
faces_tool_window.set_editing_phase(EditingPhase.DETECTING_FACES_FINISHED);
} else
pick_faces_from_autodetected();
diff --git a/src/faces_opencv/faces_opencv.cpp b/src/faces_opencv/faces_opencv.cpp
index dc04c1d3..b67fddb5 100644
--- a/src/faces_opencv/faces_opencv.cpp
+++ b/src/faces_opencv/faces_opencv.cpp
@@ -22,10 +22,12 @@ using namespace cv;
// OpenCV calls in C++
vector<FaceRect> ocvDetectFaces(Mat &img, CascadeClassifier &cascade, double scale) {
- Mat gray;
- cvtColor(img, gray, CV_BGR2GRAY);
+ UMat gray, uimg;
- Mat smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);
+ img.copyTo(uimg);
+ cvtColor(uimg, gray, CV_BGR2GRAY);
+
+ UMat smallImg(cvRound(uimg.rows / scale), cvRound(uimg.cols / scale), CV_8UC1);
Size smallImgSize = smallImg.size();
resize(gray, smallImg, smallImgSize, 0, 0, INTER_LINEAR);
diff --git a/src/meson.build b/src/meson.build
index b537438e..ce0788f0 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -27,18 +27,16 @@ face_sources = []
face_obj = ''
if get_option('face-detection')
- subdir('faces_opencv')
face_sources = (['faces/FacesBranch.vala',
'faces/FaceLocation.vala',
'faces/FacePage.vala',
'faces/FaceShape.vala',
'faces/Faces.vala',
'faces/Face.vala',
+ 'faces/FaceDetect.vala',
'db/FaceLocationTable.vala',
'db/FaceTable.vala',
'faces/FacesTool.vala'])
- shotwell_deps += [faces_dep]
- shotwell_libs += [faces_lib]
endif
if unity_available
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]