1

I want to have detailed image comparison which are captured using webcam.

I tried OpenCV and other Python libraries for image comparison which work good when I do any digital change in image that is changes done on image using PC (using Paint).

But when I do any change in image physically using pen or any other object and capture the image with a webcam, then the same library is unable to detected the change done on the image.

Factors which leads for such issue:

  1. camera (I am using Logitech c310)
  2. External noise (I am capturing image under LED tube light)
  3. While changing the design it may shift a bit, which is displayed as difference as well.

My code :

from skimage.measure import compare_ssim
import argparse
import imutils
import cv2
import numpy as np

# load the two input images
imageA = cv2.imread('./t_0.png')
cv2.imwrite("./test/org.jpg", imageA)
# imageA = cv2.medianBlur(imageA,29)
imageB = cv2.imread('./t_1.png')
cv2.imwrite("./test/test.jpg", imageB)
# imageB = cv2.medianBlur(imageB,29)

# convert the images to grayscale
grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)

##########################################################################################################

difference = cv2.subtract(grayA,grayB)    
result = not np.any(difference)
if result is True:
    print ("Pictures are the same")
else:
    cv2.imwrite("./test/open_cv_subtract.jpg", difference )
    print ("Pictures are different, the difference is stored.")

##########################################################################################################

diff = cv2.absdiff(grayA, grayB)
cv2.imwrite("./test/absdiff.png", diff)

##########################################################################################################

grayB=cv2.resize(grayB,(grayA.shape[1],grayA.shape[0]))
(score, diff) = compare_ssim(grayA, grayB, full=True)
diff = (diff * 255).astype("uint8")
print("SSIM: {}".format(score))

#########################################################################################################

thresh = cv2.threshold(diff, 25, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
#s = imutils.grab_contours(cnts)
count = 0
# loop over the contours
for c in cnts:
    # images differ
    count=count+1
    (x, y, w, h) = cv2.boundingRect(c)
    cv2.rectangle(imageA, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.rectangle(imageB, (x, y), (x + w, y + h), (0, 0, 255), 2)

##########################################################################################################

print (count)
cv2.imwrite("./test/original.jpg", imageA)
# cv2.imshow("Modified", imageB)
cv2.imwrite("./test/test_image.jpg", imageB)
cv2.imwrite("./test/compare_ssim.jpg", diff)
cv2.imwrite("./test/thresh.jpg", thresh)
cv2.waitKey(0)
  • I don’t want to use cv2.medianBlur as this will lesser the image quality.

  • there is no need to resize or crop image as all images captured using webcam will be of same size.

  • Environment will always remain same for image capture only the design will change with minor changes (such as small dots over design).

Image 1:

Original Image

Image 2:

Image to be compared

Resulted Image :

marking the difference

It was able to find 1000s of differences:

displaying the difference

absdiff image (opencv) :

absdiff image

expected output :

expected output

It is not able to detect detailed required difference.

Can any one help me with Python code or library for detail image which can detect the changes done on image physically to comparison two images mention as above.

There are many question which was matching my requirements but none of then compare the image which are captured using a webcam with the required result.

  1. How to archive a constant environment for image capture?
  2. How to have detail image comparison (small pin point dot)?
  3. which camera I need to use?
  4. What type if light I need to use to create a bright and constant environment?
  5. Is there any other way, any other programming language or library to do this?

Do help me for find the solution using Python.

Ujwala Patil
  • 180
  • 14
  • 2
    `cv2.absdiff` is the right approach, but you need to remove very small regions from the difference (one pixel being different doesn’t mean anything, you can’t measure changes that small) and you need to include a threshold (a small change in brightness is caused by noise, not a change in the object). – Cris Luengo Feb 09 '19 at 14:28
  • @CrisLuengo I have added the image for **absdiff** , the problem from my side is while changing the design it may shift bit, which is displayed as difference as well. – Ujwala Patil Feb 11 '19 at 05:08
  • 1
    Well, if the images shift, you will have to find that shift and correct for it first. Look up cross correlation, it's the simplest approach and will work well if it is just a shift (no rotation or change of perspective). To take rotation into account, the Fourier-Mellin transform is the simplest approach. With perspective changes things get a lot more complex. – Cris Luengo Feb 11 '19 at 06:38
  • Thanks @CrisLuengo I need to deal only with **detailed shifting** so that it will not show shifting as a difference after comparison. – Ujwala Patil Feb 11 '19 at 06:51
  • 1
    @UjwalaPatil to deal with shifting you need to make a template of it using `cv2.drawContours`. after making the template for both the images you can overlap this teamplate for comparison using `cv2.matchTemplate`. you can find many code avalaible for matching template. you need to search code for macking template. i hope `cv2.drawContours` will help you for macking template. – M. D. P Feb 14 '19 at 11:47
  • @CrisLuengo is there any way to check the neighbouring pixel value, for image comparison ??? to compare current pixel value with neighbouring pixel value – Ujwala Patil Feb 26 '19 at 09:25
  • 1
    Do you mean how to check the value of `image[i+1,j]` when you’re iterating through the image at location `i,j`? With plain indexing... You just need to make sure first that `i+1` is still in the image domain. – Cris Luengo Feb 26 '19 at 14:11
  • @CrisLuengo which image comparison function or algorithm will allow me to do `image[i+1,j]` this ??? OR how can I implement this using `cv2.absdiff` ??? – Ujwala Patil Mar 06 '19 at 06:43

0 Answers0