我想获取使用相机捕获的打印件的图像差异。
我尝试了许多使用python库的解决方案:opencv,image-magic等。
我发现用于图像比较的解决方案是为了提高准确性:
捕获图像的条件: 1. 相机将永远不会移动(安装在固定支架上)。 2. 将对象手动放置在白板上,因此将永远无法正确对齐对象。 (每次手动操作时角度都会略有变化)
使用相机针对以下代码捕获的图像样本:
图片样本1:白色圆点:
图片样本2:作为原始图片
图像样本3:黑点
带有白点打印的接受输出不可用,但只能标记差异(缺陷):
当前,我正在使用以下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)
差异后的输出不正确,因为比较工作在逐像素的情况下进行,因此仅标记实际差异还不够聪明:
我提到的上述解决方案可以有效地获得所需的输出差异,但是没有库或image-magic命令可用于此类图像比较。
是否要执行此操作的任何python代码或Image-magic命令?
答案 0 :(得分:4)
似乎您正在执行一些缺陷检测任务。我想到的第一个解决方案是图像配准技术。 首先,请尝试在相同的条件下(光线,相机角度和...)拍摄图像(所提供的图像之一大于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)
图像差异和阈值: 倾斜= 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。
答案 1 :(得分:2)
尽管您不希望进行逐点处理,但这是使用Imagemagick进行的子图像搜索比较。它会在裁掉黑色图像后填充一张图像,然后将其移到较小的位置,找到较大的最佳匹配位置。
convert image1.jpg -gravity north -chop 0x25 image1c.png
convert image2.jpg -gravity north -chop 0x25 -gravity center -bordercolor "rgb(114,151,157)" -border 20x20 image2c.png
compare -metric rmse -subimage-search image2c.png image1c.png null:
1243.41 (0.0189732) @ 22,20
convert image2c.png image1c.png -geometry +22+20 -compose difference -composite -shave 22x20 -colorspace gray -auto-level +level-colors white,red diff.png
添加:
如果只想使用compare,则需要在compare命令中添加-fuzz 15%:
compare -metric rmse -fuzz 15% -subimage-search image2c.png image1c.png diff.png
产生两个图像。差异图片是第一个,所以请看diff-0.png