Imagine that two kids drew some objects (look like dots) in two white papers, which are similar in size and dimension.
I want to detect these objects, and count objects which are in a same x and y-axis, How can we count the similar objects? And measure the agreement between them?
I found some similarity methods, but for these small objects did not work.
You can see image examples here. A machine learning methods can be used here? Or a simple method of OpenCV
?
These two images are input (resized images of original images).
And these are my code, I tried this code from another similar post.
The point is that the SSIM
is not accurate in my case.
from skimage.metrics import structural_similarity
import numpy as np
import cv2
image1=cv2.imread("E:/image1.png")
image2=cv2.imread("E:/image2.png")
image1gray=cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
image2gray=cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
# Compute SSIM between the two images
(score, diff) = structural_similarity(image1gray, image2gray, full=True)
print("Image Similarity: {:.4f}%".format(score * 100))
# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1]
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = (diff * 255).astype("uint8")
diff_box = cv2.merge([diff, diff, diff])
# Threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
mask = np.zeros(image1.shape, dtype='uint8')
filled_image2 = image2.copy()
filled_image1=image1.copy()
for c in contours:
area = cv2.contourArea(c)
if area > 40:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image1, (x, y), (x + w, y + h), (36,255,12), 2)
cv2.rectangle(image2, (x, y), (x + w, y + h), (36,255,12), 2)
cv2.rectangle(diff_box, (x, y), (x + w, y + h), (36,255,12), 2)
cv2.drawContours(mask, [c], 0, (255,255,255), -1)
cv2.drawContours(filled_image2, [c], 0, (0,255,0), -1)
cv2.drawContours(filled_image1, [c], 0, (0,255,0), -1)
cv2.imwrite('E:/Outout/image11.png', image1)
cv2.imwrite('E:/Outout/image22.png', image2)
cv2.imwrite('E:/Outout/diff_img.png', diff)
cv2.imwrite('E:/Outout/diff_box.png', diff_box)
cv2.imwrite('E:/Outout/mask.png', mask)
cv2.imwrite('E:/Outout/filled image2.png', filled_image2)
You can see the output that are not accurate as well.
What I want is a contour for each spot in the image, but by using this method I can get some patterns of dots in a contour.