如何在python中打印循环内的图像名称并将所有打印件导出到excel

时间:2021-01-10 10:44:51

标签: python python-3.x excel opencv image-processing

我有一个图像比较脚本。

如何在每次循环时打印图像名称?

另外,我可以打印两个图像测量值吗?

最重要的部分:如何将所有打印的东西导出到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")
    

这是所需的格式: This is the format needed

以下方法有效,但它将所有图像与所有图像进行比较(文件夹中的 4 个图像和文件夹中的 4 个图像,它导出 16 行)。我只需要 4 行,每次比较一个,我的意思是文件夹 Images1 中的 image1 与文件夹 Images2 中的 Image1,等等。 也只需要没有路径的名称 例如:Images1\Image1 => Image1

有什么想法吗? enter image description here

如果我使用这个版本,我可以比较不同的图像,我怎样才能使最终代码以相同的方式工作?

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")

1 个答案:

答案 0 :(得分:5)

首先,我想提一下您的代码中可能存在的错误。

  • 如果 originalimage_to_compare 变量形状不相等,则会发生错误。由于 differenceb 变量都没有定义。因此,如果您重新格式化代码:

    • 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_pathls_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中,并且在第一列中我需要显示图像名称?

  • 您有多种选择,xlswriterpandas

  • 例如: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()