Open CV dnn module python and c++ outputs are different

I have tf model (DeepLabv3 plus with MobileNet V2 backbone). In python open CV(4.5.1) I can read model .pb and do inference which is done correct. Here is my code.

my_im = cv2.imread(‘test.jpg’)
net = cv2.dnn.readNetFromTensorflow(‘DeepLabSegm.pb’)
inputs = cv2.dnn.blobFromImage(my_im, size=(513, 513),scalefactor=1/255.0, mean=[-123.68/255, -116.779/255,-103.939/255 ], swapRB=True)
net.setInput(inputs)

outputs = net.forward()

This works fine and gives me output segmentation map.

But in C++, I have the same code and it gives wrong output Mat. In response I have very large numbers which are wrong.

Here is my C++ code.

From here after debugging, I see that in my response data I have very large numbers like 471316160… This is strange and I have no idea why in python I can run same functions but in c++ I have such output response.

Here is my .pb file. Deeplabv3 model - Google Drive

just for comparison – can you show your python code as well, please ?

@berak Here is my python code.

my_im = cv2.imread(im_path)
mean_sub = [-123.68/255, -116.779/255,-103.939/255 ]

net = cv2.dnn.readNetFromTensorflow(model_path)
inputs = cv2.dnn.blobFromImage(my_im, size=(513,513),scalefactor=1/255, mean=mean_sub, swapRB=True)
net.setInput(inputs)
outputs = net.forward()

plt.imshow(np.argmax(outputs[0], axis=0))
plt.show()

I have checked that input blobs are the same for python and C++. So I think the problem is either in forward function or in parsing the response in C++.

1 Like

aaand your c++ code AS TEXT, not as a silly image, so ppl can actually try it ?

(please NEVER post screenshots of code or errors anywhere, please…)

@berak Ok, Sorry. Here is my C++ code also

cv::Mat faceImg= cv::imread(facePath);
cv::dnn::Net net = cv::dnn::readNetFromTensorflow(MODEL_PATH);
cv::Mat blob;
cv::Scalar scMean(-123.68/255, -116.779/255, -103.939/255);
cv::dnn::blobFromImage(faceImg, blob, 1.0/255.0, cv::Size(IMAGE_SIZE, IMAGE_SIZE), scMean, true);
net.setInput(blob);
cv::Mat response = net.forward();

const int rows = response.size[2]; //image height
const int cols = response.size[3]; //The width of the image
const int chns = response.size[1]; //Number of image channels
cv::Mat maxCl(rows, cols, CV_8UC1);
cv::Mat maxVal(rows, cols, CV_32FC1);

for (int c = 0; c < chns; c++)
{
	for (int row = 0; row < rows; row++)
	{
		const float* ptrScore = response.ptr<float>(0, c, row);
		uchar* ptrMaxCl = maxCl.ptr<uchar>(row);
		float* ptrMaxVal = maxVal.ptr<float>(row);
		for (int col = 0; col < cols; col++)
		{
			if (ptrScore[col] > ptrMaxVal[col])
			{
				ptrMaxVal[col] = ptrScore[col];
				ptrMaxCl[col] = (uchar)c;
			}
		}
	}
}
1 Like

should have initialized memory, since you compare it:

cv::Mat maxVal(rows, cols, CV_32FC1, 0.0f);

apart from that, sorry, i cannot reproduce the problem from c++, the values in the response look all reasonable.

if you really only have 2 classes / channels as output, you might simplify it to:

Mat ch1(IMAGE_SIZE, IMAGE_SIZE, CV_32F, response.ptr<float>(0,0)); // bg
Mat ch2(IMAGE_SIZE, IMAGE_SIZE, CV_32F, response.ptr<float>(0,1)); // fg

Mat res;
cv::compare(ch1, ch2, res, cv::CMP_LT);|

@berak
Thanks for response, I have changed the code like yours, but for test image I only get background pixel predictions. If you test an image do you get reasonable result for background segmentation?

When I run this code after getting response,

for (int row = 0; row < 512; row++) {
const float* ptrScore = response.ptr(0, 0, row);
std::cout << ptrScore << std::endl;
}
I am getting numbers

00000171AF35B080
00000171AF35B884
00000171AF35C088
00000171AF35C88C
00000171AF35D090

What version of openCV do you use? May be the problem is in the version

will print out the address, not the value, which would be:

std::cout << *ptrScore << std::endl; // "de-ref" the pointer !

using this input:
person

i get:

latest master (4.5.2-dev)

Ah, sorry…

with *ptrScore I am getting values something like this 4.71316e+08… for channel 1,
and -4.03595e+08 for channel 2… But in python I am getting values something like 2.5 or -1.7

Mine is 4.5.1. can update of version help?

i’m getting the same 2.5 or -1.7 values in c++

unlikely. problem is somewhere in your code

Strange… Can you send me your full code of c++ please?

Thanks, I am using full copy of your code and the output is the same :). Are you trying this on Intel processor?