💪 专业从事且热爱图像处理,图像处理专栏更新如下👇:
📝《图像去噪》
📝《超分辨率重建》
📝《语义分割》
📝《风格迁移》
📝《目标检测》
📝《图像增强》
📝《模型优化》
📝《模型实战部署》
📝《图像配准融合》
📝《数据集》
📝《高效助手》
一、需求
在使用大模型大批量处理图像数据时非常耗时,由于某些外界因素导致处理中断,先前已经处理好了一部分图像数据不需要再处理,只需要处理剩余未处理图像即可。
举例:在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代码,希望能帮到你!
感谢您阅读到最后!😊总结不易,多多支持呀🌹 点赞👍收藏⭐评论✍️,您的三连是我持续更新的动力💖
关注公众号「视觉研坊」,获取干货教程、实战案例、技术解答、行业资讯!