Ask Your Question
1

Preventing information loss on image subtraction

asked 2014-11-14 10:04:37 -0600

leinaD_natipaC gravatar image

I have two images that I am subtracting from one another quite simply:

Mat foo, a, b;
...//imread onto a and b or somesuch
foo = a - b;

Now, as I understand it, any pixel value that goes into the negatives will end up being zero. If that is so, I'd like to know if there is any way to permit it to go under zero so that I may adjust the image later without loss of information.

edit retag flag offensive close merge delete

Comments

Hi you can use absdiff(InputArray src1, InputArray src2, OutputArray dst)

wuling gravatar imagewuling ( 2014-11-14 21:18:36 -0600 )edit

the problem is i won't be able to tell apart -9 from 9 right?

leinaD_natipaC gravatar imageleinaD_natipaC ( 2014-11-18 07:45:50 -0600 )edit

But that function does something completely different...

FooBar gravatar imageFooBar ( 2014-11-18 10:10:11 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
2

answered 2014-11-14 17:23:59 -0600

"Now, as I understand it, any pixel value that goes into the negatives will end up being zero."

Why don't you just try? The behaviour depends on your matrix type. If you have an unsigned Matrix (e.g. CV_8UC1) then the value will be truncated. If you use a signed Matrix (CV_8SC1) negative values can be used without any problem.

edit flag offensive delete link more

Comments

That doesn't actually resolve my problem. I guess you are suggesting that I convert my matrix to signed? How do I change from 8UC1 to 16SC!(for example) and back again? Or can I use imwrite() without converting the mat back to CV_8UC1?

leinaD_natipaC gravatar imageleinaD_natipaC ( 2014-11-18 07:48:43 -0600 )edit
1

In the same vein, you might want to use a type with a bigger range (maybe an int or an other signed format) in order to have at least a range of 254.. -255 instead of being limited to 127..-128. So if at one pixel you do (254-1 = 253) and at another pixel you do (0 - 219 = -219), you would be able to represent both of them in your signed Mat. Just remark, might not be relevant

Doombot gravatar imageDoombot ( 2014-11-18 10:10:35 -0600 )edit
0

answered 2014-11-18 09:59:00 -0600

leinaD_natipaC gravatar image

Warning: this answer is a blatant copy of an answer from stackoverflow

This is how a simple convert => substract => convertAndScaleBack application would look like:

input:

enter image description here

and

enter image description here

int main() { cv::Mat input = cv::imread("../inputData/Lenna.png", CV_LOAD_IMAGE_GRAYSCALE); cv::Mat input2 = cv::imread("../inputData/Lenna_edges.png", CV_LOAD_IMAGE_GRAYSCALE);

    cv::Mat input1_16S;
    cv::Mat input2_16S;

    input.convertTo(input1_16S, CV_16SC1);
    input2.convertTo(input2_16S, CV_16SC1);

    // compute difference of 16 bit signed images
    cv::Mat diffImage = input1_16S-input2_16S;

    // now you have a 16S image that has some negative values

    // find minimum and maximum values:
    double min, max;
    cv::minMaxLoc(diffImage, &min, &max);
    std::cout << "min pixel value: " << min<< std::endl;

    cv::Mat backConverted;

    // scale the pixel values so that the smalles value is 0 and the largest one is 255
    diffImage.convertTo(backConverted,CV_8UC1, 255.0/(max-min), -min);

    cv::imshow("backConverted", backConverted);        
    cv::waitKey(0);
}

output:

enter image description here

edit flag offensive delete link more

Question Tools

Stats

Asked: 2014-11-14 10:04:37 -0600

Seen: 2,293 times

Last updated: Nov 18 '14