2025年4月12日 星期六 乙巳(蛇)年 正月十三 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

利用Python3的opencv等处理地展中采集的图片数据,生成表格后导入到网上示范田中

时间:12-10来源:作者:点击数:16

01_resize.py:修改图片尺寸为600*800或者800*600并保存到small文件夹中,若有错误会生成“第一步LOG日志.txt”文件。 

  • #!/usr/bin/env python
  • # coding=utf-8
  • # 延伸阅读:https://www.cdsy.xyz/computer/programme/Python/241210/cd64921.html
  • # 修改图片尺寸为600*800或者800*600并保存到small文件夹中
  • import os
  • import cv2
  • import numpy as np
  • # 从里面一行行的读取文件夹名字
  • class Resize():
  • def __init__(self):
  • self.file_list = "file_list.txt"
  • with open(self.file_list,"r")as f:
  • file = f.read()
  • file_name_list = file.split()
  • for name in file_name_list:
  • img_dir = "./images/" + name
  • if os.path.exists(img_dir):
  • self.main(name,img_dir)
  • def main(self,name,img_dir):
  • # 存放一些错误信息
  • error_list = []
  • # img_dir = "./images/"+name # 以后实际中需要更换
  • file_name = img_dir.rsplit('/', 1)[1].strip()
  • small_dir = "./images/small"
  • # 在small里建立和img_dir中west-4文件名一样的文件夹
  • small_full_dir = os.path.join(small_dir, file_name)
  • # 在img_dir文件夹中创建small文件夹,如果没有则创建
  • if not os.path.exists(small_full_dir):
  • os.makedirs(small_full_dir)
  • # 获取所有.jpg的图片名字,并按照升序排列
  • file_names = sorted([f for f in os.listdir(img_dir) if f.lower().endswith('.jpg')])
  • print('%s文件夹中一共%s张图片需要处理'%(name,len(file_names)))
  • # Resizing and save into subfolder
  • # dim = None
  • num = 1
  • for name in file_names:
  • img_path = os.path.join(img_dir, name)
  • # 这个可以处理图片放在中文名字的文件夹中
  • img=cv2.imdecode(np.fromfile(img_path, dtype=np.uint8), -1)
  • # 以下这个不能处理图片放在中文名字的文件夹中,并且img如果返回None说明路径中有中文
  • # img = cv2.imread(os.path.join(img_dir, name))
  • # img.shape返回(高度,宽度,通道数)的元组。
  • # 如果高度大于宽度,图片尺寸也就是3120×4160这种的转换为600×800
  • if img.shape[0] > img.shape[1]:
  • dim = (600, 800)
  • else:
  • dim = (800, 600)
  • # 修改尺寸
  • img_small = cv2.resize(img, dim)
  • img_small_path = os.path.join(small_full_dir, name)
  • # 这个不知道为啥返回none
  • status = cv2.imencode('.jpg', img_small)[1].tofile(img_small_path)
  • # 返回true或false
  • # status = cv2.imwrite(img_small_path, img_small)
  • if not status:
  • print("第%s张处理成功"%num)
  • num += 1
  • print('%s resized copied to %s' % (name, img_small_path))
  • else:
  • print("第%s张图片%s处理失败"%(num,name))
  • error_list.append("第%s张图片%s处理失败"%(num,name))
  • num += 1
  • # 生成错误日志文件
  • log_file = small_full_dir + "/" + name + "第一步LOG日志.txt"
  • if len(error_list)>0:
  • with open(log_file, "w")as f:
  • for i in range(len(error_list)):
  • f.write(error_list[i] + "\n")
  • else:
  • if os.path.exists(log_file):
  • os.remove(log_file) # 删除日志文件
  • print('Resizing complete!'+"\n")
  • if __name__ == "__main__":
  • try:
  • resize = Resize()
  • except Exception as e:
  • print("出错了:",e)

02_create_xlsx_with_file_names.py:将small文件夹中处理尺寸后的图片名字全部写入到表格中,根据生成的表格,让用户将B列填写完整(无用的图用x/xx/xxx均可,不区分大小写,用户只需要填入有地编号牌子的那一张图即可)。

  • #!/usr/bin/env python
  • # coding=utf-8
  • # 将small文件夹中处理尺寸后的图片名字全部写入到表格中
  • import os
  • from openpyxl import Workbook, load_workbook
  • class Create_xlsx():
  • def __init__(self):
  • self.file_list = "file_list.txt"
  • with open(self.file_list,"r")as f:
  • file = f.read()
  • file_name_list = file.split()
  • for name in file_name_list:
  • img_dir = "./images/" + name
  • if os.path.exists(img_dir):
  • self.main(name)
  • def main(self,name):
  • # img_dir = "./images/"+name # 以后实际中需要更换
  • # file_name = img_dir.rsplit('/', 1)[1].strip()
  • file_name = name
  • small_dir = "./images/small"
  • img_full_dir = os.path.join(small_dir, file_name)
  • # 保存表格名字
  • xlsx_name = file_name+ ".xlsx"
  • filenames = sorted([f for f in os.listdir(img_full_dir) if f.lower().endswith('.jpg')])
  • # Create xlsx file and write the sorted filenames to the first column
  • wb = Workbook()
  • ws = wb.active
  • for idx, name_ in enumerate(filenames):
  • ws.cell(row=idx + 1, column=1).value = name_
  • # Formatting单元格A列宽度
  • ws.column_dimensions['A'].width = 26
  • wb.save(os.path.join(img_full_dir, xlsx_name))
  • wb.close()
  • print("表格已生成,%s共处理%s张图片"%(name,len(filenames)))
  • if __name__ == "__main__":
  • try:
  • resize = Create_xlsx()
  • except Exception as e:
  • print("出错了:",e)

03_generate_new_names:填写完整后的表格生成D/E/F/G等列的内容,包含shadw值、图片修改后的名字、棚号、地编等,如果有重复的地编会变红色,若有错误会生成“第三步LOG日志.txt”文件。(第一列原始图片名字、第二列用户填入的地编号、第三列无用数据为了生成第五列需要、第四列匹配到的shadw值、第五列以shadw值命名的唯一新图片名字、第六列文件夹名字也就是棚号、第七列地编号)

  • #!/usr/bin/env python
  • # coding=utf-8
  • # 根据生成的表格,让用户将B列填写完整后生成D/E/F/G等列的内容,包含shadw值、图片修改后的名字、棚号、地编等
  • # 如果有重复的地编会变红色一定要先让用户修改,修改完毕后再重新执行此文件
  • import os
  • from openpyxl import load_workbook
  • from openpyxl.styles import Font
  • from openpyxl.styles import colors
  • class Generate_new_names():
  • def __init__(self):
  • self.file_list = "file_list.txt"
  • with open(self.file_list,"r")as f:
  • file = f.read()
  • file_name_list = file.split()
  • for name in file_name_list:
  • img_dir = "./images/" + name
  • if os.path.exists(img_dir):
  • self.main(name)
  • def main(self,name):
  • # img_dir = "./images/" + name # 以后实际中需要更换
  • # file_name = img_dir.rsplit('/', 1)[1].strip() # 获取文件夹名字west-4
  • file_name = name
  • small_dir = "./images/small"
  • # ./images/small\west-4
  • img_full_dir = os.path.join(small_dir, file_name)
  • # 生成表格名字
  • xlsx_name = file_name+".xlsx"
  • # 需要调取的表格名字
  • shadow_list_excel = "shadow_list.xlsx"
  • # 打开本地表格shadow_list.xlsx
  • wb0 = load_workbook(shadow_list_excel)
  • ws0 = wb0.active
  • # ws0.dimensions:有数据的单元格区域A1:E4088
  • # 第一个sheet表名.单元格名,一行是一个元组
  • # ws0[ws0.dimensions]:(<Cell '棚区露地'.A1>, <Cell '棚区露地'.B1>, <Cell '棚区露地'.C1>, <Cell '棚区露地'.D1>, <Cell '棚区露地'.E1>)
  • # 组合成字典{('1-8', 'C213'): 'shadow1059-4051'}
  • shadow_dict = dict()
  • # 处理shadow_list.xlsx
  • for c1, c2, c3,c4,c5 in ws0[ws0.dimensions]:
  • # c1,c2,c3,c4,c5分别为表格中的五列,第二列和第三列组合成元组后是shadow_dict字典的key值
  • # 我们要用第二列和第三列组合成整体去判断filename_list.xlsx里面的第二列 从而得到唯一的shadow值
  • if shadow_dict.get((c2.value, c3.value)) is not None:
  • print('ERROR:重复! shadow_list.xlsx表格中 (%s,%s)出现了多次!'%(c2.value, c3.value))
  • # raise Exception('重复! when loading %s', c2.value, c3.value)
  • shadow_dict[(str(c2.value), str(c3.value))] = c4.value
  • wb0.close()
  • # 获取表格路径
  • xlsx_path = os.path.join(img_full_dir, xlsx_name)
  • wb = load_workbook(xlsx_path)
  • print('Opened xlsx file successfully!(%s)'%xlsx_path)
  • ws = wb.active
  • shadow_id = ""
  • # Generate new name
  • label_tmp = ''
  • j = 0
  • # 如果需要跳过这个无用图就写列表中的任意一个值
  • skip_list = ['x', 'xx', 'xxx']
  • # 存放一些错误信息
  • error_list = []
  • # 存储用户输入的地编
  • all_labels = []
  • for i in range(len(ws['A'])):
  • # 第一列生成的图片原始名字
  • origin_name = ws.cell(row=i+1, column=1).value
  • # 第二列用户输入的地编号
  • label = ws.cell(row=i+1, column=2).value
  • # zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0:'00001-'
  • prefix = str(i+1).zfill(5) + '-'
  • # If labeled 'xxx', it refers to the img to be skipped.
  • if label:
  • # 第二列用户输入的地编号
  • label = str(label).strip()
  • if label.lower() in skip_list:
  • ws.cell(row=i+1, column=3).value = prefix + 'SKIPPED.jpg'
  • print('%s is skipped!' % origin_name)
  • # error_list.append('%s is skipped!' % origin_name)
  • label_tmp = ''
  • continue
  • if label != '':
  • # 如果用户输入的第二列值有重复数据,标红色
  • if label in all_labels:
  • #raise Exception('Duplicates!! Dir: %s, Label: %s at row %d.' % (img_dir.rsplit('/', 1)[1], label, i+1))
  • print('重复!! 文件夹: %s, %d行地编%s之前已经存在.' % (file_name, i+1, label))
  • ws.cell(i + 1, 2).font = Font(color=colors.RED)
  • error_list.append('重复!! 文件夹: %s, %d行地编%s之前已经存在.' % (file_name, i+1, label))
  • else:
  • ws.cell(i + 1, 2).font = Font(color=colors.BLACK)
  • if label not in skip_list:
  • all_labels.append(label)
  • j = 0
  • label_tmp = label
  • # Look for the shadow id with field-name and label
  • if (file_name, label) not in shadow_dict.keys():
  • if label not in skip_list:
  • print("错误的ID", (file_name, label))
  • error_list.append("错误ID:"+str((file_name,label)))
  • shadow_id = '未找到'
  • else:
  • shadow_id = shadow_dict[(file_name, label)]
  • label_tmp += '__' + shadow_id
  • # 00034- + TW12__shadow135-770 + -LABEL.jpg
  • ws.cell(row=i+1, column=3).value = prefix + label_tmp + '-LABEL.jpg'
  • if j > 0:
  • if label_tmp:
  • new_name = '%s%s-0%d.jpg' % (prefix, label_tmp, j)
  • # 用不到:00047-TW27__shadow150-860-01.jpg,用来生成第五列
  • ws.cell(row=i+1, column=3).value = new_name
  • # 第四列shadw值
  • ws.cell(row=i+1, column=4).value = shadow_id
  • # 第五列用shadw值命名的图片名字
  • ws.cell(row=i+1, column=5).value = new_name.split('__')[1]
  • # 第六列棚号
  • ws.cell(row=i+1, column=6).value = file_name
  • # 第七列地编
  • ws.cell(row=i+1, column=7).value = label_tmp.split('__')[0]
  • j += 1
  • # 生成错误日志文件
  • log_file = img_full_dir + "/" + file_name + "第三步LOG日志.txt"
  • if len(error_list)>0:
  • with open(log_file, "w")as f:
  • for i in range(len(error_list)):
  • f.write(error_list[i]+"\n")
  • else:
  • if os.path.exists(log_file):
  • os.remove(log_file)
  • # 设置列宽
  • ws.column_dimensions['C'].width = 40
  • ws.column_dimensions['D'].width = 17
  • ws.column_dimensions['E'].width = 27
  • # Save and close
  • wb.save(xlsx_path)
  • wb.close()
  • print('%s数据处理完成!'%name+"\n")
  • if __name__ == "__main__":
  • try:
  • resize = Generate_new_names()
  • except Exception as e:
  • print("出错了:",e)

04_rename_all:修改图片名字放到目录/images/final/中,如果第五列中有重复的图片名字会变红色,若有错误会生成“第四步LOG日志.txt”文件。

  • #!/usr/bin/env python
  • # coding=utf-8
  • # 修改图片名字放到目录/images/final/中
  • import os
  • from openpyxl import load_workbook
  • from shutil import copyfile
  • from openpyxl.styles import Font
  • from openpyxl.styles import colors
  • class Rename():
  • def __init__(self):
  • self.file_list = "file_list.txt"
  • with open(self.file_list,"r")as f:
  • file = f.read()
  • file_name_list = file.split()
  • for name in file_name_list:
  • img_dir = "./images/" + name
  • if os.path.exists(img_dir):
  • self.main(name)
  • def main(self,name):
  • print('开始重命名...')
  • # img_dir = "./images/"+name # 以后实际中需要更换
  • # file_name = img_dir.rsplit('/', 1)[1].strip() # 获取文件夹名字west-4
  • file_name = name # 获取文件夹名字west-4
  • small_dir = "./images/small"
  • # ./images/small\west-4
  • img_full_dir = os.path.join(small_dir, file_name)
  • # 生成表格名字
  • xlsx_name = file_name+".xlsx"
  • # 获取表格路径
  • xlsx_path = os.path.join(img_full_dir, xlsx_name)
  • # 将改后的名字单独放在一个目录中
  • copy_dir ="./images/final/"+name
  • wb = load_workbook(xlsx_path)
  • print('Workbook loaded successfully!')
  • ws = wb.active
  • if copy_dir:
  • if not os.path.exists(copy_dir):
  • os.makedirs(copy_dir)
  • print('复制模式: copy to', copy_dir)
  • else:
  • print('Rename inplace mode.')
  • count = 0
  • # 检测第五列替换后的名字有没有重复的
  • rename_result=[]
  • error_list = []
  • for i in range(len(ws['A'])):
  • # 将from一列里面的图片名字改成to五列的名字
  • name_from = str(ws.cell(row=i+1, column=1).value)
  • name_to = str(ws.cell(row=i + 1, column=5).value)
  • # 去掉未找到的和空的
  • if "未找到" not in name_to and name_to != "None":
  • if copy_dir:
  • if name_to not in rename_result:
  • rename_result.append(name_to)
  • copyfile(os.path.join(img_full_dir, name_from),
  • os.path.join(copy_dir, name_to))
  • count += 1
  • ws.cell(i + 1, 5).font = Font(color=colors.BLACK)
  • print('%s renamed and copied to %s' % (name_from, copy_dir))
  • else:
  • print("注意,small中%s表格第五列中第%s行有重复的图片名字"%(name,i+1))
  • error_list.append("注意,small中%s表格第五列中第%s行有重复的图片名字"%(name,i+1))
  • ws.cell(i+1, 5).font = Font(color=colors.RED)
  • continue
  • wb.save(xlsx_path)
  • else:
  • os.rename(os.path.join(img_full_dir, name_from),
  • os.path.join(img_full_dir, name_to))
  • count += 1
  • print('%s renamed to %s inplace.' % (name_from, name_to))
  • print('总共%d张图片重命名完成.' % count)
  • log_file = copy_dir +"/" + name + "第四步LOG日志.txt"
  • if len(error_list)>0:
  • with open(log_file, "a")as f:
  • for i in range(len(error_list)):
  • f.write(error_list[i]+"\n")
  • else:
  • if os.path.exists(log_file):
  • os.remove(log_file)
  • wb.close()
  • print('Workbook closed successfully!')
  • print('Rename completed!'+"\n")
  • if __name__ == "__main__":
  • try:
  • resize = Rename()
  • except Exception as e:
  • print("出错了:",e)

05_merge_excel: 这个是新增加的功能,将第三步中生成表格中有用的数据(4-7列数据)合并到一个表格中:total.xlsx,存放于images目录下,若有错误会在images目录下生成“第五步LOG日志.txt”文件。

  • #!/usr/bin/env python
  • # coding=utf-8
  • # 最后合并每一个excel表格到总表:./images/total.xlsx
  • import os
  • from openpyxl import load_workbook
  • from openpyxl import Workbook
  • from openpyxl.styles import Font, Alignment
  • import time
  • class Merge_excel():
  • def __init__(self):
  • self.length = 0
  • self.wb = Workbook()
  • self.ws = self.wb.active
  • result_excel = "./images/total.xlsx"
  • # 写表头
  • header = ["shadw值", "图片名字", "棚号", "地编"]
  • self.ws.append(header)
  • self.file_list = "file_list.txt"
  • with open(self.file_list, "r")as f:
  • file = f.read()
  • file_name_list = file.split()
  • for name in file_name_list:
  • img_dir = "./images/small/" + name
  • if os.path.exists(img_dir):
  • self.main(name,img_dir)
  • # 设置列宽
  • self.ws.column_dimensions['A'].width = 18
  • self.ws.column_dimensions['B'].width = 26
  • self.ws.column_dimensions['C'].width = 9
  • self.ws.column_dimensions['D'].width = 9
  • # 冻结首行
  • self.ws.freeze_panes = 'A2'
  • # 设置第一行加粗垂直居中
  • for k in range(len(header)):
  • d = self.ws.cell(row=1, column=k+1)
  • d.font = Font(bold=True)
  • d.alignment = Alignment(horizontal='center',vertical='center')
  • self.wb.save(result_excel)
  • print("以上数据全部处理完毕,表格存放于%s"%result_excel)
  • def main(self,name,img_dir):
  • # img_dir = "./images/small/" + name
  • # 列表形式['west-4.xlsx']
  • file_names = [f for f in os.listdir(img_dir) if f.lower().endswith('.xlsx')]
  • # 表格路径
  • local_excel_path = os.path.join(img_dir,file_names[0])
  • # 将需要的数据组装成列表
  • result_data = []
  • # 打开本地表格west-4.xlsx
  • wb0 = load_workbook(local_excel_path)
  • ws0 = wb0.active
  • print("打开表格%s成功."%local_excel_path)
  • for c1, c2, c3, c4, c5,c6,c7 in ws0[ws0.dimensions]:
  • # 一行需要的数据为一个列表最后放到result_data中
  • data = []
  • if c4.value is not None:
  • data.append(c4.value)
  • data.append(c5.value)
  • data.append(c6.value)
  • data.append(c7.value)
  • result_data.append(data)
  • print("写入数据中,共%s行数据需要写入..."%len(result_data))
  • for i in range(self.length,self.length+len(result_data)):
  • for j in range(len(result_data[i-self.length])):
  • self.ws.cell(row=i+2,column=j+1,value=result_data[i-self.length][j])
  • print("%s写入完毕!"%name + "\n")
  • # 继续上一个表格的最后一行数据继续写入
  • self.length += len(result_data)
  • if __name__ == "__main__":
  • try:
  • resize = Merge_excel()
  • log_file = "./images/第五步LOG日志.txt"
  • if os.path.exists(log_file):
  • os.remove(log_file)
  • except Exception as e:
  • print("出错了:",e)
  • log_file = "./images/第五步LOG日志.txt"
  • if e:
  • with open(log_file, "w")as f:
  • f.write(str(e) + "\n")

首先:要将“file_list.txt”补充完整,作用是读取的文件夹名字,文件名字不可更改;

其次:将“shadow_list.xlsx”补充完整,作用是根据第二列和第三列的组合去匹配第四列的shadw值(第一列文件夹中文名、第二列文件夹非中文名字、第三列地编号、第四列唯一的shadw值、第五列上传完示范田后的田id)文件名字不可更改;

最后:按照py文件名字顺序依次执行,处理完02_create_xlsx_with_file_names后,需要添加有标签图片的地编号。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐