基于opencv的图像匹配

当图片太多的时候,你想要找出想要匹配的图片,还要一个一个去找,太麻烦了。所以研究了一下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_())

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值