Правильный способ сделать библиотеку с заголовком priv / public и передать cv :: Mat - PullRequest
0 голосов
/ 20 декабря 2018

Мне нужно создать библиотеку .so или .a и различные заголовки, один из которых будет доступен пользователям для компиляции моей основной программы (и ссылки в коде, processmatinlibrary_pub.h) и другой для использования в определениях иотделяется от основного кода (processmatinlibrary.h).

Когда я использую открытый заголовок (без некоторых частных определений методов), иногда, в зависимости от структуры моей программы, я получаю ошибки сегментации или утверждения opencvниже я вставляю свой код, его можно загрузить из https://github.com/eld1e6o/TestErrorOnLibrary

Вот мой код и некоторые комментарии

Файлы для создания моей основной программы, которая использует функции из моей библиотеки

Это основная функция, я использую ее для проверки библиотеки с публичным заголовком Я получаю некоторые ошибки сегментации в зависимости от структуры моей программы Я могу вызвать ошибкиcommenting # определяет

#define _MAKE_ASSERT_OPENCV 1
#define _MAKE_SEGFAULT_ 1

* Если я изменю открытый заголовок на частный, у меня не возникнет проблем:

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

Вместоиз

#include "processmatinlibrary_pub.h" 

Кажется, это проблема стека, и мне нужно правильно определить библиотеку или заголовки

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

Это мой открытый заголовок, используемый для определения функций как открытых

#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

Файлы для создания моей библиотеки

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

Это мой частный заголовок, используемый для компиляции моей библиотеки, он отличается только для частных объявлений

#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

Как скомпилировать все эти

CMakeLists.txt

Обратите внимание, что я определил другой PATH для библиотеки OpenCV, возможно, есть ошибка для компиляции в стандартном PATH, я не могу проверить, что find_package (OpenCV REQUIRED) работает

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)

Мой вопрос и проблема: как правильно передать cv :: Mat в качестве аргумента через библиотеку w?один частный заголовок для библиотеки и другой (общедоступный заголовок) для совместного использования?

Полный код можно посмотреть здесь:

https://github.com/eld1e6o/TestErrorOnLibrary

Спасибо!

...