当图片太多的时候,你想要找出想要匹配的图片,还要一个一个去找,太麻烦了。所以研究了一下cv2这个模块。可以实现在一堆图片里找到你想要的图片。
效果图:
import sys
import cv2
import os
import shutil
import numpy as np
from PySide2.QtWidgets import (QApplication, QMainWindow, QLabel, QLineEdit, QPushButton, QFileDialog,
QVBoxLayout, QHBoxLayout, QWidget, QProgressBar, QFormLayout)
from PySide2.QtCore import QThread, Signal
from PySide2.QtGui import QFont
class ImageMatcher(QThread):
progress = Signal(int)
result = Signal(int)
def __init__(self, source_folder, destination_folder, template_path, threshold=0.8):
super().__init__()
self.source_folder = source_folder
self.destination_folder = destination_folder
self.template_path = template_path
self.threshold = threshold
def match_template(self, image_path, template_path, threshold=0.8):
image = cv2.imread(image_path, 0)
template = cv2.imread(template_path, 0)
if image is None:
print(f"无法读取图像文件: {image_path}")
return False
if template is None:
print(f"无法读取模板文件: {template_path}")
return False
if template.shape[0] > image.shape[0] or template.shape[1] > image.shape[1]:
print(f"模板图像尺寸大于源图像尺寸: {template_path}")
return False
res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(res >= threshold)
return len(loc[0]) > 0
def run(self):
quantity = 0
file_list = os.listdir(self.source_folder)
total_files = len(file_list)
if not os.path.exists(self.destination_folder):
os.makedirs(self.destination_folder)
for idx, filename in enumerate(file_list):
file_path = os.path.join(self.source_folder, filename)
if os.path.isfile(file_path):
try:
if self.match_template(file_path, self.template_path, self.threshold):
shutil.move(file_path, os.path.join(self.destination_folder, filename))
quantity += 1
except Exception as e:
print(f"处理 {filename} 时出错: {e}")
self.progress.emit(int((idx + 1) / total_files * 100))
self.result.emit(quantity)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("图像匹配移动工具")
self.setGeometry(100, 100, 265, 250) # 调整窗口大小
font = QFont()
font.setPointSize(10)
self.source_label = QLabel("文件路径:")
self.source_label.setFont(font)
self.source_input = QLineEdit()
self.source_input.setFont(font)
self.source_button = QPushButton("选择源文件夹")
self.source_button.setFont(font)
self.source_button.clicked.connect(self.select_source_folder)
self.destination_label = QLabel("输出路径:")
self.destination_label.setFont(font)
self.destination_input = QLineEdit()
self.destination_input.setFont(font)
self.destination_button = QPushButton("选择目标文件夹")
self.destination_button.setFont(font)
self.destination_button.clicked.connect(self.select_destination_folder)
self.template_label = QLabel("模板路径:")
self.template_label.setFont(font)
self.template_input = QLineEdit()
self.template_input.setFont(font)
self.template_button = QPushButton("选择模板图片")
self.template_button.setFont(font)
self.template_button.clicked.connect(self.select_template_image)
self.start_button = QPushButton("开始")
self.start_button.setFont(font)
self.start_button.clicked.connect(self.start_matching)
self.progress_bar = QProgressBar()
self.progress_bar.setTextVisible(True) # 使进度条显示文本
self.result_label = QLabel("")
form_layout = QFormLayout()
form_layout.setSpacing(10) # 设置控件之间的间距
form_layout.addRow(self.source_label, self.source_input)
form_layout.addRow(self.source_button)
form_layout.addRow(self.destination_label, self.destination_input)
form_layout.addRow(self.destination_button)
form_layout.addRow(self.template_label, self.template_input)
form_layout.addRow(self.template_button)
button_layout = QHBoxLayout()
button_layout.addWidget(self.start_button)
button_layout.addWidget(self.progress_bar)
main_layout = QVBoxLayout()
main_layout.addLayout(form_layout)
main_layout.addLayout(button_layout)
main_layout.addWidget(self.result_label)
container = QWidget()
container.setLayout(main_layout)
self.setCentralWidget(container)
def select_source_folder(self):
folder = QFileDialog.getExistingDirectory(self, "选择源文件夹")
if folder:
self.source_input.setText(folder)
def select_destination_folder(self):
folder = QFileDialog.getExistingDirectory(self, "选择目标文件夹")
if folder:
self.destination_input.setText(folder)
def select_template_image(self):
file, _ = QFileDialog.getOpenFileName(self, "选择模板图片")
if file:
self.template_input.setText(file)
def start_matching(self):
source_folder = self.source_input.text()
destination_folder = self.destination_input.text()
template_path = self.template_input.text()
if not source_folder or not destination_folder or not template_path:
print("请确保所有路径都已选择")
return
self.matcher = ImageMatcher(source_folder, destination_folder, template_path)
self.matcher.progress.connect(self.update_progress)
self.matcher.result.connect(self.matching_finished)
self.matcher.start()
def update_progress(self, value):
self.progress_bar.setValue(value)
self.progress_bar.setFormat(f"{value}%") # 设置进度条显示格式
self.progress_bar.update()
def matching_finished(self, quantity):
self.result_label.setText(f"共移动 {quantity} 张图片")
self.progress_bar.setValue(100)
self.progress_bar.setFormat("100%") # 显示完成
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())