Bootstrap

批量复制不重复图像——将A文件夹中剩余与B文件夹不重名的多张图像拷贝到C文件夹(附C++和Python代码)

在这里插入图片描述

💪 专业从事且热爱图像处理,图像处理专栏更新如下👇:
📝《图像去噪》
📝《超分辨率重建》
📝《语义分割》
📝《风格迁移》
📝《目标检测》
📝《图像增强》
📝《模型优化》
📝《模型实战部署》
📝《图像配准融合》
📝《数据集》
📝《高效助手》


在这里插入图片描述

一、需求

在使用大模型大批量处理图像数据时非常耗时,由于某些外界因素导致处理中断,先前已经处理好了一部分图像数据不需要再处理,只需要处理剩余未处理图像即可。

举例:在A文件夹中有9000张图像,B文件夹中包含从A文件夹复制的2000张图像。将A文件夹中剩余的7000张且与B文件夹中的图像不重名的图片拷贝到C文件夹中。

二、Python脚本实现

2.1 参数修改

代码简单,学者使用代码需要修改的地方见下:

在这里插入图片描述

2.2 参数说明

在代码中进行拷贝过程主要用到shutil 模块,此模块的原理见下:

shutil.copy(src_path, dest_path) 是 Python 标准库 shutil 模块中的一个函数,主要用于将文件从源路径 src_path 拷贝到目标路径 dest_path。它的实现背后调用了较底层的文件操作模块,分为以下几个步骤:

(1)检查文件类型
判断 src_path 是否为普通文件(非目录)。如果不是普通文件,直接抛出 OSError。
调用 os.stat() 获取文件的元数据,用以辅助权限模式等信息的复制。

(2)打开并复制文件内容
源文件以只读模式打开 (‘rb’)。
目标文件以写模式打开 (‘wb’)。
调用底层文件读写函数(比如逐块读写文件内容)。

(3)更新文件权限
将源文件的权限模式复制到目标文件。
调用 os.chmod() 设置目标文件权限。

(4)返回目标路径
操作完成后,返回目标路径 dest_path。

2.3 代码

下面是Python版的完整代码:

import os
import shutil
from tqdm import tqdm

# 定义文件夹路径
folder_a = "Images/copy_residue_images/A"      # A文件夹路径
folder_b = "Images/copy_residue_images/B"       # B文件夹路径
folder_c = "Images/copy_residue_images/C"      # C文件夹路径

# 确保C文件夹存在
os.makedirs(folder_c,exist_ok=True)

# 获取A文件夹中的所有图片文件名
files_a = set(os.listdir(folder_a))       # set()作用是将folder_a文件夹中的所有文件名转换为一个集合set

# 获取B文件夹中所有图片的文件名
files_b = set(os.listdir(folder_b))

# 找到A文件夹中不在B文件夹中的文件
files_to_copy = files_a - files_b

# 将不在B文件件中的图像文件拷贝到C文件夹中
for file_name in tqdm(files_to_copy,desc="processing:"):
    src_path = os.path.join(folder_a,file_name)
    dest_path = os.path.join(folder_c,file_name)
    shutil.copy(src_path,dest_path)

print(f"拷贝完成,共拷贝{len(files_to_copy)}张图片到{folder_c}")

运行上面代码后,终端输出见下:

在这里插入图片描述

三、C++脚本实现

C++代码实现原理同上。

3.1 参数修改

使用C++脚本,将路径修改为自己文件夹路径即可:

在这里插入图片描述

3.2 代码

C++脚本完整代码见下:

#include <iostream>                   // 包含输入输出流的头文件
#include <filesystem>                 // 包含文件系统操作的头文件,C++17新特性
#include <algorithm>                  // 包含STL算法的头文件,比如下面代码要用到的set_difference
#include <set>                        // 包含set容器的头文件
#include <string>                     // 包含字符串类的头文件
#include <iterator>                   // 包含迭代器的头文件
#include <fstream>                    // 包含文件流的头文件

namespace fs = std::filesystem;       // 命名空间 std::filesystem 定义一个简短的别名 fs,可以在代码中使用更短的形式来引用 std::filesystem 中的类和函数

int main()
{
    //定义文件夹路径
    std::string folder_a = "copy_residue_images/A";    // A文件件路径
    std::string folder_b = "copy_residue_images/B";    // B文件夹路径
    std::string folder_c = "copy_residue_images/C";    // C文件夹路径

    // 确保C文件夹存在,如果不存在则创建
    if (!fs::exists(folder_c))
    {
        fs::create_directories(folder_c);
    }

    // 获取A文件夹中的所有图片文件名,并存储在set中,set自动去重
    std::set<std::string> files_a;
    for (const auto& entry : fs::directory_iterator(folder_a))
    {
        if (entry.is_regular_file())               // 判断是否为普通文件
        {
            files_a.insert(entry.path().filename().string());    // 插入文件名
        }
    }

    // 获取B文件夹中所有图片文件名,并存储在set中
    std::set<std::string> files_b;
    for (const auto& entry : fs::directory_iterator(folder_b))
    {
        if (entry.is_regular_file())
        {
            files_b.insert(entry.path().filename().string());
        }
    }

    // 使用set_difference算法找出A文件夹中有而B文件夹中没有的文件名
    std::set<std::string> files_to_copy;
    std::set_difference(files_a.begin(),files_a.end(),
                        files_b.begin(),files_b.end(),
                        std::inserter(files_to_copy,files_to_copy.end()));

    // 将不在B文件夹中的图片文件拷贝到C文件夹
    int count = 0;    // 计数器,记录复制的文件数量
    for (const auto& file_name : files_to_copy)
    {
        fs::path src_path = fs::path(folder_a) / file_name;             // A文件夹中文件的完整路径
        fs:: path dest_path = fs::path(folder_c) / file_name;           // C文件夹中文件的目标路径
        try
        {
            fs::copy(src_path,dest_path,fs::copy_options::overwrite_existing);   // 复制文件,如果目标文件已存在则覆盖
            ++count;     // 复制成功,计数器加1
        }
        catch (const fs::filesystem_error& e)        // 捕获文件系统错误
        {
            std::cerr << "Error copying file:" << file_name << "_" << e.what() << '\n';       // 输出错误信息
        }
    }

    std::cout << "拷贝完成,共拷贝" << count << "张图片到" << folder_c << "\n";         // 输出复制结果

    return 0;       // 程序结束
}

四、拷贝效果展示

下面给出了用上面脚本处理的例子,将A文件夹中剩余与B文件夹不重名的多张图像拷贝到C文件夹,效果见下:

在这里插入图片描述

五、总结

已经就是批量复制不重复图像,将A文件夹中剩余与B文件夹不重名的多张图像拷贝到C文件夹的详细过程及C++和Python代码,希望能帮到你!

感谢您阅读到最后!😊总结不易,多多支持呀🌹 点赞👍收藏⭐评论✍️,您的三连是我持续更新的动力💖

关注公众号「视觉研坊」,获取干货教程、实战案例、技术解答、行业资讯!

;