Использование Java с OpenCV и Mask_RCNN - PullRequest
0 голосов
/ 09 марта 2020

У меня большой опыт работы с Java, и я уже написал свои собственные утилиты для обработки изображений. Я понимаю, что существует множество учебных пособий для Python, но я гораздо больше склонен использовать Java, так как я хотел бы интегрировать некоторые возможности OpenCV 4.1 с моим существующим кодом Java. Один из моих экспериментов состоит в том, чтобы попытаться получить маски объектов, идентифицированных ионными изображениями, используя набор данных кокосов

// Give the textGraph and weight files for the model
private static final String TEXT_GRAPH = "models/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt";
private static final String MODEL_WEIGHTS = "models/mask_rcnn_inception_v2_coco_2018_01_28/frozen_inference_graph.pb";
private static final String CLASSES_FILE = "models/mscoco_labels.names";

TextFileConsumer consumer = new TextFileConsumer();
File textFile = new File(CLASSES_FILE);
if (textFile.exists()){
    BufferedReader fr1 = new BufferedReader(new FileReader(textFile));
    fr1.lines().forEach(consumer::storeLines);
}
String[] CLASSES = consumer.lines.toArray(new String[0]);
Mat image = Imgcodecs.imread("images/bird.jpg");
Size size = image.size();
int cols = image.cols();
int rows = image.rows();
double h = size.height;
double w = size.width;
int hh = (int)size.height;
int ww = (int)size.width;
Mat blob = org.opencv.dnn.Dnn.blobFromImage(image, 1.0,  new Size(w, h), Scalar.all(0), true, false);

// Load the network
Net net = org.opencv.dnn.Dnn.readNetFromTensorflow(MODEL_WEIGHTS, TEXT_GRAPH);
net.setPreferableBackend(org.opencv.dnn.Dnn.DNN_BACKEND_OPENCV);
net.setPreferableTarget(org.opencv.dnn.Dnn.DNN_TARGET_CPU);
net.setInput(blob);
ArrayList<String> outputlayers = new ArrayList<String>();
ArrayList<Mat> outputMats = new ArrayList<Mat>();
outputlayers.add("detection_out_final");
outputlayers.add("detection_masks");
net.forward(outputMats,outputlayers);
Mat numClasses = outputMats.get(0);
numClasses = numClasses.reshape(1, (int)numClasses.total() / 7);

for (int i = 0; i < numClasses.rows(); ++i) {
    double confidence = numClasses.get(i, 2)[0];
    //System.out.println(confidence);
    if (confidence > 0.2) {
        int classId = (int) numClasses.get(i, 1)[0];
        String label = CLASSES[classId] + ": " + confidence;
        System.out.println(label);
        int left   = (int)(numClasses.get(i, 3)[0] * cols);
        int top    = (int)(numClasses.get(i, 4)[0] * rows);
        int right  = (int)(numClasses.get(i, 5)[0] * cols);
        int bottom = (int)(numClasses.get(i, 6)[0] * rows);
        System.out.println(left + " " + top + " " + right + " " + bottom);
    }
}
Mat numMasks = outputMats.get(1);

Пока все хорошо. Моя проблема сейчас заключается в попытке получить формы сегментации из numMasks Mat. Размер дает 90x100, всего 2025000 и тип -1 * -1 * CV_32FC1, isCont = true, isSubmat = true. Я знаю, что мне тоже нужно изменить форму, возможно, так:

numMasks = numMasks.reshape(1, (int)numMasks.total() / 90);

Любая помощь будет принята с благодарностью. Дальнейшее редактирование Я думаю, что маски 15 x 15. 90 x 100 x 15 x 15 дают 2025000, так что я получаю общее количество, которое я видел ранее, поэтому мне нужно изменить размер маски и смешать с исходным изображением.

...