我想获取使用相机拍摄的打印品的图像差异。
我尝试了很多使用 python 库的解决方案:opencv、image-magic 等。
我找到的图像比较解决方案是为了提高准确性:
- 移动图像:从左到右并寻找最小差异。
- 移动图像:从右到左并寻找最小差异。
- 移动图像:从上到下并寻找最小差异。
- 移动图像:从下到上并寻找最小差异。
捕获图像的条件: 1. 相机永远不会移动(安装在固定支架上)。 2. 对象手动放置在白纸上,因此对象永远不会正确对齐。 (每次角度都略有变化,因为它是手动的)
使用相机为以下代码捕获的图像样本:
图像示例 1:白点:
图像样本 2:作为原始图像
图像示例 3:黑点
Accepted Output for print with white dots is not available, 但它应该只标记差异(缺陷):
目前我正在使用以下 Image-magic 命令来区分图像:
compare -highlight-color black -fuzz 5% -metric AE Image_1.png Image_2.png -compose src diff.png
代码:
import subprocess
# -fuzz 5% # ignore minor difference between two images
cmd = 'compare -highlight-color black -fuzz 5% -metric AE Input.png output.png -compose src diff.png '
subprocess.call(cmd, shell=True)
差异后的输出不正确,因为比较是逐像素进行的,仅标记真正的差异不够智能:
我提到的上述解决方案将努力获得所需的差异作为输出,但没有可用于此类图像比较的库或图像魔术命令。
执行此操作的任何 python 代码或 Image-magic 命令?
最佳答案
看来您正在执行一些缺陷检测任务。我想到的第一个解决方案是图像配准技术。 首先尝试在相同条件下(照明、相机角度和...)拍摄图像(您提供的图像之一大 2 像素)。
然后你应该注册两张图片并将一张与另一张匹配,就像这样
然后借助单应矩阵将它们包裹起来,生成对齐的图像,在本例中,结果是这样的:
然后取对齐图像与查询图像的差值并对其进行阈值处理,结果:
正如我所说,如果您尝试使用更精确的帧,配准结果会更好,并导致更准确的性能。
各部分代码:(大部分取自here)。
import cv2
import numpy as np
MAX_FEATURES = 1000
GOOD_MATCH_PERCENT = 0.5
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_FEATURES)
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.jpg", 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
if __name__ == '__main__':
# Read reference image
refFilename = "vv9gFl.jpg"
imFilename = "uP3CYl.jpg"
imReference = cv2.imread(refFilename, cv2.IMREAD_COLOR)
im = cv2.imread(imFilename, cv2.IMREAD_COLOR)
# Registered image will be resotred in imReg.
# The estimated homography will be stored in h.
imReg = alignImages(im, imReference)
# Write aligned image to disk.
outFilename = "aligned.jpg"
cv2.imwrite(outFilename, imReg)
对于图像差异和阈值处理: alined = cv2.imread("aligned.jpg", 0) alined = alined[:, :280]
b = cv2.imread("vv9gFl.jpg", 0 )
b = b[:, :280]
print (alined.shape)
print (b.shape)
diff = cv2.absdiff(alined, b)
cv2.imwrite("diff.png", diff)
threshold = 25
alined[np.where(diff > threshold)] = 255
alined[np.where(diff <= threshold)] = 0
cv2.imwrite("threshold.png", diff)
如果您有大量图像并且想要执行缺陷检测任务,我建议使用 Denoising Autoencoder 来训练深度人工神经网络。阅读更多 here .
关于python - 将重叠图像相互移动以获得准确的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56125062/