Нет «настроек инструмента» в Eclipse - PullRequest
0 голосов
/ 11 мая 2019

Я строю проект на Java, и у меня есть C ++ и файл заголовка для обработки изображений, который я хочу использовать.

Их имена: "SPImageProc.cpp" и "SPImageProc.h".

Поэтому я использовал JNI согласно инструкциям этого урока:

https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html#zz-2.6

(я использую только часть: «2.6 JNI в Eclipse»).

Из этого туториала вы узнаете, как создать файл заголовка и файл C ++.

Из-за этогоЯ копирую исходный файл C ++ и заголовочный файл в созданный мной файл C ++ (имя которого совпадает с именем оригинала - «SPImageProc.cpp»).

Теперь одна из строк, которую я пытался скопироватьстроки, которые используют opencv:

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>

Так что мне нужно настроить opencv.

В учебном пособии, которое я нашел для этого, одна из инструкций была:

Перейдите в «Проект -> Свойства -> Сборка C / C ++ -> Настройки» и нажмитена> «Включает»

А на снимке экрана «Включает» находится на вкладке «Настройки инструмента».

Но у меня нет этой вкладки.

Решение в этом посте:

Не удалось найти настройки инструмента в Eclipse CDT

, чтобы проверить "Автоматически генерировать Makefile".

Но я боюсь, что это вызовет у меня проблемы.Тем более, что я использую JNI.И потому что я использую CDT в качестве плагина для Eclipse Java.

И я не знаю, как это проверить, поэтому я не буду знать, как решать проблемы, которые он создаст (если будет).

Среда разработки

+ Eclipse IDE для разработчиков Java (32-разрядная версия) Версия: Kepler Service Release 2.

+ CDT-плагин для Eclipse

+ Windows 10 64-разрядная версия (я использую 32-разрядную версию Eclipse)потому что в какой-то момент 64-разрядное затмение не могло открыться, и решение состояло в том, чтобы использовать 32-разрядное затмение)

Исходный файл C ++, который я хочу использовать

#include <cstdlib>
#include <cassert>
#include <cstring>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <cstdio>
#include "SPImageProc.h"
extern "C" {
#include "SPLogger.h"
}

using namespace cv;
using namespace std;

#define PCA_MEAN_STR "mean"
#define PCA_EIGEN_VEC_STR "e_vectors"
#define PCA_EIGEN_VAL_STR "e_values"
#define STRING_LENGTH 1024
#define WARNING_MSG_LENGTH 2048

#define GENERAL_ERROR_MSG "An error occurred"
#define PCA_DIM_ERROR_MSG "PCA dimension couldn't be resolved"
#define PCA_FILE_NOT_EXIST "PCA file doesn't exist"
#define PCA_FILE_NOT_RESOLVED "PCA filename couldn't be resolved"
#define NUM_OF_IMAGES_ERROR "Number of images couldn't be resolved"
#define NUM_OF_FEATS_ERROR "Number of features couldn't be resolved"
#define MINIMAL_GUI_ERROR "Minimal GUI mode couldn't be resolved"
#define IMAGE_PATH_ERROR "Image path couldn't be resolved"
#define IMAGE_NOT_EXIST_MSG ": Images doesn't exist"
#define MINIMAL_GUI_NOT_SET_WARNING "Cannot display images in non-Minimal-GUI mode"
#define ALLOC_ERROR_MSG "Allocation error"
#define INVALID_ARG_ERROR "Invalid arguments"





void sp::ImageProc::initFromConfig(const SPConfig config) {
    SP_CONFIG_MSG msg = SP_CONFIG_SUCCESS;
    pcaDim = spConfigGetPCADim(config, &msg);
    if (msg != SP_CONFIG_SUCCESS) {
        spLoggerPrintError(PCA_DIM_ERROR_MSG, __FILE__, __func__, __LINE__);
        throw Exception();
    }
    numOfImages = spConfigGetNumOfImages(config, &msg);
    if (msg != SP_CONFIG_SUCCESS) {
        spLoggerPrintError(NUM_OF_IMAGES_ERROR, __FILE__, __func__, __LINE__);
        throw Exception();
    }
    numOfFeatures = spConfigGetNumOfFeatures(config, &msg);
    if (msg != SP_CONFIG_SUCCESS) {
        spLoggerPrintError(NUM_OF_FEATS_ERROR, __FILE__, __func__, __LINE__);
        throw Exception();
    }
    minimalGui = spConfigMinimalGui(config, &msg);
    if (msg != SP_CONFIG_SUCCESS) {
        spLoggerPrintError(MINIMAL_GUI_ERROR, __FILE__, __func__, __LINE__);
        throw Exception();
    }
}

void sp::ImageProc::getImagesMat(vector<Mat>& images, const SPConfig config) {
    char warningMSG[WARNING_MSG_LENGTH] = { '\0' };
    for (int i = 0; i < numOfImages; i++) {
        char imagePath[STRING_LENGTH + 1] = { '\0' };
        if (spConfigGetImagePath(imagePath, config, i) != SP_CONFIG_SUCCESS) {
            spLoggerPrintError(IMAGE_PATH_ERROR, __FILE__, __func__, __LINE__);
            throw Exception();
        }
        Mat img = imread(imagePath, IMREAD_GRAYSCALE);
        if (img.empty()) {
            sprintf(warningMSG, "%s %s", imagePath, IMAGE_NOT_EXIST_MSG);
            spLoggerPrintWarning(warningMSG, __FILE__, __func__, __LINE__);
            continue;
        }
        images.push_back(img);
    }
}

void sp::ImageProc::getFeatures(vector<Mat>& images, Mat& features) {
    //To store the keypoints that will be extracted by SIFT
    vector<KeyPoint> keypoints;
    //To store the SIFT descriptor of current image
    Mat descriptor;
    //To store all the descriptors that are extracted from all the images.

    //The SIFT feature extractor and descriptor
    Ptr<xfeatures2d::SiftDescriptorExtractor> detector =
            xfeatures2d::SIFT::create(numOfFeatures);

    //feature descriptors and build the vocabulary
    for (int i = 0; i < static_cast<int>(images.size()); i++) {
        //detect feature points
        detector->detect(images[i], keypoints);
        //compute the descriptors for each keypoint
        detector->compute(images[i], keypoints, descriptor);
        //put the all feature descriptors in a single Mat object
        features.push_back(descriptor);
    }
}

void sp::ImageProc::preprocess(const SPConfig config) {
    try {
        vector<Mat> images;
        Mat features;
        char pcaPath[STRING_LENGTH + 1] = { '\0' };
        getImagesMat(images, config);
        getFeatures(images, features);
        pca = PCA(features, Mat(), CV_PCA_DATA_AS_ROW, pcaDim);
        if (spConfigGetPCAPath(pcaPath, config) != SP_CONFIG_SUCCESS) {
            spLoggerPrintError(PCA_FILE_NOT_RESOLVED, __FILE__, __func__,
            __LINE__);
            throw Exception();
        }
        FileStorage fs(pcaPath, FileStorage::WRITE);
        fs << PCA_EIGEN_VEC_STR << pca.eigenvectors;
        fs << PCA_EIGEN_VAL_STR << pca.eigenvalues;
        fs << PCA_MEAN_STR << pca.mean;
        fs.release();
    } catch (...) {
        spLoggerPrintError(GENERAL_ERROR_MSG, __FILE__, __func__, __LINE__);
        throw Exception();
    }
}

void sp::ImageProc::initPCAFromFile(const SPConfig config) {
    if (!config) {
        spLoggerPrintError(GENERAL_ERROR_MSG, __FILE__, __func__, __LINE__);
        throw Exception();
    }
    char pcaFilename[STRING_LENGTH + 1] = { '\0' };
    if (spConfigGetPCAPath(pcaFilename, config) != SP_CONFIG_SUCCESS) {
        spLoggerPrintError(PCA_FILE_NOT_RESOLVED, __FILE__, __func__, __LINE__);
        throw Exception();
    }
    FileStorage fs(pcaFilename, FileStorage::READ);
    if (!fs.isOpened()) {
        spLoggerPrintError(PCA_FILE_NOT_EXIST, __FILE__, __func__, __LINE__);
        throw Exception();
    }
    fs[PCA_EIGEN_VEC_STR] >> pca.eigenvectors;
    fs[PCA_EIGEN_VAL_STR] >> pca.eigenvalues;
    fs[PCA_MEAN_STR] >> pca.mean;
    fs.release();
}

sp::ImageProc::ImageProc(const SPConfig config) {
    try {
        if (!config) {
            spLoggerPrintError(INVALID_ARG_ERROR, __FILE__, __func__, __LINE__);
            throw Exception();
        }
        SP_CONFIG_MSG msg;
        bool preprocMode = false;
        initFromConfig(config);
        if ((preprocMode = spConfigIsExtractionMode(config, &msg))) {
            preprocess(config);
        } else {
            initPCAFromFile(config);
        }
    } catch (...) {
        spLoggerPrintError(GENERAL_ERROR_MSG, __FILE__, __func__, __LINE__);
        throw Exception();
    }
}

SPPoint* sp::ImageProc::getImageFeatures(const char* imagePath, int index,
        int* numOfFeats) {
    vector<KeyPoint> keypoints;
    Mat descriptor, img, points;
    double* pcaSift = NULL;
    char errorMSG[STRING_LENGTH * 2];
    Ptr<xfeatures2d::SiftDescriptorExtractor> detector;
    if (!imagePath || !numOfFeats) {
        spLoggerPrintError(INVALID_ARG_ERROR, __FILE__, __func__, __LINE__);
        return NULL;
    }
    img = imread(imagePath, IMREAD_GRAYSCALE);
    if (img.empty()) {
        sprintf(errorMSG, "%s %s", imagePath, IMAGE_NOT_EXIST_MSG);
        spLoggerPrintError(errorMSG, __FILE__, __func__, __LINE__);
        return NULL;
    }
    detector = xfeatures2d::SIFT::create(numOfFeatures);
    detector->detect(img, keypoints);
    detector->compute(img, keypoints, descriptor);
    points = pca.project(descriptor);
    pcaSift = (double*) malloc(sizeof(double) * pcaDim);
    if (!pcaSift) {
        spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__);
        return NULL;
    }
    *numOfFeats = points.rows;
    SPPoint* resPoints = (SPPoint*) malloc(sizeof(*resPoints) * points.rows);
    if (!resPoints) {
        free(pcaSift);
        spLoggerPrintError(ALLOC_ERROR_MSG, __FILE__, __func__, __LINE__);
        return NULL;
    }
    for (int i = 0; i < points.rows; i++) {
        for (int j = 0; j < points.cols; j++) {
            pcaSift[j] = (double) points.at<float>(i, j);
        }
        resPoints[i] = spPointCreate(pcaSift, pcaDim, index);
    }
    free(pcaSift);
    return resPoints;
}

void sp::ImageProc::showImage(const char* imgPath) {
    if (minimalGui) {
        Mat img = imread(imgPath, cv::IMREAD_COLOR);
        if (img.empty()) {
            spLoggerPrintWarning(IMAGE_NOT_EXIST_MSG, __FILE__, __func__,
            __LINE__);
            return;
        }
        imshow(windowName, img);
        waitKey(0);
        destroyAllWindows();
    } else {
        spLoggerPrintWarning(MINIMAL_GUI_NOT_SET_WARNING, __FILE__, __func__,
        __LINE__);
    }

}


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

#ifndef SPIMAGEPROC_H_
#define SPIMAGEPROC_H_
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <vector>

extern "C" {
#include "SPConfig.h"
#include "SPPoint.h"
}

namespace sp {

/**
 * A class which supports different image processing functionalites.
 */
class ImageProc {
private:
    const char* windowName = "Software Project CBIR";
    int pcaDim;
    int numOfImages;
    int numOfFeatures;
    cv::PCA pca;
    bool minimalGui;
    void initFromConfig(const SPConfig);
    void getImagesMat(std::vector<cv::Mat>&, const SPConfig);
    void getFeatures(std::vector<cv::Mat>&,
            cv::Mat&);
    void preprocess(const SPConfig config);
    void initPCAFromFile(const SPConfig config);
public:

    /**
     * Creates a new object for the purpose of image processing based
     * on the configuration file.
     * @param config - the configuration file from which the object is created
     */
    ImageProc(const SPConfig config);

    /**
     * Returns an array of features for the image imagePath. All SPPoint elements
     * will have the index given by index. The actual number of features extracted
     * for this image will be stored in the pointer given by numOfFeats.
     *
     * @param imagePath - the target imagePath
     * @param index - the index  of the image in the database
     * @param numOfFeats - a pointer in which the actual number of feats extracted
     *                     will be stored
     * @return
     * An array of the actual features extracted. NULL is returned in case of
     * an error.
     */
    SPPoint* getImageFeatures(const char* imagePath,int index,int* numOfFeats);

    /**
     *  Displays the image given by imagePath. Notice that this function works
     *  only in MinimalGUI mode (otherwise a warnning message is printed).
     *
     *  @param imagePath - the path of the image to be displayed
     */
    void showImage(const char* imagePath);
};

}
#endif

Файл C ++, который я создал (с помощью руководства jni)

#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>


#include <jni.h>
#include <stdio.h>
#include "SPImageProc.h"

JNIEXPORT void JNICALL Java_SPImageProc_cppFunc(JNIEnv *env, jobject thisObj) {
   printf("After adding include in the cpp file !\n");
   return;
}

Файл заголовка, который был создан моим make-файлом

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class SPImageProc */

#ifndef _Included_SPImageProc
#define _Included_SPImageProc
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     SPImageProc
 * Method:    cppFunc
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_SPImageProc_cppFunc
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

makefile

# Define a variable for classpath
CLASS_PATH = ../bin

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

all : spimageproc.dll

# $@ matches the target, $< matches the first dependency
spimageproc.dll : SPImageProc.o
    g++ -Wl,--add-stdcall-alias -shared -o $@ $<

# $@ matches the target, $< matches the first dependency
SPImageProc.o : SPImageProc.cpp SPImageProc.h
    g++ -I"C:\Program Files (x86)\Java\jdk1.8.0_212\include" -I"C:\Program Files (x86)\Java\jdk1.8.0_212\include\win32" -c $< -o $@

# $* matches the target filename without the extension
SPImageProc.h : SPImageProc.class
    javah -classpath $(CLASS_PATH) $*

clean :
    rm SPImageProc.h SPImageProc.o spimageproc.dll

SPImageProc.java

public class SPImageProc {

    static {
        System.loadLibrary("spimageproc"); // spimageproc.dll

    }

    // Declare native method
    private native void cppFunc();

    public static void function() {
        new SPImageProc().cppFunc(); // Allocate an instance and invoke the native
                                    // method
    }
}

CBIR.java

public class CBIR {


   public static void main(String[] args) {
      SPImageProc.function();
   }

}

1 Ответ

0 голосов
/ 13 мая 2019

Используя Eclipse CDT, вы можете выбирать между:

  • Наличие Eclipse для управления вашими make-файлами
  • Написание make-файлов самостоятельно

Первый вариант дает вамДиалог ToolSettings (среди прочего), где вы можете ввести свои настройки, и CDT преобразует их в соответствующие параметры компилятора и компоновщика.Поэтому, если вы добавляете путь включения, CDT добавляет опцию компилятора -I.

Если вы решите написать make-файлы самостоятельно, это просто так.Вы должны добавить -I<your path> в make-файл самостоятельно (в строке, начинающейся с g++, в которую уже включены другие).

Не знаю, будет ли преобразование вашего проекта в управляемый CDT проект читатьсуществующий make-файл и сохраните его настройки, но вы всегда можете сделать резервную копию ваших файлов и просто попробовать.

...