有什么方法可以提高指向两个图像之间的差异的准确性吗?

时间:2019-08-21 10:18:24

标签: python opencv tensorflow scipy computer-vision

我正在尝试建立验证系统,以指出两个扫描的传单之间的区别。

我模糊了这两个图像,找到了单应性以对齐两个图像,然后发现了两个图像之间的差异以绘制矩形。

标准传单:https://ibb.co/GWjKW1x

检查样本:https://ibb.co/pv3Crxm

import cv2
import numpy as np
from skimage.measure import compare_ssim as ssim
from scipy import ndimage

#MAX_MATCHES = 1000000  #MSE for labels
MAX_MATCHES = 50000 #MSE for text
GOOD_MATCH_PERCENT = 0.4

def mse(imageA, imageB):
    # the 'Mean Squared Error' between the two images is the
    # sum of the squared difference between the two images;
    # NOTE: the two images must have the same dimension
    err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2)
    err /= float(imageA.shape[0] * imageA.shape[1])

    return err

    # return the MSE, the lower the error, the more "similar"
    # the two images are

def diff_remove_bg(img0, img, img1):
    d1 = diff(img0, img)
    d2 = diff(img, img1)
    return cv2.bitwise_and(d1, d2)

def alignImages(im1, im2):

  # Convert images to grayscale
  im1Gray = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)
  im2Gray = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)


  # Detect ORB features and compute descriptors.
  orb = cv2.ORB_create(MAX_MATCHES)

  keypoints1, descriptors1 = orb.detectAndCompute(im1Gray, None)
  keypoints2, descriptors2 = orb.detectAndCompute(im2Gray, None)

  # Match features.
  matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)  
  matches = matcher.match(descriptors1, descriptors2, None)

  # Sort matches by score
  matches.sort(key=lambda x: x.distance, reverse=False)

  # Remove not so good matches
  numGoodMatches = int(len(matches) * GOOD_MATCH_PERCENT)
  matches = matches[:numGoodMatches]

  # Draw top matches
  imMatches = cv2.drawMatches(im1, keypoints1, im2, keypoints2, matches, None)
  cv2.imwrite("matches.png", imMatches)

  # Extract location of good matches
  points1 = np.zeros((len(matches), 2), dtype=np.float32)
  points2 = np.zeros((len(matches), 2), dtype=np.float32)

  for i, match in enumerate(matches):
    points1[i, :] = keypoints1[match.queryIdx].pt
    points2[i, :] = keypoints2[match.trainIdx].pt

  # Find homography
  h, mask = cv2.findHomography(points1, points2, cv2.RANSAC)

  # Use homography
  height, width, channels = im2.shape
  im1Reg = cv2.warpPerspective(im1, h, (width, height))

  return im1Reg, h



# Read reference image
refFilename = "standard.png"
print("Reading reference image : ", refFilename)

imReference = cv2.imread(refFilename, cv2.IMREAD_COLOR)  
imReference = ndimage.gaussian_filter(imReference, 2)


imFilename = "sample-fin.png"
print("Reading image to align : ", imFilename);  

im = cv2.imread(imFilename, cv2.IMREAD_COLOR)
im = ndimage.gaussian_filter(im, 2)

print("Aligning images ...")

# Registered image will be resotred in imReg. 
# The estimated homography will be stored in h. 
imReg, h = alignImages(im, imReference)

# Write aligned image to disk. 
outFilename = "aligned.png"
print("Saving aligned image : ", outFilename); 
cv2.imwrite(outFilename, imReg)

# Print estimated homography
print("Estimated homography : \n",  h)

x1 = imReg
x2 = imReference

absdiff = cv2.absdiff(x1, x2)

print(np.max(absdiff))

#Threshold for minimum detection
threshold = absdiff < 30
absdiff[threshold] = 0      

cv2.imwrite("absdiff.png", absdiff)

diff = cv2.subtract(x1, x2)
result = not np.any(diff)


########### Drawing Rectangles around the differences ##############

img = cv2.pyrDown(cv2.imread('absdiff.png', cv2.IMREAD_UNCHANGED))
img1 =  cv2.pyrDown(cv2.imread('aligned.png', cv2.IMREAD_UNCHANGED))


ret, threshed_img = cv2.threshold(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
                40, 40, cv2.THRESH_BINARY)

_,contours, hier = cv2.findContours(threshed_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)


for c in contours:
    x,y,w,h = cv2.boundingRect(c)

    cv2.rectangle(img1, (x-5, y-5), (x+w+10, y+h+10), (0, 255, 0), 2)

    # get the min area rect
    rect = cv2.minAreaRect(c)
    box = cv2.boxPoints(rect)

    # convert all coordinates floating point values to int
    box = np.int0(box)

print(len(contours))

cv2.imwrite("cont-1.png", img1)

差异图片:https://ibb.co/NCj32qs

指出的错误:https://ibb.co/YWKxYLF

我想提高此算法的准确性。还是有其他方法可以用来解决这一任务?

编辑: 我想删除传单末尾出现的多余矩形。单应性也不是完美的。我必须在差异上设置一个巨大的门槛才能获得此结果。

0 个答案:

没有答案