您当前的位置: 首页 > 综合百科 > 利用ChatGPT3.5 预处理车辆计数数据集:CARPK和PUCPR+
利用ChatGPT3.5 预处理车辆计数数据集:CARPK和PUCPR+
发布时间:2023-09-18 17:29

本文在 3.5的辅助下对CARPK数据集和PUCPR+数据集进行了预处理,包括划分数据集和将数据集内的框标注转换为点标注。

1 数据集介绍

在简书上找到了它们的下载地址:

CARPK数据集和PUCPR+数据集由Hsieh等人[1]在2017年中提出,其中CARPK数据集包含使用无人机拍摄的989张训练图像和459张测试图像,包含89777辆汽车的信息。PUCPR+数据集是原始PUCPR数据集的修订版本,由fxe相机捕获,包含100张训练图像和25张测试图像,共有17000辆汽车信息。上述数据集涉及车辆照明、黑暗程度和背景等方面的显著变化,部分展示图见图1和图2。

图1 CARPK数据集展示

图2 PUCPR+数据集展示

CARPK数据集和PUCPR+数据集内部结构一样,分为三个文件夹、和。存放了各个图像的车辆框标注信息,与图像同名;中存放了图像;存放了训练集和测试集的图像名,如图3所示。

图3 数据集结构图

2 划分数据集

根据里的训练集和测试集信息将对应图片和txt提取出来便可将数据集进行划分。

首先询问:实现,根据txt里存储的文件名称(无后缀)将一个文件夹中的文件提取到新的文件夹中。

答复如下:

要实现根据txt文件中存储的文件名称(无后缀)将一个文件夹中的文件提取到新的文件夹中,你可以使用的库来完成。下面是一个示例代码,假设txt文件中每行包含一个文件名(无后缀),文件夹中的文件也都是以这些文件名命名的。

import os
import shutildef extract_files(source_folder, destination_folder, txt_file_path):with open(txt_file_path, 'r') as txt_file:for line in txt_file:file_name = line.strip()  # Remove newline characters or spacessource_file_path = os.path.join(source_folder, file_name)destination_file_path = os.path.join(destination_folder, file_name)try:shutil.move(source_file_path, destination_file_path)print(f"Moved {file_name} to {destination_folder}")except FileNotFoundError:print(f"File {file_name} not found in {source_folder}")except shutil.Error as e:print(f"Error moving {file_name}: {e}")# 示例用法
source_folder = '/path/to/source_folder'
destination_folder = '/path/to/destination_folder'
txt_file_path = '/path/to/file_names.txt'extract_files(source_folder, destination_folder, txt_file_path)

请注意,在运行代码之前,确保替换/path/to/、/path/to/和/path/to/.txt为实际的文件夹路径和txt文件路径。此代码将逐行读取txt文件中的文件名,并将相应的文件从源文件夹移动到目标文件夹。如果文件名对应的文件不存在或移动过程中出现错误,将会显示相应的错误消息。

然后本文根据提供的复制语法实现了将图片和标注文件提取到训练集文件夹和测试集文件夹的语法,详情看注释即可,值得注意的是本文将图片和标注文件分到两个文件夹中了。

# 根据给定的train.txt 和 test.txt提取图片
import os
import shutildef select_and_copy_images(txt_file, source_folder, destination_folder_img,destination_folder_ann):# 创建目标文件夹(如果不存在)if not os.path.exists(destination_folder_img):os.makedirs(destination_folder_img)if not os.path.exists(destination_folder_ann):os.makedirs(destination_folder_ann)# 读取txt文件中的图片名with open(txt_file, 'r') as file:image_names = file.read().splitlines()# 从源文件夹中选择并复制图片到目标文件夹for image_name in image_names:source_path = os.path.join(os.path.join(source_folder,'Images'), image_name+'.png')print(source_path)destination_path = os.path.join(destination_folder_img, image_name+'.png')if os.path.exists(source_path):shutil.copyfile(source_path, destination_path)print("已复制图片: "+image_name)else:print("找不到图片: "+image_name)# 从源文件夹中选择并复制标注文件到目标文件夹for image_name in image_names:source_path = os.path.join(os.path.join(source_folder,'Annotations'), image_name+'.txt')print(source_path)destination_path = os.path.join(destination_folder_ann, image_name+'.txt')if os.path.exists(source_path):shutil.copyfile(source_path, destination_path)print("已复制标注文件: "+image_name)else:print("找不到标注文件: "+image_name)file=['train','test']
for i in file:#遍历训练集和测试集txt_file = os.path.join(r'/CARPKandPUCPR/CARPK_devkit/data/ImageSets',i+'.txt') # 训练集=测试集txt的存放地址source_folder = os.path.join(r'/CARPKandPUCPR/CARPK_devkit/data') # 源路径destination_folder_img = os.path.join(r'/CARPKandPUCPR/CARPK_devkit/data/destination_folder', i,'img') # 目的路径-图片destination_folder_ann = os.path.join(r'/CARPKandPUCPR/CARPK_devkit/data/destination_folder', i,'ann')# 目的路径-标注文件select_and_copy_images(txt_file, source_folder, destination_folder_img,destination_folder_ann)

接着需要将训练集划分出验证集,

首先询问:实现,从第一个图片开始每隔几个文件抽取一个文件并复制到目标文件夹

答复如下:

要实现从第一个图片开始每隔几个文件抽取一个文件并复制到目标文件夹,你可以使用的库来进行文件复制。下面是一个示例代码:

import os
import shutildef extract_images_with_interval(source_folder, destination_folder, interval):file_list = sorted(os.listdir(source_folder))  # 获取源文件夹中的所有文件,并按名称排序for i in range(0, len(file_list), interval):source_file_path = os.path.join(source_folder, file_list[i])destination_file_path = os.path.join(destination_folder, file_list[i])try:shutil.copyfile(source_file_path, destination_file_path)print(f"Copied {file_list[i]} to {destination_folder}")except FileNotFoundError:print(f"File {file_list[i]} not found in {source_folder}")except shutil.Error as e:print(f"Error copying {file_list[i]}: {e}")# 示例用法
source_folder = '/path/to/source_folder'
destination_folder = '/path/to/destination_folder'
interval = 3  # 设置复制间隔为3个文件extract_images_with_interval(source_folder, destination_folder, interval)

请注意,在运行代码之前,确保替换/path/to/和/path/to/为实际的文件夹路径,并根据需要设置复制的间隔数()。此代码将从源文件夹中按照指定的间隔抽取图片并复制到目标文件夹,并在控制台上显示复制的文件名。例如,如果设置间隔为3,那么代码将从第一个文件开始,每隔两个文件复制一个文件到目标文件夹。

这上面提供的语法已经很完善了,根据具体情况可以具体处理,本文根据此实现了将文件夹中的图片抽取一部分到另一个文件夹中。

# 根据一定间隔提取图片import os
import shutildef extract_images(source_folder, destination_folder, interval):# 创建目标文件夹(如果不存在)if not os.path.exists(destination_folder):os.makedirs(destination_folder)# 获取源文件夹中的所有图片文件,并按文件名排序image_files = sorted([file for file in os.listdir(source_folder) if file.endswith('.jpg') or file.endswith('.png')])# 从第一个图片开始每隔一定间隔抽取图片并复制到目标文件夹for i in range(0, len(image_files), interval):image_name = image_files[i]source_path = os.path.join(source_folder, image_name)destination_path = os.path.join(destination_folder, image_name)shutil.copyfile(source_path, destination_path)# os.remove(source_path) #删除源图片source_folder = r'Images'  # 源图片所在文件夹路径
destination_folder = r'valImages'  # 抽取后存储图片的目标文件夹路径
interval = 10  # 抽取间隔extract_images(source_folder, destination_folder, interval)```

3 将数据集中的框标注转换为点标注

首先确认框标注文件的格式,根据官方源码可知,标注文件的格式是x1 y1 x2 y2,对应着框的左上角坐标和右下角坐标。

##------------------官方代码:部分----------------------for idx, obj in enumerate(objs):info = re.findall('\d+', obj)x1 = float(info[0])y1 = float(info[1])x2 = float(info[2])y2 = float(info[3])gtBBs[idx, :] = [x1, y1, x2, y2]
##------------------官方代码:部分----------------------

然后

询问:将一个文件夹中的框标注文件转换为点标注文件并转移到新的文件夹中。其中框标注文件是.txt后缀,每一个框标注文件含有多行x1 y1 x2 y2信息,对应着框的左上角坐标和右下角坐标。

答复如下:

import os
import shutildef convert_bbox_to_points(bbox_file_path):# 读取框标注文件with open(bbox_file_path, 'r') as file:lines = file.readlines()points = []for line in lines:# 解析x1 y1 x2 y2信息并计算框的中心点坐标x1, y1, x2, y2 = map(int, line.strip().split())center_x = (x1 + x2) // 2center_y = (y1 + y2) // 2points.append((center_x, center_y))return pointsdef main():# 原始文件夹路径和目标文件夹路径source_folder = 'path/to/source_folder'destination_folder = 'path/to/destination_folder'# 创建目标文件夹(如果不存在)if not os.path.exists(destination_folder):os.makedirs(destination_folder)# 遍历原始文件夹中的所有框标注文件for filename in os.listdir(source_folder):if filename.endswith('.txt'):# 构建完整路径bbox_file_path = os.path.join(source_folder, filename)# 将框标注文件转换为点标注列表points = convert_bbox_to_points(bbox_file_path)# 构建新的点标注文件名point_file_name = filename# 构建新的点标注文件路径point_file_path = os.path.join(destination_folder, point_file_name)# 将点标注写入新的文件with open(point_file_path, 'w') as point_file:for point in points:point_file.write(f"{point[0]} {point[1]}\n")# 移动原始框标注文件到目标文件夹shutil.move(bbox_file_path, os.path.join(destination_folder, filename))if __name__ == "__main__":main()

本文感觉这里给的不太对,就自己重写了一份:

import cv2
import numpy as np
import os
import re
import argparse
from PIL import Image
import scipydef changeLine(lines,w,h):lines = lines.split(' ')x1 = int(lines[0])y1 = int(lines[1])x2 = int(lines[2])y2 = int(lines[3])Kx = (x1+x2)/2ky = (y1+y2)/2return str( 1 ) +' ' + str(Kx/w) +' ' + str(ky/h) + ' \n'txt_data = r'/data/txttxt' # 保存为所需的yolo标注文件
ann_data = r'/data/Annotations' # 框标注文件路径files = os.listdir(ann_data)for file in files:ann_path = os.path.join(ann_data,file)img_path = ann_path.replace('Annotations','Images').replace('.txt','.jpg')img = cv2.imread(img_path, 1)h,w = img.shape[0],img.shape[1] ann = open(ann_path, encoding='utf-8')annLines = ann.readlines()result = []for lines in annLines:resultL = changeLine(lines,w,h) #这里计算出点坐标相对图像长宽的比例信息。result.append(resultL)print(result)#result里存储着需要另存的txt文件with open(os.path.join(txt_data, file), 'w') as f:f.writelines(result)

转换后的点标注格式如下:

至此,对CARPK数据集和PUCPR+数据集的预处理操作就此结束。

[1] Meng-,Yen-,.Hsu.Drone-based by ,

相关阅读