I am currently planning on training a binary image classification model. The images I want to train on are the difference between two original pictures. In other words, for each data entry, I start out with 2 pictures, take their difference, and the label that difference as a 0 or 1. My question is what is the best way to find this difference. I know about cv2.absdiff and then normal subtraction of images - what is the most effective way to go about this?
About the data: The images I'm training on are screenshots that usually are the same but may have small differences. I found that normal subtraction seems to show the differences less than absdiff.
This is the code I use for absdiff:
diff = cv2.absdiff(img1, img2) mask = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY) th = 1 imask = mask>1 canvas = np.zeros_like(img2, np.uint8) canvas[imask] = img2[imask] And then this for normal subtraction:
def extract_diff(self,imageA, imageB, image_name, path): subtract = imageB.astype(np.float32) - imageA.astype(np.float32) mask = cv2.inRange(np.abs(subtract),(30,30,30),(255,255,255)) th = 1 imask = mask>1 canvas = np.zeros_like(imageA, np.uint8) canvas[imask] = imageA[imask] Thanks!
21 Answer
A difference can be negative or positive.
For some number types, such as uint8 (unsigned 8-bit int), which can't be negative (have no sign), a negative value wraps around and the value would make no sense anymore. Other types can be signed (e.g. floats, signed ints), so a negative value can be represented correctly.
That's why cv.absdiff exists. It always gives you absolute differences, and those are okay to represent in an unsigned type.
Example with numbers: a = 4, b = 6. a-b should be -2, right?
That value, as an uint8, will wrap around to become 0xFE, or 254 in decimal. The 254 value has some relation to the true -2 difference, but it also incorporates the range of values of the data type (8 bits: 256 values), so it's really just "code".
cv.absdiff would give you the absolute of the difference (-2), which is 2.