Opencv detect changes between two photos taken by different time

Prometheus picture Prometheus · Jun 27, 2017 · Viewed 8.1k times · Source

We have one original image / photo of the item. (ie sculpture).

Time to time we are taking new photos of the item. Photo always taken same angle 90 degree to the item. but

  • there will be some slightly movement up down / left right there will be different length of the same object ( we are taking with line camera and the object moving in front of it so time to time speed of the object changing so the final image will be longer than the original)

Also lighting changes so colour and lightning also not same always. Time to time there will be a mud, different small objects on the item.

I would love to your suggestions and solutions to detect and mark the different part of the object on the new picture with opencv.

We tried resemblejs but it shows all parts changed due to colour, length etc differences. But object is same

Thx

code :

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


ap = argparse.ArgumentParser()
ap.add_argument("-f", "--first", required=True,
    help="first input image")
ap.add_argument("-s", "--second", required=True,
    help="second")
args = vars(ap.parse_args())

imageA = cv2.imread(args["first"])
imageB = cv2.imread(args["second"])

grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)


(score, diff) = compare_ssim(grayA, grayB, full=True)
diff = (diff * 55).astype("uint8")
print("SSIM: {}".format(score))

thresh = cv2.threshold(diff, 0, 255,
    cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]

for c in cnts:
    (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)

cv2.imshow("Diff", diff)
cv2.waitKey(0)

Edit 1

Link to test images

Answer

eshirima picture eshirima · Jun 27, 2017

A couple methods come to mind.

  1. Calculate the difference between frames. OpenCV offers absdiff for doing just that. From there findContours of the resulting difference matrix then draw them.

  2. This tutorial uses scikit-image for image differences

  3. You could also look into meanStdDev to accomplish this. Calculate the standard deviation of two frames and check to see if it passes a certain threshold.