chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1 @@
|
||||
misc/java/src/cpp/dnn_converters.hpp
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"type_dict": {
|
||||
"MatShape": {
|
||||
"j_type": "MatOfInt",
|
||||
"jn_type": "long",
|
||||
"jni_type": "jlong",
|
||||
"jni_var": "MatShape %(n)s",
|
||||
"suffix": "J",
|
||||
"v_type": "Mat",
|
||||
"j_import": "org.opencv.core.MatOfInt"
|
||||
},
|
||||
"vector_MatShape": {
|
||||
"j_type": "List<MatOfInt>",
|
||||
"jn_type": "long",
|
||||
"jni_type": "jlong",
|
||||
"jni_var": "std::vector< MatShape > %(n)s",
|
||||
"suffix": "J",
|
||||
"v_type": "Mat",
|
||||
"j_import": "org.opencv.core.MatOfInt"
|
||||
},
|
||||
"vector_vector_MatShape": {
|
||||
"j_type": "List<List<MatOfInt>>",
|
||||
"jn_type": "long",
|
||||
"jni_type": "jlong",
|
||||
"jni_var": "std::vector< std::vector<MatShape> > %(n)s",
|
||||
"suffix": "J",
|
||||
"v_type": "vector_Mat",
|
||||
"j_import": "org.opencv.core.MatOfInt"
|
||||
},
|
||||
"vector_size_t": {
|
||||
"j_type": "MatOfDouble",
|
||||
"jn_type": "long",
|
||||
"jni_type": "jlong",
|
||||
"jni_var": "std::vector<size_t> %(n)s",
|
||||
"suffix": "J",
|
||||
"v_type": "Mat",
|
||||
"j_import": "org.opencv.core.MatOfDouble"
|
||||
},
|
||||
"vector_Ptr_Layer": {
|
||||
"j_type": "List<Layer>",
|
||||
"jn_type": "List<Layer>",
|
||||
"jni_type": "jobject",
|
||||
"jni_var": "std::vector< Ptr<cv::dnn::Layer> > %(n)s",
|
||||
"suffix": "Ljava_util_List",
|
||||
"v_type": "vector_Layer",
|
||||
"j_import": "org.opencv.dnn.Layer"
|
||||
},
|
||||
"vector_Target": {
|
||||
"j_type": "List<Integer>",
|
||||
"jn_type": "List<Integer>",
|
||||
"jni_type": "jobject",
|
||||
"jni_var": "std::vector< cv::dnn::Target > %(n)s",
|
||||
"suffix": "Ljava_util_List",
|
||||
"v_type": "vector_Target"
|
||||
},
|
||||
"LayerId": {
|
||||
"j_type": "DictValue",
|
||||
"jn_type": "long",
|
||||
"jn_args": [
|
||||
[
|
||||
"__int64",
|
||||
".getNativeObjAddr()"
|
||||
]
|
||||
|
||||
],
|
||||
"jni_name": "(*(*(Ptr<cv::dnn::DictValue>*)%(n)s_nativeObj))",
|
||||
"jni_type": "jlong",
|
||||
"suffix": "J",
|
||||
"j_import": "org.opencv.dnn.DictValue"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
// Author: abratchik
|
||||
|
||||
#include "dnn_converters.hpp"
|
||||
#include "converters.h"
|
||||
|
||||
#define LOG_TAG "org.opencv.dnn"
|
||||
|
||||
void Mat_to_MatShape(cv::Mat& mat, MatShape& matshape)
|
||||
{
|
||||
matshape.clear();
|
||||
CHECK_MAT(mat.type()==CV_32SC1 && mat.cols==1);
|
||||
matshape = (MatShape) mat;
|
||||
}
|
||||
|
||||
void MatShape_to_Mat(MatShape& matshape, cv::Mat& mat)
|
||||
{
|
||||
mat = cv::Mat(matshape, true);
|
||||
}
|
||||
|
||||
void Mat_to_vector_MatShape(cv::Mat& mat, std::vector<MatShape>& v_matshape)
|
||||
{
|
||||
v_matshape.clear();
|
||||
if(mat.type() == CV_32SC2 && mat.cols == 1)
|
||||
{
|
||||
v_matshape.reserve(mat.rows);
|
||||
for(int i=0; i<mat.rows; i++)
|
||||
{
|
||||
cv::Vec<int, 2> a = mat.at< cv::Vec<int, 2> >(i, 0);
|
||||
long long addr = (((long long)a[0])<<32) | (a[1]&0xffffffff);
|
||||
cv::Mat& m = *( (cv::Mat*) addr );
|
||||
MatShape matshape = (MatShape) m;
|
||||
v_matshape.push_back(matshape);
|
||||
}
|
||||
} else {
|
||||
LOGD("Mat_to_vector_MatShape() FAILED: mat.type() == CV_32SC2 && mat.cols == 1");
|
||||
}
|
||||
}
|
||||
|
||||
void vector_MatShape_to_Mat(std::vector<MatShape>& v_matshape, cv::Mat& mat)
|
||||
{
|
||||
int count = (int)v_matshape.size();
|
||||
mat.create(count, 1, CV_32SC2);
|
||||
for(int i=0; i<count; i++)
|
||||
{
|
||||
cv::Mat temp_mat = cv::Mat(v_matshape[i], true);
|
||||
long long addr = (long long) new cv::Mat(temp_mat);
|
||||
mat.at< cv::Vec<int, 2> >(i, 0) = cv::Vec<int, 2>(addr>>32, addr&0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
void Mat_to_vector_vector_MatShape(cv::Mat& mat, std::vector< std::vector< MatShape > >& vv_matshape)
|
||||
{
|
||||
std::vector<cv::Mat> vm;
|
||||
vm.reserve( mat.rows );
|
||||
Mat_to_vector_Mat(mat, vm);
|
||||
for(size_t i=0; i<vm.size(); i++)
|
||||
{
|
||||
std::vector<MatShape> vmatshape;
|
||||
Mat_to_vector_MatShape(vm[i], vmatshape);
|
||||
vv_matshape.push_back(vmatshape);
|
||||
}
|
||||
}
|
||||
|
||||
void vector_vector_MatShape_to_Mat(std::vector< std::vector< MatShape > >& vv_matshape, cv::Mat& mat)
|
||||
{
|
||||
std::vector<cv::Mat> vm;
|
||||
vm.reserve( vv_matshape.size() );
|
||||
for(size_t i=0; i<vv_matshape.size(); i++)
|
||||
{
|
||||
cv::Mat m;
|
||||
vector_MatShape_to_Mat(vv_matshape[i], m);
|
||||
vm.push_back(m);
|
||||
}
|
||||
vector_Mat_to_Mat(vm, mat);
|
||||
}
|
||||
|
||||
jobject vector_Ptr_Layer_to_List(JNIEnv* env, std::vector<cv::Ptr<cv::dnn::Layer> >& vs)
|
||||
{
|
||||
static jclass juArrayList = ARRAYLIST(env);
|
||||
static jmethodID m_create = CONSTRUCTOR(env, juArrayList);
|
||||
jmethodID m_add = LIST_ADD(env, juArrayList);
|
||||
|
||||
static jclass jLayerClass = LAYER(env);
|
||||
static jmethodID m_create_layer = LAYER_CONSTRUCTOR(env, jLayerClass);
|
||||
|
||||
jobject result = env->NewObject(juArrayList, m_create, vs.size());
|
||||
for (std::vector< cv::Ptr<cv::dnn::Layer> >::iterator it = vs.begin(); it != vs.end(); ++it) {
|
||||
jobject element = env->NewObject(jLayerClass, m_create_layer, (*it).get());
|
||||
env->CallBooleanMethod(result, m_add, element);
|
||||
env->DeleteLocalRef(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
jobject vector_Target_to_List(JNIEnv* env, std::vector<cv::dnn::Target>& vs)
|
||||
{
|
||||
static jclass juArrayList = ARRAYLIST(env);
|
||||
static jmethodID m_create = CONSTRUCTOR(env, juArrayList);
|
||||
jmethodID m_add = LIST_ADD(env, juArrayList);
|
||||
|
||||
static jclass jInteger = env->FindClass("java/lang/Integer");
|
||||
static jmethodID m_create_Integer = env->GetMethodID(jInteger, "<init>", "(I)V");
|
||||
|
||||
jobject result = env->NewObject(juArrayList, m_create, vs.size());
|
||||
for (size_t i = 0; i < vs.size(); ++i)
|
||||
{
|
||||
jobject element = env->NewObject(jInteger, m_create_Integer, vs[i]);
|
||||
env->CallBooleanMethod(result, m_add, element);
|
||||
env->DeleteLocalRef(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<cv::Ptr<cv::dnn::Layer> > List_to_vector_Ptr_Layer(JNIEnv* env, jobject list)
|
||||
{
|
||||
static jclass juArrayList = ARRAYLIST(env);
|
||||
jmethodID m_size = LIST_SIZE(env, juArrayList);
|
||||
jmethodID m_get = LIST_GET(env, juArrayList);
|
||||
|
||||
static jclass jLayerClass = LAYER(env);
|
||||
|
||||
jint len = env->CallIntMethod(list, m_size);
|
||||
std::vector< cv::Ptr<cv::dnn::Layer> > result;
|
||||
result.reserve(len);
|
||||
for (jint i=0; i<len; i++)
|
||||
{
|
||||
jobject element = static_cast<jobject>(env->CallObjectMethod(list, m_get, i));
|
||||
cv::Ptr<cv::dnn::Layer>* layer_ptr = (cv::Ptr<cv::dnn::Layer>*) GETNATIVEOBJ(env, jLayerClass, element) ;
|
||||
cv::Ptr<cv::dnn::Layer> layer = *(layer_ptr);
|
||||
result.push_back(layer);
|
||||
env->DeleteLocalRef(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html
|
||||
|
||||
// Author: abratchik
|
||||
|
||||
#ifndef DNN_CONVERTERS_HPP
|
||||
#define DNN_CONVERTERS_HPP
|
||||
|
||||
#include <jni.h>
|
||||
#include "opencv_java.hpp"
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/dnn/dnn.hpp"
|
||||
|
||||
#define LAYER(ENV) static_cast<jclass>(ENV->NewGlobalRef(ENV->FindClass("org/opencv/dnn/Layer")))
|
||||
#define LAYER_CONSTRUCTOR(ENV, CLS) ENV->GetMethodID(CLS, "<init>", "(J)V")
|
||||
|
||||
|
||||
using namespace cv::dnn;
|
||||
|
||||
void Mat_to_MatShape(cv::Mat& mat, MatShape& matshape);
|
||||
|
||||
void MatShape_to_Mat(MatShape& matshape, cv::Mat& mat);
|
||||
|
||||
void Mat_to_vector_MatShape(cv::Mat& mat, std::vector<MatShape>& v_matshape);
|
||||
void vector_MatShape_to_Mat(std::vector<MatShape>& v_matshape, cv::Mat& mat);
|
||||
|
||||
void Mat_to_vector_vector_MatShape(cv::Mat& mat, std::vector< std::vector< MatShape > >& vv_matshape);
|
||||
void vector_vector_MatShape_to_Mat(std::vector< std::vector< MatShape > >& vv_matshape, cv::Mat& mat);
|
||||
|
||||
jobject vector_Ptr_Layer_to_List(JNIEnv* env, std::vector<cv::Ptr<cv::dnn::Layer> >& vs);
|
||||
|
||||
std::vector<cv::Ptr<cv::dnn::Layer> > List_to_vector_Ptr_Layer(JNIEnv* env, jobject list);
|
||||
|
||||
jobject vector_Target_to_List(JNIEnv* env, std::vector<cv::dnn::Target>& vs);
|
||||
|
||||
#endif /* DNN_CONVERTERS_HPP */
|
||||
@@ -0,0 +1,134 @@
|
||||
package org.opencv.test.dnn;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.core.Range;
|
||||
import org.opencv.dnn.Dnn;
|
||||
import org.opencv.dnn.Image2BlobParams;
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
|
||||
public class DnnBlobFromImageWithParamsTest extends OpenCVTestCase {
|
||||
|
||||
public void testBlobFromImageWithParamsNHWCScalarScale()
|
||||
{
|
||||
Mat img = new Mat(10, 10, CvType.CV_8UC4, new Scalar(0, 1, 2, 3));
|
||||
Scalar scalefactor = new Scalar(0.1, 0.2, 0.3, 0.4);
|
||||
|
||||
Image2BlobParams params = new Image2BlobParams();
|
||||
params.set_scalefactor(scalefactor);
|
||||
params.set_datalayout(Dnn.DNN_LAYOUT_NHWC);
|
||||
|
||||
Mat blob = Dnn.blobFromImageWithParams(img, params); // [1, 10, 10, 4]
|
||||
|
||||
float[] expectedValues = { (float)scalefactor.val[0] * 0, (float)scalefactor.val[1] * 1, (float)scalefactor.val[2] * 2, (float)scalefactor.val[3] * 3 }; // Target Value.
|
||||
for (int h = 0; h < 10; h++)
|
||||
{
|
||||
for (int w = 0; w < 10; w++)
|
||||
{
|
||||
float[] actualValues = new float[4];
|
||||
blob.get(new int[]{0, h, w, 0}, actualValues);
|
||||
for (int c = 0; c < 4; c++)
|
||||
{
|
||||
// Check equal
|
||||
assertEquals(expectedValues[c], actualValues[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobFromImageWithParamsCustomPaddingLetterBox()
|
||||
{
|
||||
Mat img = new Mat(40, 20, CvType.CV_8UC4, new Scalar(0, 1, 2, 3));
|
||||
|
||||
// Custom padding value that you have added
|
||||
Scalar customPaddingValue = new Scalar(5, 6, 7, 8); // Example padding value
|
||||
Size targetSize = new Size(20, 20);
|
||||
|
||||
Mat targetImg = img.clone();
|
||||
Core.copyMakeBorder(targetImg, targetImg, 0, 0, (int)targetSize.width / 2, (int)targetSize.width / 2, Core.BORDER_CONSTANT, customPaddingValue);
|
||||
|
||||
// Set up Image2BlobParams with your new functionality
|
||||
Image2BlobParams params = new Image2BlobParams();
|
||||
params.set_size(targetSize);
|
||||
params.set_paddingmode(Dnn.DNN_PMODE_LETTERBOX);
|
||||
params.set_borderValue(customPaddingValue); // Use your new feature here
|
||||
|
||||
// Create blob with custom padding
|
||||
Mat blob = Dnn.blobFromImageWithParams(img, params);
|
||||
|
||||
// Create target blob for comparison
|
||||
Mat targetBlob = Dnn.blobFromImage(targetImg, 1.0, targetSize);
|
||||
|
||||
assertEquals(0, Core.norm(targetBlob, blob, Core.NORM_INF), EPS);
|
||||
}
|
||||
|
||||
public void testBlobFromImageWithParams4chLetterBox()
|
||||
{
|
||||
Mat img = new Mat(40, 20, CvType.CV_8UC4, new Scalar(0, 1, 2, 3));
|
||||
|
||||
// Construct target mat.
|
||||
Mat[] targetChannels = new Mat[4];
|
||||
|
||||
// The letterbox will add zero at the left and right of output blob.
|
||||
// After the letterbox, every row data would have same value showing as valVec.
|
||||
byte[] valVec = { 0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0};
|
||||
|
||||
Mat rowM = new Mat(1, 20, CvType.CV_8UC1);
|
||||
rowM.put(0, 0, valVec);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Core.multiply(rowM, new Scalar(i), targetChannels[i] = new Mat());
|
||||
}
|
||||
|
||||
Mat targetImg = new Mat();
|
||||
Core.merge(Arrays.asList(targetChannels), targetImg);
|
||||
Size targetSize = new Size(20, 20);
|
||||
|
||||
Image2BlobParams params = new Image2BlobParams();
|
||||
params.set_size(targetSize);
|
||||
params.set_paddingmode(Dnn.DNN_PMODE_LETTERBOX);
|
||||
Mat blob = Dnn.blobFromImageWithParams(img, params);
|
||||
Mat targetBlob = Dnn.blobFromImage(targetImg, 1.0, targetSize); // only convert data from uint8 to float32.
|
||||
|
||||
assertEquals(0, Core.norm(targetBlob, blob, Core.NORM_INF), EPS);
|
||||
}
|
||||
|
||||
public void testBlobFromImageWithParams4chMultiImage()
|
||||
{
|
||||
Mat img = new Mat(10, 10, CvType.CV_8UC4, new Scalar(0, 1, 2, 3));
|
||||
|
||||
Scalar scalefactor = new Scalar(0.1, 0.2, 0.3, 0.4);
|
||||
|
||||
Image2BlobParams param = new Image2BlobParams();
|
||||
param.set_scalefactor(scalefactor);
|
||||
param.set_datalayout(Dnn.DNN_LAYOUT_NHWC);
|
||||
|
||||
List<Mat> images = new ArrayList<>();
|
||||
images.add(img);
|
||||
Mat img2 = new Mat();
|
||||
Core.multiply(img, Scalar.all(2), img2);
|
||||
images.add(img2);
|
||||
|
||||
Mat blobs = Dnn.blobFromImagesWithParams(images, param);
|
||||
|
||||
Range[] ranges = new Range[4];
|
||||
ranges[0] = new Range(0, 1);
|
||||
ranges[1] = new Range(0, blobs.size(1));
|
||||
ranges[2] = new Range(0, blobs.size(2));
|
||||
ranges[3] = new Range(0, blobs.size(3));
|
||||
|
||||
Mat blob0 = blobs.submat(ranges).clone();
|
||||
|
||||
ranges[0] = new Range(1, 2);
|
||||
Mat blob1 = blobs.submat(ranges).clone();
|
||||
|
||||
Core.multiply(blob0, Scalar.all(2), blob0);
|
||||
|
||||
assertEquals(0, Core.norm(blob0, blob1, Core.NORM_INF), EPS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package org.opencv.test.dnn;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.Range;
|
||||
import org.opencv.dnn.Dnn;
|
||||
import org.opencv.dnn.Net;
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
|
||||
public class DnnForwardAndRetrieve extends OpenCVTestCase {
|
||||
|
||||
public void testForwardAndRetrieve()
|
||||
{
|
||||
// Create a simple Caffe prototxt with a Slice layer
|
||||
String prototxt =
|
||||
"input: \"data\"\n" +
|
||||
"layer {\n" +
|
||||
" name: \"testLayer\"\n" +
|
||||
" type: \"Slice\"\n" +
|
||||
" bottom: \"data\"\n" +
|
||||
" top: \"firstCopy\"\n" +
|
||||
" top: \"secondCopy\"\n" +
|
||||
" slice_param {\n" +
|
||||
" axis: 0\n" +
|
||||
" slice_point: 2\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
// Read network from prototxt
|
||||
MatOfByte bufferProto = new MatOfByte();
|
||||
bufferProto.fromArray(prototxt.getBytes());
|
||||
Net net = Dnn.readNetFromCaffe(bufferProto);
|
||||
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
|
||||
|
||||
// Create input data
|
||||
Mat inp = new Mat(4, 5, CvType.CV_32F);
|
||||
Core.randu(inp, -1, 1);
|
||||
net.setInput(inp);
|
||||
|
||||
// Define output names
|
||||
List<String> outNames = new ArrayList<>();
|
||||
outNames.add("testLayer");
|
||||
|
||||
// Forward and retrieve multiple outputs
|
||||
List<List<Mat>> outBlobs = new ArrayList<>();
|
||||
net.forwardAndRetrieve(outBlobs, outNames);
|
||||
|
||||
// Verify results
|
||||
assertEquals(1, outBlobs.size());
|
||||
assertEquals(2, outBlobs.get(0).size());
|
||||
|
||||
// Compare results
|
||||
Mat expectedFirst = inp.rowRange(0, 2);
|
||||
Mat expectedSecond = inp.rowRange(2, 4);
|
||||
|
||||
Mat actualFirst = outBlobs.get(0).get(0);
|
||||
Mat actualSecond = outBlobs.get(0).get(1);
|
||||
|
||||
assertEquals(0, Core.norm(expectedFirst, actualFirst, Core.NORM_INF), EPS);
|
||||
assertEquals(0, Core.norm(expectedSecond, actualSecond, Core.NORM_INF), EPS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package org.opencv.test.dnn;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfInt;
|
||||
import org.opencv.core.MatOfFloat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.dnn.DictValue;
|
||||
import org.opencv.dnn.Dnn;
|
||||
import org.opencv.dnn.Layer;
|
||||
import org.opencv.dnn.Net;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
|
||||
/*
|
||||
* regression test for #12324,
|
||||
* testing various java.util.List invocations,
|
||||
* which use the LIST_GET macro
|
||||
*/
|
||||
|
||||
public class DnnListRegressionTest extends OpenCVTestCase {
|
||||
|
||||
private final static String ENV_OPENCV_DNN_TEST_DATA_PATH = "OPENCV_DNN_TEST_DATA_PATH";
|
||||
|
||||
private final static String ENV_OPENCV_TEST_DATA_PATH = "OPENCV_TEST_DATA_PATH";
|
||||
|
||||
String modelFileName = "";
|
||||
String sourceImageFile = "";
|
||||
|
||||
Net net;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
String envDnnTestDataPath = System.getenv(ENV_OPENCV_DNN_TEST_DATA_PATH);
|
||||
|
||||
if(envDnnTestDataPath == null){
|
||||
isTestCaseEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
File dnnTestDataPath = new File(envDnnTestDataPath);
|
||||
modelFileName = new File(dnnTestDataPath, "dnn/tensorflow_inception_graph.pb").toString();
|
||||
|
||||
String envTestDataPath = System.getenv(ENV_OPENCV_TEST_DATA_PATH);
|
||||
|
||||
if(envTestDataPath == null) throw new Exception(ENV_OPENCV_TEST_DATA_PATH + " has to be defined!");
|
||||
|
||||
File testDataPath = new File(envTestDataPath);
|
||||
|
||||
File f = new File(testDataPath, "dnn/grace_hopper_227.png");
|
||||
sourceImageFile = f.toString();
|
||||
if(!f.exists()) throw new Exception("Test image is missing: " + sourceImageFile);
|
||||
|
||||
net = Dnn.readNetFromTensorflow(modelFileName);
|
||||
|
||||
Mat image = Imgcodecs.imread(sourceImageFile);
|
||||
assertNotNull("Loading image from file failed!", image);
|
||||
|
||||
Mat inputBlob = Dnn.blobFromImage(image, 1.0, new Size(224, 224), new Scalar(0), true, true);
|
||||
assertNotNull("Converting image to blob failed!", inputBlob);
|
||||
|
||||
net.setInput(inputBlob, "input");
|
||||
}
|
||||
|
||||
public void testSetInputsNames() {
|
||||
List<String> inputs = new ArrayList();
|
||||
inputs.add("input");
|
||||
try {
|
||||
net.setInputsNames(inputs);
|
||||
} catch(Exception e) {
|
||||
fail("Net setInputsNames failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testForward() {
|
||||
List<Mat> outs = new ArrayList();
|
||||
List<String> outNames = new ArrayList();
|
||||
outNames.add("softmax2");
|
||||
try {
|
||||
net.forward(outs,outNames);
|
||||
} catch(Exception e) {
|
||||
fail("Net forward failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetMemoryConsumption() {
|
||||
int layerId = 1;
|
||||
List<MatOfInt> netInputShapes = new ArrayList();
|
||||
netInputShapes.add(new MatOfInt(1, 3, 224, 224));
|
||||
long[] weights=null;
|
||||
long[] blobs=null;
|
||||
try {
|
||||
net.getMemoryConsumption(layerId, netInputShapes, weights, blobs);
|
||||
} catch(Exception e) {
|
||||
fail("Net getMemoryConsumption failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetFLOPS() {
|
||||
int layerId = 1;
|
||||
List<MatOfInt> netInputShapes = new ArrayList();
|
||||
netInputShapes.add(new MatOfInt(1, 3, 224, 224));
|
||||
try {
|
||||
net.getFLOPS(layerId, netInputShapes);
|
||||
} catch(Exception e) {
|
||||
fail("Net getFLOPS failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetLayersShapes() {
|
||||
List<MatOfInt> netInputShapes = new ArrayList();
|
||||
netInputShapes.add(new MatOfInt(1, 3, 224, 224));
|
||||
|
||||
MatOfInt layersIds = new MatOfInt();
|
||||
List<List<MatOfInt>> inLayersShapes = new ArrayList();
|
||||
List<List<MatOfInt>> outLayersShapes = new ArrayList();
|
||||
try {
|
||||
net.getLayersShapes(netInputShapes, layersIds, inLayersShapes, outLayersShapes);
|
||||
|
||||
assertEquals(layersIds.total(), inLayersShapes.size());
|
||||
assertEquals(layersIds.total(), outLayersShapes.size());
|
||||
|
||||
// Layer ID for "conv2d0_pre_relu/conv"
|
||||
int layerId = 1;
|
||||
|
||||
MatOfInt expectedInShape = new MatOfInt(1, 3, 224, 224);
|
||||
MatOfInt expectedOutShape = new MatOfInt(1, 64, 112, 112);
|
||||
|
||||
// Test inLayersShapes
|
||||
MatOfInt actualInShape = inLayersShapes.get(layerId).get(0);
|
||||
assertMatEqual(expectedInShape, actualInShape);
|
||||
|
||||
// Test outLayersShapes
|
||||
MatOfInt actualOutShape = outLayersShapes.get(layerId).get(0);
|
||||
assertMatEqual(expectedOutShape, actualOutShape);
|
||||
|
||||
} catch(Exception e) {
|
||||
fail("Net getLayersShapes failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package org.opencv.test.dnn;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfFloat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.Scalar;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.dnn.DictValue;
|
||||
import org.opencv.dnn.Dnn;
|
||||
import org.opencv.dnn.Layer;
|
||||
import org.opencv.dnn.Net;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
|
||||
public class DnnTensorFlowTest extends OpenCVTestCase {
|
||||
|
||||
private final static String ENV_OPENCV_DNN_TEST_DATA_PATH = "OPENCV_DNN_TEST_DATA_PATH";
|
||||
|
||||
private final static String ENV_OPENCV_TEST_DATA_PATH = "OPENCV_TEST_DATA_PATH";
|
||||
|
||||
String modelFileName = "";
|
||||
String sourceImageFile = "";
|
||||
|
||||
Net net;
|
||||
|
||||
private static void normAssert(Mat ref, Mat test) {
|
||||
final double l1 = 1e-5;
|
||||
final double lInf = 1e-4;
|
||||
double normL1 = Core.norm(ref, test, Core.NORM_L1) / ref.total();
|
||||
double normLInf = Core.norm(ref, test, Core.NORM_INF) / ref.total();
|
||||
assertTrue(normL1 < l1);
|
||||
assertTrue(normLInf < lInf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
String envDnnTestDataPath = System.getenv(ENV_OPENCV_DNN_TEST_DATA_PATH);
|
||||
|
||||
if(envDnnTestDataPath == null){
|
||||
isTestCaseEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
File dnnTestDataPath = new File(envDnnTestDataPath);
|
||||
modelFileName = new File(dnnTestDataPath, "dnn/tensorflow_inception_graph.pb").toString();
|
||||
|
||||
String envTestDataPath = System.getenv(ENV_OPENCV_TEST_DATA_PATH);
|
||||
|
||||
if(envTestDataPath == null) throw new Exception(ENV_OPENCV_TEST_DATA_PATH + " has to be defined!");
|
||||
|
||||
File testDataPath = new File(envTestDataPath);
|
||||
|
||||
File f = new File(testDataPath, "dnn/grace_hopper_227.png");
|
||||
sourceImageFile = f.toString();
|
||||
if(!f.exists()) throw new Exception("Test image is missing: " + sourceImageFile);
|
||||
|
||||
net = Dnn.readNetFromTensorflow(modelFileName);
|
||||
}
|
||||
|
||||
public void testGetLayerTypes() {
|
||||
List<String> layertypes = new ArrayList();
|
||||
net.getLayerTypes(layertypes);
|
||||
|
||||
assertFalse("No layer types returned!", layertypes.isEmpty());
|
||||
}
|
||||
|
||||
public void testGetLayer() {
|
||||
List<String> layernames = net.getLayerNames();
|
||||
|
||||
assertFalse("Test net returned no layers!", layernames.isEmpty());
|
||||
|
||||
String testLayerName = layernames.get(0);
|
||||
|
||||
DictValue layerId = new DictValue(testLayerName);
|
||||
|
||||
assertEquals("DictValue did not return the string, which was used in constructor!", testLayerName, layerId.getStringValue());
|
||||
|
||||
Layer layer = net.getLayer(layerId);
|
||||
|
||||
assertEquals("Layer name does not match the expected value!", testLayerName, layer.get_name());
|
||||
|
||||
}
|
||||
|
||||
public void checkInceptionNet(Net net)
|
||||
{
|
||||
Mat image = Imgcodecs.imread(sourceImageFile);
|
||||
assertNotNull("Loading image from file failed!", image);
|
||||
|
||||
Mat inputBlob = Dnn.blobFromImage(image, 1.0, new Size(224, 224), new Scalar(0), true, true);
|
||||
assertNotNull("Converting image to blob failed!", inputBlob);
|
||||
|
||||
net.setInput(inputBlob, "input");
|
||||
|
||||
Mat result = new Mat();
|
||||
try {
|
||||
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
|
||||
result = net.forward("softmax2");
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail("DNN forward failed: " + e.getMessage());
|
||||
}
|
||||
assertNotNull("Net returned no result!", result);
|
||||
|
||||
result = result.reshape(1, 1);
|
||||
Core.MinMaxLocResult minmax = Core.minMaxLoc(result);
|
||||
assertEquals("Wrong prediction", (int)minmax.maxLoc.x, 866);
|
||||
|
||||
Mat top5RefScores = new MatOfFloat(new float[] {
|
||||
0.63032645f, 0.2561979f, 0.032181446f, 0.015721032f, 0.014785315f
|
||||
}).reshape(1, 1);
|
||||
|
||||
Core.sort(result, result, Core.SORT_DESCENDING);
|
||||
|
||||
normAssert(result.colRange(0, 5), top5RefScores);
|
||||
}
|
||||
|
||||
public void testTestNetForward() {
|
||||
checkInceptionNet(net);
|
||||
}
|
||||
|
||||
public void testReadFromBuffer() {
|
||||
File modelFile = new File(modelFileName);
|
||||
byte[] modelBuffer = new byte[ (int)modelFile.length() ];
|
||||
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(modelFile);
|
||||
fis.read(modelBuffer);
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
fail("Failed to read a model: " + e.getMessage());
|
||||
}
|
||||
net = Dnn.readNetFromTensorflow(new MatOfByte(modelBuffer));
|
||||
checkInceptionNet(net);
|
||||
}
|
||||
|
||||
public void testGetAvailableTargets() {
|
||||
List<Integer> targets = Dnn.getAvailableTargets(Dnn.DNN_BACKEND_OPENCV);
|
||||
assertTrue(targets.contains(Dnn.DNN_TARGET_CPU));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user