Honza
Honza

Reputation: 1008

Running of "OpenPose C++ API Tutorial - Example 3 - Body from image" has failed

I have successfully installed openpose (with OpenCV, CUDA, and all required libraries). At first I have tried to run openpose by running demo application (I had to use argument --net-resolution):

./build/examples/openpose/openpose.bin --net-resolution "-1x64"

It is working correctly.

Now, I would like to use openpose in my own source code. So I wanted to build and run an example from OpenPose tutorial (03 Keypoints from image). But when I'm trying to run the source code, I got following output:

Starting OpenPose demo...
Configuring OpenPose...
Starting thread(s)...
Auto-detecting all available GPUs... Detected 1 GPU(s), using 1 of them starting at GPU 0.
F0806 22:47:55.485319 12505 syncedmem.cpp:71] Check failed: error == cudaSuccess (2 vs. 0)  out of memory
*** Check failure stack trace: ***
    @     0x7f35145810cd  google::LogMessage::Fail()
    @     0x7f3514582f33  google::LogMessage::SendToLog()
    @     0x7f3514580c28  google::LogMessage::Flush()
    @     0x7f3514583999  google::LogMessageFatal::~LogMessageFatal()
    @     0x7f3513c92c28  caffe::SyncedMemory::mutable_gpu_data()
    @     0x7f3513b1c202  caffe::Blob<>::mutable_gpu_data()
    @     0x7f3513cdfd10  caffe::ConvolutionLayer<>::Forward_gpu()
    @     0x7f3513c58f11  caffe::Net<>::ForwardFromTo()
    @     0x7f3517a89e9d  op::NetCaffe::forwardPass()
    @     0x7f3517ab244a  op::PoseExtractorCaffe::forwardPass()
    @     0x7f3517aab2d5  op::PoseExtractor::forwardPass()
    @     0x7f3517aa829f  op::WPoseExtractor<>::work()
    @     0x7f3517aebb79  op::Worker<>::checkAndWork()
    @     0x7f3517aebd03  op::SubThread<>::workTWorkers()
    @     0x7f3517af5968  op::SubThreadQueueInOut<>::work()
    @     0x7f3517aedfe1  op::Thread<>::threadFunction()
    @     0x7f351549766f  (unknown)
    @     0x7f3514bb96db  start_thread
    @     0x7f3514ef288f  clone

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)

I've disabled all possible additional options and here is my source:

#define OPENPOSE_FLAGS_DISABLE_PRODUCER
#define OPENPOSE_FLAGS_DISABLE_DISPLAY

#include <openpose/flags.hpp>
#include <openpose/headers.hpp>

DEFINE_string(image_path, "/home/user/Downloads/myimage.jpg",
              "Process an image.");
// Display
DEFINE_bool(no_display, false,
            "Enable to disable the visual display.");

// This worker will just read and return all the jpg files in a directory
void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
{
    try
    {
        if (datumsPtr != nullptr && !datumsPtr->empty())
        {
            // Display image
            cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
            cv::waitKey(0);
        }
        else
            op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
    }
    catch (const std::exception& e)
    {
        op::error(e.what(), __LINE__, __FUNCTION__, __FILE__);
    }
}

void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
{
    try
    {
        // Example: How to use the pose keypoints
        if (datumsPtr != nullptr && !datumsPtr->empty())
        {
            op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString(), op::Priority::High);
            op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString(), op::Priority::High);
            op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString(), op::Priority::High);
            op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString(), op::Priority::High);
        }
        else
            op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
    }
    catch (const std::exception& e)
    {
        op::error(e.what(), __LINE__, __FUNCTION__, __FILE__);
    }
}

void configureWrapper(op::Wrapper& opWrapper)
{
    try
    {
        // Configuring OpenPose

        // logging_level
        op::check(0 <= FLAGS_logging_level && FLAGS_logging_level <= 255, "Wrong logging_level value.",
                  __LINE__, __FUNCTION__, __FILE__);
        op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level);
        op::Profiler::setDefaultX(FLAGS_profile_speed);

        // Applying user defined configuration - GFlags to program variables
        // outputSize
        const auto outputSize = op::flagsToPoint(FLAGS_output_resolution, "-1x-1");
        // netInputSize
        const auto netInputSize = op::flagsToPoint(FLAGS_net_resolution, "-1x64");
        // poseMode
        const auto poseMode = op::flagsToPoseMode(FLAGS_body);
        // poseModel
        const auto poseModel = op::flagsToPoseModel(FLAGS_model_pose);
        // JSON saving
        if (!FLAGS_write_keypoint.empty())
            op::log("Flag `write_keypoint` is deprecated and will eventually be removed."
                    " Please, use `write_json` instead.", op::Priority::Max);
        // keypointScaleMode
        const auto keypointScaleMode = op::flagsToScaleMode(FLAGS_keypoint_scale);
        // heatmaps to add
        const auto heatMapTypes = op::flagsToHeatMaps(FLAGS_heatmaps_add_parts, FLAGS_heatmaps_add_bkg,
                                                      FLAGS_heatmaps_add_PAFs);
        const auto heatMapScaleMode = op::flagsToHeatMapScaleMode(FLAGS_heatmaps_scale);
        // >1 camera view?
        const auto multipleView = (FLAGS_3d || FLAGS_3d_views > 1);
        // Enabling Google Logging
        const bool enableGoogleLogging = true;

        // Pose configuration (use WrapperStructPose{} for default and recommended configuration)
        const op::WrapperStructPose wrapperStructPose{
                poseMode, netInputSize, outputSize, keypointScaleMode, FLAGS_num_gpu, FLAGS_num_gpu_start,
                FLAGS_scale_number, (float)FLAGS_scale_gap, op::flagsToRenderMode(FLAGS_render_pose, multipleView),
                poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap,
                FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapScaleMode, FLAGS_part_candidates,
                (float)FLAGS_render_threshold, FLAGS_number_people_max, FLAGS_maximize_positives, FLAGS_fps_max,
                FLAGS_prototxt_path, FLAGS_caffemodel_path, (float)FLAGS_upsampling_ratio, enableGoogleLogging};
        opWrapper.configure(wrapperStructPose);

        // Face configuration (use op::WrapperStructFace{} to disable it)
        opWrapper.configure(op::WrapperStructFace{});

        // Hand configuration (use op::WrapperStructHand{} to disable it)
        opWrapper.configure(op::WrapperStructHand{});

        // Extra functionality configuration (use op::WrapperStructExtra{} to disable it)
        opWrapper.configure(op::WrapperStructExtra{});

        // No GUI. Equivalent to: opWrapper.configure(op::WrapperStructGui{});
        opWrapper.configure(op::WrapperStructGui{});

        // Set to single-thread (for sequential processing and/or debugging and/or reducing latency)
        if (FLAGS_disable_multi_thread)
            opWrapper.disableMultiThreading();
    }
    catch (const std::exception& e)
    {
        op::error(e.what(), __LINE__, __FUNCTION__, __FILE__);
    }
}

int tutorialApiCpp()
{
    try
    {
        op::log("Starting OpenPose demo...", op::Priority::High);
        const auto opTimer = op::getTimerInit();

        // Configuring OpenPose
        op::log("Configuring OpenPose...", op::Priority::High);
        op::Wrapper opWrapper{op::ThreadManagerMode::Asynchronous};
        configureWrapper(opWrapper);

        // Starting OpenPose
        op::log("Starting thread(s)...", op::Priority::High);
        opWrapper.start();

        // Process and display image
        const auto imageToProcess = cv::imread(FLAGS_image_path);
        auto datumProcessed = opWrapper.emplaceAndPop(imageToProcess);
        if (datumProcessed != nullptr)
        {
            printKeypoints(datumProcessed);
            if (!FLAGS_no_display)
                display(datumProcessed);
        }
        else
            op::log("Image could not be processed.", op::Priority::High);

        // Measuring total time
        op::printTime(opTimer, "OpenPose demo successfully finished. Total time: ", " seconds.", op::Priority::High);

        // Return
        return 0;
    }
    catch (const std::exception& e)
    {
        return -1;
    }
}

int main(int argc, char *argv[])
{
    // Parsing command line flags
    gflags::ParseCommandLineFlags(&argc, &argv, true);

    // Running tutorialApiCpp
    return tutorialApiCpp();
}

Could you help me to find what could be possibly wrong? The message error == cudaSuccess (2 vs. 0) out of memory was showing even by openpose demo application until I set --net-resolution. After setting this argument, open pose has started to work correctly.

Thank you very much for any advice, any help or comment could lead me to solve the problem.

Upvotes: 1

Views: 1872

Answers (1)

Honza
Honza

Reputation: 1008

now I am almost feeling embarrassed. The problem was not in disabling some additional options or anything nearby. The problem was in this code:

const auto netInputSize = op::flagsToPoint(FLAGS_net_resolution, "-1x368");

Like I wrote, I wanted to decrease net resolution, because I have only 2GB of GPU memory. But when I've copied a pasted an example code, I saw the piece of code above and I thought that it means:

const auto netInputSize = op::flagsToPoint(<flag_name>, <flag_value>);

But it is not. After some exploration and debugging I've found that the value of the flag FLAGS_net_resolution is the same before this code and after it. I've found that if you want to change the default value of the flag in the code (not through command line) it is necessary to do it in the main() function before calling the function ParseCommandLineFlags() (viz Changing the Default Flag Value).

So, the solution to my problem was:

  1. copy example source code
  2. paste example source code into my source file
  3. change net resolution flag in the function main()
int main(int argc, char *argv[])
{
    FLAGS_net_resolution = "-1x256";

    // Parsing command line flags
    gflags::ParseCommandLineFlags(&argc, &argv, true);

    // Running tutorialApiCpp
    return tutorialApiCpp();
}

Notice: only the default value of the flag net_resolution was changed, it is still possible to set the value through the command line.

Thank you again.

Upvotes: 2

Related Questions