ssr ssr - 2 months ago 10x
C++ Question

OpenCV Image substraction signed output

I wouls like to subtract two gray scale images (CV_8UC1) and get their signed difference as result(CV_16SC1) .

I have tried the code below but i get as difference a CV_8UC1 matrix insted of a signed CV_16SC1.

Could you please help properly defining the Mask matrix and data type parameter?


#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include "Imagesubstraction.h"

using namespace cv;
using namespace std;

int main(void)

Mat M1, M2,Dif;

M1 = imread("../data/difference/a.bmp", CV_LOAD_IMAGE_GRAYSCALE);
M2 = imread("../data/difference/b.bmp", CV_LOAD_IMAGE_GRAYSCALE);

Mat Mask(1024, 1024, CV_8UC1, Scalar(1));

subtract(M1, M2, Dif,Mask,3);

imwrite("../data/difference/c.bmp", Dif);

return 0;


Of course you're going to get an unsigned matrix after saving it to BMP format. As stated in OpenCV documentation:

Only 8-bit (or 16-bit unsigned (CV_16U) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with ‘BGR’ channel order) images can be saved using this function.

But if you take a look at your Dif matrix before saving it, you will see it is a 16-bit signed matrix.

At least, the following code snippet works as expected:

cv::Mat m1(100, 100, CV_8U, cv::Scalar(50));
cv::Mat m2(100, 100, CV_8U, cv::Scalar(30));

cv::Mat dif;

cv::Mat mask(100, 100, CV_8U, cv::Scalar(255));

cv::subtract(m2, m1, dif, mask, CV_16S);

std::cout << dif << std::endl;