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)

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)
outputs = net.forward()

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

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);
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);|

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


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:

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?