Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Correct way to make priv / public header and pass cv::Mat

Hello!

I need to make a .so or .a library and different headers, one of them to be shared with users to compile my main program (and link, in the code, processmatinlibrary_pub.h) and other to use in definitions and separated to the main code (processmatinlibrary.h).

When I use the public header (whitout some private definitions of methods), some times, depending on the structure of my program, I get segmentation faults or opencv assertions, below I paste my code, it could be dowloaded from https://github.com/eld1e6o/TestErrorOnLibrary

Here is my code and some comments

Files to create my main program, that uses functions on my library

This is the main function, I use it to check the library with public header I get some segmentation faults depending on the structure of my program I can force errors commenting #defines

#define _MAKE_ASSERT_OPENCV 1
#define _MAKE_SEGFAULT_ 1

*If I change the public header to the private header, I have not problems:

#include "processmatinlibrary.h" it works but the headers are not cshared

Instead of

#include "processmatinlibrary_pub.h"

It seems that is a stack problem and I need to define the library or the headers in the right way

Main.cpp

#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include "processmatinlibrary_pub.h"  //If I change this header to #include "processmatinlibrary.h" it works but the headers are not cshared 

using namespace std;
using namespace cv;

#define _MAKE_ASSERT_OPENCV 1
//#define _MAKE_SEGFAULT_ 1

void testEmpty(cv::Mat test_img, std::string msg)
{
    cout << "* Check empty " << msg ;
    if(test_img.empty())
    {
    cout << ": Image is Empty " << endl;
    exit(1);
    }
    else cout << ": Image is not empty " << endl;
}

int main(int argc, char* argv[])
{
    // Classify and get probabilities
    Mat test_img = imread(argv[1], CV_LOAD_IMAGE_COLOR);

    testEmpty(test_img, "After load image");

    cv::resize(test_img, test_img, cv::Size(256, 256));

    cout << " After resize " << endl;

    testEmpty(test_img, "Before initialize library ");

    ProcessMatInLibrary matToLibrary;

#ifdef _MAKE_SEGFAULT_
    return 0; // If I comment this line, I got a segmentation fault: Segmentation Fault (`core' generated)

#endif
    testEmpty(test_img, "After initialize library ");

    bool b = matToLibrary.flip(test_img);

    testEmpty(test_img, "After use function in library ");

    cout << "In main " << endl;
    /*
     * If I define _MAKE_ASSERT_OPENCV, I got errors
    OpenCV(3.4.1) Error: Assertion failed (0 <= _dims && _dims <= 32) in setSize, file /home/diego/Code/opencv/modules/core/src/matrix.cpp, line 209
    terminate called after throwing an instance of 'cv::Exception'
      what():  OpenCV(3.4.1) /home/diego/Code/opencv/modules/core/src/matrix.cpp:209: error: (-215) 0 <= _dims && _dims <= 32 in function setSize
    */
#ifndef _MAKE_ASSERT_OPENCV
    imshow("Test before close", test_img); //If i comment this two lines, I got segmentation faults (OpenCV exception)
    waitKey(0);
#endif
}

processmathlibrary_pub.h

This is my public header, used to define functions as publics

#ifndef PROCESSMATINLIBRARY_H
#define PROCESSMATINLIBRARY_H

#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>

class ProcessMatInLibrary
{
public:
    ProcessMatInLibrary();
    bool flip(cv::Mat image);
    bool myTest(cv::Mat one);
};

#endif // PROCESSMATINLIBRARY_H

Files to create my library

processmathinlibrary.cpp

#include "processmatinlibrary.h"

using namespace std;
using namespace cv;

#include <iostream>

ProcessMatInLibrary::ProcessMatInLibrary()
{
    cout << "Initialized " << endl;
}

bool ProcessMatInLibrary::flip(cv::Mat image)
{
    cout << "** Inside Library: " << endl;
    if(image.empty())
    {
    cout << " Image is empty" << endl;
    return false;
    }
    cout << " Image is not empty " << endl;

    //    return false;
    Mat image2;
    cv::flip(image, image2, 0);

    imshow("Image in library", image);
    imshow("Image2 in library", image2);
    waitKey(0);

    cout << "Inside Library: Image is not empty" << endl;
    return true;
}


bool ProcessMatInLibrary::myTest(cv::Mat one)
{
    one.copyTo(_img);
}

processmathlibrary.h

This is my private header, used to compile my library, it only differs on private declarations

#ifndef PROCESSMATINLIBRARY_LIB_H
#define PROCESSMATINLIBRARY_LIB_H

#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>

class ProcessMatInLibrary
{
public:
    ProcessMatInLibrary();
    bool flip(cv::Mat image);
    bool myTest(cv::Mat one);
private:
    cv::Mat _img;
};

#endif // PROCESSMATINLIBRARY_LIB_H

How to compile all of this

CMakeLists.txt

Note that I have defined other PATH for OpenCV library, maybe there is an error to compile in the default PATH, I cannot check that find_package(OpenCV REQUIRED) is working

cmake_minimum_required(VERSION 2.8.12)

project(test_pub_priv)

set(CMAKE_CXX_FLAGS "-Wall -Wextra -O3 -std=c++11")

#set(OpenCV_INCLUDE_DIRS "./include/")

find_package(OpenCV REQUIRED)

message(" ** Test with public private libraries ** ")

include_directories(${OpenCV_INCLUDE_DIRS})

aux_source_directory(./src SRC_LIST)
include_directories(./hpp SRC_LIST)
FILE(GLOB_RECURSE LibFiles "./hpp/*.h")
add_custom_target(headers SOURCES ${LibFiles})

add_library(myFramework ${SRC_LIST} )
add_executable(test_pub_priv ./examples/Main.cpp)
target_link_libraries(test_pub_priv ${OpenCV_LIBS} myFramework)

My question and problem is: What is the right way to pass a cv::Mat as argument trough library with one private header to the library and other (public header) to be shared?

Complete code can be seen here:

https://github.com/eld1e6o/TestErrorOnLibrary

Thanks!

Correct way to make priv / public header and pass cv::Mat

Hello!

I need to make a .so or .a library and different headers, one of them to be shared with users to compile my main program (and link, in the code, processmatinlibrary_pub.h) and other to use in definitions and separated to the main code (processmatinlibrary.h).

When I use the public header (whitout some private definitions of methods), some times, depending on the structure of my program, I get segmentation faults or opencv assertions, below I paste my code, it could be dowloaded from https://github.com/eld1e6o/TestErrorOnLibrary

Here is my code and some comments

Files to create my main program, that uses functions on my library

This is the main function, I use it to check the library with public header I get some segmentation faults depending on the structure of my program I can force errors commenting #defines

#define _MAKE_ASSERT_OPENCV 1
#define _MAKE_SEGFAULT_ 1

*If I change the public header to the private header, I have not problems:

#include "processmatinlibrary.h" it works but the headers are not cshared

Instead of

#include "processmatinlibrary_pub.h"

It seems that is a stack problem and I need to define the library or the headers in the right way

Main.cpp

#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include "processmatinlibrary_pub.h"  //If I change this header to #include "processmatinlibrary.h" it works but the headers are not cshared 

using namespace std;
using namespace cv;

#define _MAKE_ASSERT_OPENCV 1
//#define _MAKE_SEGFAULT_ 1

void testEmpty(cv::Mat test_img, std::string msg)
{
    cout << "* Check empty " << msg ;
    if(test_img.empty())
    {
    cout << ": Image is Empty " << endl;
    exit(1);
    }
    else cout << ": Image is not empty " << endl;
}

int main(int argc, char* argv[])
{
    // Classify and get probabilities
    Mat test_img = imread(argv[1], CV_LOAD_IMAGE_COLOR);

    testEmpty(test_img, "After load image");

    cv::resize(test_img, test_img, cv::Size(256, 256));

    cout << " After resize " << endl;

    testEmpty(test_img, "Before initialize library ");

    ProcessMatInLibrary matToLibrary;

#ifdef _MAKE_SEGFAULT_
    return 0; // If I comment this line, I got a segmentation fault: Segmentation Fault (`core' generated)

#endif
    testEmpty(test_img, "After initialize library ");

    bool b = matToLibrary.flip(test_img);

    testEmpty(test_img, "After use function in library ");

    cout << "In main " << endl;
    /*
     * If I define _MAKE_ASSERT_OPENCV, I got errors
    OpenCV(3.4.1) Error: Assertion failed (0 <= _dims && _dims <= 32) in setSize, file /home/diego/Code/opencv/modules/core/src/matrix.cpp, line 209
    terminate called after throwing an instance of 'cv::Exception'
      what():  OpenCV(3.4.1) /home/diego/Code/opencv/modules/core/src/matrix.cpp:209: error: (-215) 0 <= _dims && _dims <= 32 in function setSize
    */
#ifndef _MAKE_ASSERT_OPENCV
    imshow("Test before close", test_img); //If i comment this two lines, I got segmentation faults (OpenCV exception)
    waitKey(0);
#endif
}

processmathlibrary_pub.h

This is my public header, used to define functions as publics

#ifndef PROCESSMATINLIBRARY_H
#define PROCESSMATINLIBRARY_H

#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>

class ProcessMatInLibrary
{
public:
    ProcessMatInLibrary();
    bool flip(cv::Mat image);
    bool myTest(cv::Mat one);
};

#endif // PROCESSMATINLIBRARY_H

Files to create my library

processmathinlibrary.cpp

#include "processmatinlibrary.h"

using namespace std;
using namespace cv;

#include <iostream>

ProcessMatInLibrary::ProcessMatInLibrary()
{
    cout << "Initialized " << endl;
}

bool ProcessMatInLibrary::flip(cv::Mat image)
{
    cout << "** Inside Library: " << endl;
    if(image.empty())
    {
    cout << " Image is empty" << endl;
    return false;
    }
    cout << " Image is not empty " << endl;

    //    return false;
    Mat image2;
    cv::flip(image, image2, 0);

    imshow("Image in library", image);
    imshow("Image2 in library", image2);
    waitKey(0);

    cout << "Inside Library: Image is not empty" << endl;
    return true;
}


bool ProcessMatInLibrary::myTest(cv::Mat one)
{
    one.copyTo(_img);
}

processmathlibrary.h

This is my private header, used to compile my library, it only differs on private declarations

#ifndef PROCESSMATINLIBRARY_LIB_H
#define PROCESSMATINLIBRARY_LIB_H

#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>

class ProcessMatInLibrary
{
public:
    ProcessMatInLibrary();
    bool flip(cv::Mat image);
    bool myTest(cv::Mat one);
private:
    cv::Mat _img;
};

#endif // PROCESSMATINLIBRARY_LIB_H

How to compile all of this

CMakeLists.txt

Note that I have defined other PATH for OpenCV library, maybe there is an error to compile in the default PATH, I cannot check that find_package(OpenCV REQUIRED) is working

cmake_minimum_required(VERSION 2.8.12)

project(test_pub_priv)

set(CMAKE_CXX_FLAGS "-Wall -Wextra -O3 -std=c++11")

#set(OpenCV_INCLUDE_DIRS "./include/")

find_package(OpenCV REQUIRED)

message(" ** Test with public private libraries ** ")

include_directories(${OpenCV_INCLUDE_DIRS})

aux_source_directory(./src SRC_LIST)
include_directories(./hpp SRC_LIST)
FILE(GLOB_RECURSE LibFiles "./hpp/*.h")
add_custom_target(headers SOURCES ${LibFiles})

add_library(myFramework ${SRC_LIST} )
add_executable(test_pub_priv ./examples/Main.cpp)
target_link_libraries(test_pub_priv ${OpenCV_LIBS} myFramework)

My question and problem is: What is the right way to pass a cv::Mat as argument trough library with one private header to the library and other (public header) to be shared?

Complete code can be seen here:

https://github.com/eld1e6o/TestErrorOnLibrary

Thanks!