Is there implicit limit for DNN input size of OpenCV Android?
I trained a Caffe model which does NOT specify input sizes. Then I ran it on Android using OpenCV. The code is like below.
private void runEntireImageTest(Mat inY) {
float scaleFactor = 1.0f / 255.0f;
Scalar mean = new Scalar(0);
Mat resized = new Mat();
// (550, 441) runs OK. (smaller sized runs also fine)
// (551, 441), (550, 442) crash.
// (441, 550) crashes
Imgproc.resize(inY, resized, new Size(550, 441));
Mat segBlob = Dnn.blobFromImage(resized, scaleFactor, resized.size(), mean, false, false);
mNet.setInput(segBlob);
// if input size is above some value, crash will happen here
Mat lastLayer = mNet.forward();
Mat outY = lastLayer.reshape(1, 1);
}
As it is written in the comment, there seems to be some intrinsic, or implicit limitation for the input size. (550, 441)
ran okay, but (551, 441)
will cause SIGSEGV
:
A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x6d494bd744 in tid 19693 (myappname), pid 19661 (myappname)
I think it's not a memory problem because (550, 441)
runs fine but (441, 550)
will crash. What is the cause of this problem?
ADDED
Below is the prototxt file. It is a variant of FSRCNN paper (link to the paper). Although the input shape is written as { dim: 1 dim: 1 dim:678 dim:1014}
, it does not have any effect.
name: "FSRCNN"
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 1 dim: 1 dim:678 dim:1014} }
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 0.1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 32
kernel_size: 5
stride: 1
pad: 0
weight_filler {
type: "gaussian"
std: 0.05
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "relu1"
type: "PReLU"
bottom: "conv1"
top: "conv1"
prelu_param {
channel_shared: false
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "conv1"
top: "conv2"
param {
lr_mult: 0.1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 5
kernel_size: 1
stride: 1
group: 1
pad: 0
weight_filler {
type: "gaussian"
std: 0.6325
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "relu2"
type: "PReLU"
bottom: "conv2"
top: "conv2"
prelu_param {
channel_shared: false
}
}
layer {
name: "conv22"
type: "Convolution"
bottom: "conv2"
top: "conv22"
param {
lr_mult: 0.1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 5
kernel_size: 3
stride: 1
group: 1
pad: 1
weight_filler {
type: "gaussian"
std: 0.2108
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "relu22"
type: "PReLU"
bottom: "conv22"
top: "conv22"
prelu_param {
channel_shared: false
}
}
layer {
name: "conv23"
type: "Convolution"
bottom: "conv22"
top: "conv23"
param {
lr_mult: 0.1
}
param {
lr_mult: 0.1
}
convolution_param {
num_output: 32
kernel_size: 1
stride: 1
group: 1
pad: 0
weight_filler {
type: "gaussian"
std: 0.25
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "relu23"
type: "PReLU"
bottom: "conv23"
top: "conv23"
prelu_param {
channel_shared: false
}
}
layer {
name: "conv3"
type: "Deconvolution"
bottom: "conv23"
top: "conv3"
param {
lr_mult: 0.1
}
convolution_param {
num_output: 1
kernel_size: 9
stride: 3
pad: 3
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}
opencv version ? what kind of network are you using ?
@berak It's OpenCV 3.4.2 for Android. The network is a caffe network without specific input size.
is it a classification network ? a detection one ? which architecture is it using ?
simply mentioning caffe is not enough information, here.
please add the prototxt to your question, so we can take a look.
@berak I added the prototxt content to the post.
you should probably test your network on a machine, where you can debug it properly. (not on android)
and a (bold) guess: from the paper you linked, this is a super-resolution network, so it might be nessecary, to keep the aspect ratio of the original image halfway intact
@berak Testing on a PC rather than Android seems a good idea. Thanks!