Face detection
- This tutorial assumes that RAPP API and OpenCV are installed and built
- This tutorial uses the 0.7.0 version of the C++ API
We are going to do a project using OpenCV, RAPP and CMake.
Using CMake requires you to configure your CMakeLists.txt in the root of your RAPP project. Essentially, the structure is the following:
project/
CMakeLists.txt
source/
face_detection.cpp
build/
Source code
We created a project called face_detection
with a folder source
where we have our
example call face_detection.cpp
.
You can see the complete example here.
In this example we take image data from a camera and we use the image to call the RAPP platform and look for faces. For acquisition of the image from our usb camera we use OpenCV:
cv::VideoCapture camera(0);
if(!camera.isOpened()) {
std::cout << "Failed to connect to the camera" << std::endl;
return -1;
}
We created the parameter camera
which is our dev0
. You will have to check if your camera is
the correct device and change the number if necessary. In the case that the program
doesn't recognise any devices, it will exit.
In previous face_detection
examples, we only print the result of the cloud to stdout. In this example we are goint to draw rectangles around the faces in the image that our camera is recording:
cv::namedWindow("Face detection", cv::WINDOW_AUTOSIZE);
The size of the window depends on the camera resolution. We can initialize our OpenCV matrix where we are going to save the image data from the camera:
cv::Mat frame;
We initialize the platform information and the service controller:
rapp::cloud::platform info = {"rapp.ee.auth.gr", "9001", "rapp_token"};
rapp::cloud::service_controller ctrl(info);
We define an inline lambda which will capture by reference the variables used, and at the same time will iterate the discovered faces and draw a frame around them:
auto callback = [&](std::vector<rapp::object::face> faces) {
std::cout << "Found: " << faces.size() << " faces" << std::endl;
for(auto each_face : faces) {
cv::rectangle(frame,
cv::Point(each_face.get_left_x(), each_face.get_left_y()),
cv::Point(each_face.get_right_x(), each_face.get_right_x()),
cv::Scalar(255,0,0),
1, 8, 0);
}
};
NOTE: keep in mind that we can't use a simple loop to make the calls. There is a pause between the calls so that our client doesn't hog up the CPU. Also, the platform may block us if we spam non-stop calls.
Because of that we wait for a second (see rapp-api/cpp/examples/loop.cpp
) before doing a call.
In the loop
example we use a std::chrono
object which counts the time between loops.
In this example, we are going to make a call every 500 ms.
auto before = std::chrono::system_clock::now();
for (;;) {
auto now = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - before).count();
...
}
OpenCV has the function cv::imencode
.
which saves an image matrix to an image file.
Thus, whilst we acquire an image matrix from OpenCV, we end up transmitting a PNG to the platform.
if (elapsed > 500) {
camera >> frame;
std::vector<int> param = {{ CV_IMWRITE_PNG_COMPRESSION, 3 }};
cv::vector<uchar> buf;
cv::imencode(".png", frame, buf, param);
std::vector<rapp::types::byte> bytes(buf.begin(), buf.end());
auto pic = rapp::object::picture(bytes);
before = now;
ctrl.make_call<rapp::cloud::face_detection>(pic, true, callback);
cv::imshow("Face detection", frame);
}
After calling the cloud function, we use cv::imshow
to draw the frame on the GUI.
The interface is not going to refresh the image until we use cv::waitKey
function.
CMakeLists.txt
We assume that you have built your RAPP API in the static and shared libraries mode.
This file is going to be the same that we have in helloworld/CMakeLists.txt
.
We only have to add the OpenCV library and change the names of the project and executable.
NOTE: If you want to use only the static libraries, you can see helloworld_static
project.
The only lines that we have to add are:
find_package(OpenCV REQUIRED)
target_link_libraries(face_detection ${RAPP_LIBRARIES}
${OpenCV_LIBS})
Building your code
The next step is to create our build
folder and build the prorgam:
- Go to your project path (in our case
face_detection/
) -
Build your project
mkdir build cd build cmake .. make
- If everything is ok, you will have an executable
face_detection
in the folder build. - Run your executable
./face_detection