我有一个图像比较脚本。
如何在每次循环时打印图像名称?
另外,我可以打印两个图像测量值吗?
最重要的部分:如何将所有打印的东西导出到excel中,并且在第一列中我需要显示图像名称?
谢谢
import os
import cv2
import numpy as np
# load all image names into a list
ls_imgs1_names = os.listdir("Images1")
ls_imgs2_names = os.listdir("Images2")
# construct image paths and save in list
ls_imgs1_path = [os.path.join("Images1", img) for img in ls_imgs1_names]
ls_imgs2_path = [os.path.join("Images2", img) for img in ls_imgs2_names]
# list comprehensin to load imgs in lists
ls_imgs1 = [cv2.imread(img) for img in ls_imgs1_path]
ls_imgs2 = [cv2.imread(img) for img in ls_imgs2_path]
for original in ls_imgs1:
for image_to_compare in ls_imgs2:
# compare orignal to image_to_compare
# here just insert your code where you compare two images
# 1) Check if 2 images are equals
if original.shape == image_to_compare.shape:
print("The images have the same size and channels")
difference = cv2.subtract(original, image_to_compare)
b, g, r = cv2.split(difference)
cv2.imshow("difference", difference)
print(cv2.countNonZero(b))
if cv2.countNonZero(b) == 0 and cv2.countNonZero(g) == 0 and cv2.countNonZero(r) ==0:
print("Similarity: 100% (equal size and channels)")
# 2) Check for similarities between the 2 images
sift = cv2.xfeatures2d.SIFT_create()
kp_1, desc_1 = sift.detectAndCompute(original, None)
kp_2, desc_2 = sift.detectAndCompute(image_to_compare, None)
index_params = dict(algorithm=0, trees=5)
search_params = dict()
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(desc_1, desc_2, k=2)
good_points = []
ratio = 0.9 # mai putin de 1
for m, n in matches:
if m.distance < ratio*n.distance:
good_points.append(m)
# Define how similar they are
number_keypoints = 0
if len(kp_1) <= len(kp_2):
number_keypoints = len(kp_1)
else:
number_keypoints = len(kp_2)
print("Keypoints 1ST Image: " + str(len(kp_1)))
print("Keypoints 2ND Image: " + str(len(kp_2)))
print("How good it's the match: ", len(good_points) / number_keypoints * 100, "%")
#print(original.name)
#print("Title:" +title)
percentage_similarity = len(good_points) / number_keypoints * 100
print("Similarity: " + str(int(percentage_similarity)) + "%\n")
以下方法有效,但它将所有图像与所有图像进行比较(文件夹中的 4 个图像和文件夹中的 4 个图像,它导出 16 行)。我只需要 4 行,每次比较一个,我的意思是文件夹 Images1 中的 image1 与文件夹 Images2 中的 Image1,等等。 也只需要没有路径的名称 例如:Images1\Image1 => Image1
如果我使用这个版本,我可以比较不同的图像,我怎样才能使最终代码以相同的方式工作?
import os
import cv2
import numpy as np
# load all image names into a list
ls_imgs1_names = os.listdir("Images1")
ls_imgs2_names = os.listdir("Images2")
# construct image paths and save in list
ls_imgs1_path = [os.path.join("Images1", img) for img in ls_imgs1_names]
ls_imgs2_path = [os.path.join("Images2", img) for img in ls_imgs2_names]
# list comprehensin to load imgs in lists
ls_imgs1 = [cv2.imread(img) for img in ls_imgs1_path]
ls_imgs2 = [cv2.imread(img) for img in ls_imgs2_path]
for original in ls_imgs1:
for image_to_compare in ls_imgs2:
# compare orignal to image_to_compare
# here just insert your code where you compare two images
# 1) Check if 2 images are equals
if original.shape == image_to_compare.shape:
print("The images have the same size and channels")
difference = cv2.subtract(original, image_to_compare)
b, g, r = cv2.split(difference)
cv2.imshow("difference", difference)
print(cv2.countNonZero(b))
if cv2.countNonZero(b) == 0 and cv2.countNonZero(g) == 0 and cv2.countNonZero(r) ==0:
print("Similarity: 100% (equal size and channels)")
# 2) Check for similarities between the 2 images
sift = cv2.xfeatures2d.SIFT_create()
kp_1, desc_1 = sift.detectAndCompute(original, None)
kp_2, desc_2 = sift.detectAndCompute(image_to_compare, None)
index_params = dict(algorithm=0, trees=5)
search_params = dict()
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(desc_1, desc_2, k=2)
good_points = []
ratio = 0.9 # mai putin de 1
for m, n in matches:
if m.distance < ratio*n.distance:
good_points.append(m)
# Define how similar they are
number_keypoints = 0
if len(kp_1) <= len(kp_2):
number_keypoints = len(kp_1)
else:
number_keypoints = len(kp_2)
print("Keypoints 1ST Image: " + str(len(kp_1)))
print("Keypoints 2ND Image: " + str(len(kp_2)))
print("How good it's the match: ", len(good_points) / number_keypoints * 100, "%")
#print(original.name)
#print("Title:" +title)
percentage_similarity = len(good_points) / number_keypoints * 100
print("Similarity: " + str(int(percentage_similarity)) + "%\n")
答案 0 :(得分:5)
首先,我想提一下您的代码中可能存在的错误。
如果 original
和 image_to_compare
变量形状不相等,则会发生错误。由于 difference
和 b
变量都没有定义。因此,如果您重新格式化代码:
if original.shape == image_to_compare.shape:
print("The images have the same size and channels")
difference = cv2.subtract(original, image_to_compare)
b, g, r = cv2.split(difference)
cv2.imshow("difference", difference)
print(cv2.countNonZero(b))
if cv2.countNonZero(b) == 0 and cv2.countNonZero(g) == 0 and cv2.countNonZero(r) ==0:
print("Similarity: 100% (equal size and channels)")
如何在每次循环时打印图像名称?
您需要从 ls_imgs1_path
和 ls_imgs2_path
变量中获取数据。您可以使用计数器打印当前图像。例如:
for i1, original in enumerate(ls_imgs1):
for i2, image_to_compare in enumerate(ls_imgs2):
print(ls_imgs1_path[i1])
print(ls_imgs2_path[i2])
如果您在 Mac 上工作,一个可能的问题是 .DS_Store
if (".DS_Store" not in ls_imgs1_path[i1]) and (".DS_Store" not in ls_imgs2_path[i2]):
print(ls_imgs1_path[i1])
print(ls_imgs2_path[i2])
另外,我可以打印两个图像测量值吗?
你是说印刷尺寸吗?如果是这样:
for i1, original in enumerate(ls_imgs1):
for i2, image_to_compare in enumerate(ls_imgs2):
if (".DS_Store" not in ls_imgs1_path[i1]) and (".DS_Store" not in ls_imgs2_path[i2]):
print("Name: {}, dimensions: {}".format(ls_imgs1_path[i1], ls_imgs1[i1].shape))
print("Name: {}, dimensions: {}".format(ls_imgs2_path[i2], ls_imgs2[i2].shape))
示例结果:
Name: Images1/baboon.png, dimensions: (512, 512, 3)
Name: Images2/1.png, dimensions: (427, 640, 3)
最重要的部分:如何将所有打印的东西导出到excel中,并且在第一列中我需要显示图像名称?
您有多种选择,xlswriter
、pandas
等
例如:xlswriter
(source)
初始化编写器变量:
workbook = xlsxwriter.Workbook('/Users/ahx/Desktop/images.xlsx')
worksheet = workbook.add_worksheet()
row = 0
col = 0
假设你想写 image-name 和 image-shape
初始化列表变量
result = []
在循环中附加值
for i1, original in enumerate(ls_imgs1):
for i2, image_to_compare in enumerate(ls_imgs2):
if (".DS_Store" not in ls_imgs1_path[i1]) and (".DS_Store" not in ls_imgs2_path[i2]):
print("Name: {}, dimensions: {}".format(ls_imgs1_path[i1], ls_imgs1[i1].shape))
print("Name: {}, dimensions: {}".format(ls_imgs2_path[i2], ls_imgs2[i2].shape))
result.append([ls_imgs1_path[i1], ls_imgs1[i1].shape])
result.append([ls_imgs2_path[i2], ls_imgs2[i2].shape])
将值写入excel
for name, shape in result:
worksheet.write(row, col, name)
worksheet.write(row, col + 1, str(shape))
row += 1
workbook.close()
更新请求1
我只想要名字,没有扩展名
创建扩展变量:extension = ".jpg"
然后在循环内部,用空字符串替换扩展名
img_name1 = ls_imgs1_path[i1].replace(extension, "")
但是如果您有多个不同的扩展程序会怎样?
创建一个列表,即extension = [".jpg", ".png"]
如果当前名称包含扩展名,则将扩展名替换为空字符串。
for ext in extension:
if ext in ls_imgs2_path[i2]:
img_name2 = ls_imgs2_path[i2].replace(ext, "")
或更高效
img_name2 = [ls_imgs1_path[i1].replace(ext, "") for ext in extension if ext in ls_imgs2_path[i2]][0]
我需要导出到excel文件的百分比
首先定义百分比变量并设置为0。(仅用于初始化)
percentage_similarity = 0
据我所知,要计算相似度,比较的图像形状必须相等。如果每个通道的 countNonZero
值相同,则将 percentage_similarity
设置为 0。
if cv2.countNonZero(b) == 0 and cv2.countNonZero(g) == 0 and cv2.countNonZero(r) ==0:
print("Similarity: 100% (equal size and channels)")
percentage_similarity = 100
否则获取最终计算结果,将其存储在 result
列表中。
result.append([img_name2, ls_imgs1[i1].shape, ls_imgs2[i2].shape, percentage_similarity])
我们必须将写入更新为 excel 循环:
创建列名:
worksheet.write(0, 0, "Name of the image")
worksheet.write(0, 1, "Image 1 dimension")
worksheet.write(0, 2, "Image 2 dimension")
worksheet.write(0, 3, "Similarity percentage")
更新循环
for name, shape1, shape2, similarity in result:
worksheet.write(row, col, name)
worksheet.write(row, col + 1, str(shape1))
worksheet.write(row, col + 2, str(shape2))
worksheet.write(row, col + 3, str(similarity) + "%")
row += 1
更新请求2
我想比较第一个文件夹中的 image1 和第二个文件夹中的 image1;第一个文件夹中的第二个图像与第二个文件夹中的第二个图像
为了实现这一点,我们需要组合列表,我们可以使用 zip
。
for original, image_to_compare in zip(ls_imgs1, ls_imgs2):
如果没有路径 "Images1\Image1" => Image1
img_name = img_name.replace("Images1/", "")
代码:
import os
import cv2
import xlsxwriter
# load all image names into a list
ls_imgs1_names = os.listdir("Images1")
ls_imgs2_names = os.listdir("Images2")
# construct image paths and save in list
ls_imgs1_path = [os.path.join("Images1", img) for img in ls_imgs1_names]
ls_imgs2_path = [os.path.join("Images2", img) for img in ls_imgs2_names]
# list comprehensin to load imgs in lists
ls_imgs1 = [cv2.imread(img) for img in ls_imgs1_path]
ls_imgs2 = [cv2.imread(img) for img in ls_imgs2_path]
extension = [".jpg", ".png"]
result = []
i = 0 # counter
for original, image_to_compare in zip(ls_imgs1, ls_imgs2):
if (".DS_Store" not in ls_imgs1_path[i]) and (".DS_Store" not in ls_imgs2_path[i]):
print("Name: {}, dimensions: {}".format(ls_imgs1_path[i], ls_imgs1[i].shape))
print("Name: {}, dimensions: {}".format(ls_imgs2_path[i], ls_imgs2[i].shape))
img_name = [ls_imgs1_path[i].replace(ext, "") for ext in extension if ext in ls_imgs1_path[i]][0]
img_name = img_name.split(os.sep)[1]
percentage_similarity = 0
# compare orignal to image_to_compare
# here just insert your code where you compare two images
# 1) Check if 2 images are equals
if original.shape == image_to_compare.shape:
print("The images have the same size and channels")
difference = cv2.subtract(original, image_to_compare)
b, g, r = cv2.split(difference)
cv2.imshow("difference", difference)
print(cv2.countNonZero(b))
if cv2.countNonZero(b) == 0 and cv2.countNonZero(g) == 0 and cv2.countNonZero(r) == 0:
print("Similarity: 100% (equal size and channels)")
percentage_similarity = 100
else:
# 2) Check for similarities between the 2 images
sift = cv2.xfeatures2d.SIFT_create()
kp_1, desc_1 = sift.detectAndCompute(original, None)
kp_2, desc_2 = sift.detectAndCompute(image_to_compare, None)
index_params = dict(algorithm=0, trees=5)
search_params = dict()
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(desc_1, desc_2, k=2)
good_points = []
ratio = 0.9 # mai putin de 1
for m, n in matches:
if m.distance < ratio * n.distance:
good_points.append(m)
# Define how similar they are
number_keypoints = 0
if len(kp_1) <= len(kp_2):
number_keypoints = len(kp_1)
else:
number_keypoints = len(kp_2)
print("Keypoints 1ST Image: " + str(len(kp_1)))
print("Keypoints 2ND Image: " + str(len(kp_2)))
print("How good it's the match: ", len(good_points) / number_keypoints * 100, "%")
# print(original.name)
# print("Title:" +title)
percentage_similarity = len(good_points) / number_keypoints * 100
print("Similarity: " + str(int(percentage_similarity)) + "%\n")
result.append([img_name, ls_imgs1[i].shape, ls_imgs2[i].shape, percentage_similarity])
i += 1
workbook = xlsxwriter.Workbook('result.xlsx')
worksheet = workbook.add_worksheet()
row = 1
col = 0
worksheet.write(0, 0, "Name of the image")
worksheet.write(0, 1, "Image 1 dimension")
worksheet.write(0, 2, "Image 2 dimension")
worksheet.write(0, 3, "Similarity percentage")
for name, shape1, shape2, similarity in result:
worksheet.write(row, col, name)
worksheet.write(row, col + 1, str(shape1))
worksheet.write(row, col + 2, str(shape2))
worksheet.write(row, col + 3, str(similarity) + "%")
row += 1
workbook.close()