odd image sizes are not allowed with enet, try like Size(512,256)
instead (also needs to be a multiple of 4)
since you cannot access a 4d tensor from java directly, you'll have to reshape()
the network output to a 2d strip of probability maps per class, like:
---
|A|
---
|B|
---
|C|
---
now you have to find the highest probability for each pixel, and knowing which class it came from, assign a pixel color to your segmentation image:
import org.opencv.core.*;
import org.opencv.dnn.*;
import org.opencv.imgcodecs.*;
import org.opencv.imgproc.*;
public class SimpleSample {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Scalar[] colors = new Scalar[]{ // obvious TODO: find better colours ;)
new Scalar(1,22,123), new Scalar(28,53,4), new Scalar(81,2,243),
new Scalar(2,223,244), new Scalar(12,2,3), new Scalar(2,3,4),
new Scalar(161,162,3), new Scalar(124,13,144), new Scalar(112,2,223),
new Scalar(2,3,4), new Scalar(81,82,3), new Scalar(222,223,24),
new Scalar(12,222,32), new Scalar(82,3,4), new Scalar(221,12,3),
new Scalar(182,83,84), new Scalar(221,12,3), new Scalar(52,3,4),
new Scalar(91,162,23), new Scalar(211,3,49)
};
Mat img = Imgcodecs.imread("c:/data/img/warp.png"); // your data here !
Net net = Dnn.readNetFromTorch("c:/data/mdl/enet-model-best.net");
Mat inputBlob = Dnn.blobFromImage(img,
1.0/255, new Size(512,256), new Scalar(0, 0, 0), true, false);
net.setInput(inputBlob);
Mat res = net.forward();
// the net's output is a list of "probability maps", one per class
// (size(1) is, how many classes there are, 2 and 3 are H,W)
System.out.println(res.size(0)+" "+res.size(1)+" "+res.size(2)+" "+res.size(3));
// make a long, vertical "image strip" of it
// (since we can't access 4d tensors from java)
Mat strip = res.reshape(1, res.size(1) * res.size(2));
// will keep "highest probability" per pixel
Mat probs = new Mat(res.size(2), res.size(3), res.type(), Scalar.all(0));
// color overlay
Mat segm = new Mat(probs.size(), CvType.CV_8UC3);
// check each map, keep the pixel with highest probability
// and (re)assign a color to it
for (int i=0; i<res.size(1); i++) {
// probs for class i
Mat sub = strip.submat(i*res.size(2), (i+1)*res.size(2), 0, res.size(3));
// find out, which pixels int the current map had a higher probability,
// than all of the prev. ones
Mat gt = new Mat(); // 'greater than all' mask
Core.compare(sub, probs, gt, Core.CMP_GT);
// update probs and segmentation
segm.setTo(colors[i], gt);
sub.copyTo(probs, gt);
}
Mat result = new Mat();
Imgproc.resize(segm, segm, img.size());
Core.addWeighted(img, 0.8, segm, 0.2, 0, result); // alpa + beta == 1
Imgcodecs.imwrite("segm.png", result);
}
}
imho, you NEED the cvtColor call.
which network model are you using ? are IN_WIDTH, IN_HEIGHT correct for that ?
I am using the Caffe Model Enet https://modeldepot.io/timosaemann/enet
Yup Height & Width are perfect for them
I uncommented the cvtColor & now i am getting this
what about the prototxt ? don't you think, you need it ?
also, check the dims, again , please
there's also https://github.com/opencv/opencv_extr...
(guaranteed to work, at least)
Yup i had prototxt file for the same still getting the issue.
I am trying the other way around here switch to enet-model.net model checking it now.
https://github.com/opencv/opencv/blob...
@Mishal077, please check
blob.size(0)
,blob.size(1)
,blob.size(2)
andblob.size(3)
.@dkurt Android the size function is not there.
Hey i just want to know which framework this .net model belongs to is it the Torch7 or obtained by ONNX.I am not clear about its framework.
it's from torch