语义分割一些数据预处理的方式
写在前面:
因为最近在做裂缝检测,用的CRACK500数据集,尺寸大部分是640*340,如果直接resize(512,512)效果不太好。
尝试如下:
1、先将340尺寸填充成512 (512是你需要的尺寸)
2、因为mask标签图片需要为单通道的二值图像,填充后可能会变成RGB图像,所以再改为二值图像
3、随机裁剪,这个是我自己设计的算法,大概思想是根据你需要的尺寸,我先限定一个x和y可能的区域,再通过一个随机值来乘以这个区域的长度,横纵坐标分别加上这个区域距离左边和下边的长度,就得到了一个区间,在这个区间内的任意坐标,横纵坐标分别加减目标尺寸的一半,就可以得到四个坐标,就是最终的裁剪区域。(说的有点绕,其实很好理解,不理解也没关系,直接用)
4、因为随机裁剪,可能会有的区域没有你需要的像素点,所以我设计了一个读取像素点的函数,来删除那些目标像素点小于1000的图片(因为我用的是二值图像,非黑即白,如果和我不一样的话,可以适当更改,还有就是因为imread函数不能读有中文路径的,所以我把目标数据集文件复制了一份在桌面上,具体可以看注释)
1.填充尺寸
import cv2
import numpy as np
import os## 边界填充
# 这个按下面的对称填充改就可以
def constant(filenames, save_path):for filename in filenames:img = cv2.imread(filename)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)constant = cv2.copyMakeBorder(img, 76, 76, 0, 0, cv2.BORDER_CONSTANT, value=[0, 0, 0])cv2.imwrite(save_path + f'{i}.jpg', constant)# 对称填充
def reflect(filenames, save_path):i = 0for filename in filenames:img = cv2.imread(filename)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)reflect = cv2.copyMakeBorder(img, 76, 76, 0, 0, cv2.BORDER_REFLECT)cv2.imwrite(os.path.join(save_path, f'{i}.jpg'), reflect)i += 1def get_filename(path):file_names = os.listdir(path)image_names = []for file_name in file_names:image_path = os.path.join(path, file_name)image_names.append(image_path)return image_namesif __name__ == '__main__':image_names = get_filename(r'C:\Users\dell\Desktop\CRACK500_sameSize\test\image')save_path = r'C:\Users\dell\Desktop\CRACK500_512_padding\test\image'reflect(image_names, save_path)
2.改变图片通道,变为二值图像:
import numpy as np
from PIL import Image
import osdef get_filename(path):file_names = os.listdir(path)image_names = []for file_name in file_names:image_path = os.path.join(path, file_name)image_names.append(image_path)return image_names# 把图片改为二值图像
def change_channel(filenames):for filename in filenames:image = Image.open(filename)# 转为二值图像image_1 = image.convert('1')image_1.save(filename)if __name__ == '__main__':# 获取图片完整路径# 在括号里传文件夹路径image_names = get_filename()change_channel(image_names)
3.随机裁剪
from PIL import Image
import os
import randomdef random_crop(height, length, n):for i in range(0, n):x_random = random.random()y_random = random.random()for image_name in os.listdir(image_input_path):print(f'-----------第{image_name}张图片------------')# 每个图像全路径image_input_fullname = os.path.join(image_input_path, image_name)# PIL库打开每一张图像img = Image.open(image_input_fullname)# 定义裁剪图片左、上、右、下的像素坐标x_max = img.size[0] # 宽y_max = img.size[1] # 高print(x_max, y_max)if x_max % 2 != 0:x_max += 1if y_max % 2 != 0:y_max += 1print(x_max, y_max)x_max_half = x_max // 2 # 图片 宽的一半y_max_half = y_max // 2 # 图片 高的一半height_half = height // 2 # 裁剪框 高的一半length_half = length // 2 # 裁剪框 宽的一半if x_max >= length and y_max >= height:# print(i)lost_height = y_max_half - height_halflost_length = x_max_half - length_half# for i in range(0, n):mid_point_x = int(length_half + x_random * 2 * lost_length)mid_point_y = int(height_half + y_random * 2 * lost_height)print(f'第{i}次裁剪的中心坐标为 ', "x:", mid_point_x, "y:", mid_point_y)down = mid_point_y + height_halfup = mid_point_y - height_halfright = mid_point_x + length_halfleft = mid_point_x - length_halfBOX_LEFT, BOX_UP, BOX_RIGHT, BOX_DOWN = left, up, right, down# 从原始图像返回一个矩形区域,区域是一个4元组定义左上右下像素坐标box = (BOX_LEFT, BOX_UP, BOX_RIGHT, BOX_DOWN)# 进行roi裁剪roi_area = img.crop(box)# 裁剪后每个图像的路径+名称qianzhui, houzhui = os.path.splitext(image_name)image_output_fullname = os.path.join(image_output_path, qianzhui + f'_{i}' + houzhui)# 如果用原文件名称/只裁剪一次,可以用这个# image_output_fullname = os.path.join(image_output_path, image_name)# 存储裁剪得到的图像roi_area.save(image_output_fullname)print('{0} crop done.'.format(image_output_fullname))else:print("输入尺寸不符合要求")for image_name in os.listdir(mask_input_path):print(f'-----------第{image_name}张图片------------')# 每个图像全路径image_input_fullname = os.path.join(mask_input_path, image_name)# PIL库打开每一张图像img = Image.open(image_input_fullname)# 定义裁剪图片左、上、右、下的像素坐标x_max = img.size[0] # 宽y_max = img.size[1] # 高print(x_max, y_max)if x_max % 2 != 0:x_max += 1if y_max % 2 != 0:y_max += 1print(x_max, y_max)x_max_half = x_max // 2 # 图片 宽的一半y_max_half = y_max // 2 # 图片 高的一半height_half = height // 2 # 裁剪框 高的一半length_half = length // 2 # 裁剪框 宽的一半if x_max >= length and y_max >= height:# print(i)lost_height = y_max_half - height_halflost_length = x_max_half - length_half# for i in range(0, n):mid_point_x = int(length_half + x_random * 2 * lost_length)mid_point_y = int(height_half + y_random * 2 * lost_height)print(f'第{i}次裁剪的中心坐标为 ', "x:", mid_point_x, "y:", mid_point_y)down = mid_point_y + height_halfup = mid_point_y - height_halfright = mid_point_x + length_halfleft = mid_point_x - length_halfBOX_LEFT, BOX_UP, BOX_RIGHT, BOX_DOWN = left, up, right, down# 从原始图像返回一个矩形区域,区域是一个4元组定义左上右下像素坐标box = (BOX_LEFT, BOX_UP, BOX_RIGHT, BOX_DOWN)# 进行roi裁剪roi_area = img.crop(box)# 裁剪后每个图像的路径+名称qianzhui, houzhui = os.path.splitext(image_name)image_output_fullname = os.path.join(mask_output_path, qianzhui + f'_{i}' + houzhui) # 如果用原文件名称/只裁剪一次,可以用这个# image_output_fullname = os.path.join(mask_output_path, image_name)# 存储裁剪得到的图像roi_area.save(image_output_fullname)print('{0} crop done.'.format(image_output_fullname))else:print("输入尺寸不符合要求")if __name__ == '__main__':# 定义待批量裁剪图像的路径地址image_input_path = r'C:\Users\dell\Desktop\CRACK500_512_padding\train\image'mask_input_path = r'C:\Users\dell\Desktop\CRACK500_512_padding\train\mask'# 定义裁剪后的图像存放地址image_output_path = r''mask_output_path = r''# 需要裁剪的尺寸,第三个参数代表你要对每张图片裁几次random_crop(512, 512, 2)
4.读图片的像素,删除小于1000像素的图片
import cv2
import numpy as np
import os
from matplotlib import pyplot as plt# 获取裂缝像素小于 1000 的图片
def get_filename(path):file_names = os.listdir(path)image_names = []for file_name in file_names:image_path = os.path.join(path, file_name)img = cv2.imread(image_path)GrayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)img = np.array(GrayImage)height, width = img.shapei = 0a = 0 # 黑b = 0 # 白for row in range(height):for col in range(width):val = img[row][col]if val == 0:a = a + 1else:b = b + 1i += 1print("黑色像素有", a, "个,白色像素有", b, "个", '总共:', i)if b < 1000:image_names.append(file_name)return image_namesdef delete_image(path, image_names):for mask_name in image_names:# 删除mask文件夹下的图片mask_path = os.path.join(path, 'mask', mask_name)os.remove(mask_path)for mask_name in image_names:# 删除image文件夹下的图片,此时文件名后缀是png,需要改成jpgimage, extension = os.path.splitext(mask_name)image_name = image + '.jpg'image_path = os.path.join(path, 'image', image_name)os.remove(image_path)if __name__ == '__main__':# 因为imread不能用中文路径,先复制一份数据集获取文件名# 复制后的路径path = r'C:\Users\dell\Desktop\CRACK500_512_padding\train\mask'# 获取像素点小于1000的文件名image_names = get_filename(path)# 需要改动的数据集(就是你需要删除的数据集,上面那个path只是为了获取一份需要删除的图像名单)dataset_path = r''# 删除delete_image(dataset_path, image_names)# print(image_names)
有不懂的地方欢迎留言!
语义分割一些数据预处理的方式相关推荐
- 小菊的语义分割3——数据预处理及像素级分类实现原理
小菊的语义分割3
- 【语义分割】数据增强方法(原图与标签同时扩增)
增强方式介绍 参考链接: [技术综述] 一文道尽深度学习中的数据增强方法(上) 方式1:使用Augmentor模块 参考链接: DataAugment:同时对image和mask进行变换 语义分割 图 ...
- python工具方法 18 labelme语义分割标注数据批量转换为png
本实例代码主要使用labelme.utils.shapes_to_label方法实现批量将将labelme的语义分割标注数据转换为图片,支持将标注保存为实例分割训练图.语义分割训练图.语义分割+原图效 ...
- 零基础入门语义分割——Task2 数据扩增
文章目录 一.OpenCV数据扩增 二.albumentations数据扩增 三.Pytorch数据读取 数据扩增方法:数据扩增是一种有效的正则化方法,可以防止模型过拟合,在深度学习模型的训练过程中应 ...
- java按丨分割_全景语义分割主流数据导出格式:JSON+Mask丨曼孚科技
图像全景语义分割是人工智能计算机视觉领域的一个重要分支,它结合了图像分类.目标检测与图像分割等技术,是针对图像数据所进行的一种像素级分类. 经过全景语义分割处理后的图像,广泛应用于自动驾驶.无人机等场 ...
- 机器学习中数据预处理的方式
数据标量化 如果需要学习的不同的数据标签之间的量纲差距太大,那么需要进行数据标量化操作,有3个主要的优势: 可以使梯度下降更快 躲避"NaN陷阱",数据中有些数值可能超过了计算机的 ...
- python矩阵归一化方法_python之sklearn常见数据预处理归一化方式解析
标签: 标准归一化 归一化到均值为0,方差为1 sklearn.preprocessing.scale函数:Standardize a dataset along any axis 先贴出主要的源码, ...
- 目前缺少用于语义分割的 3D LiDAR 数据吗?关于三维点云数据集和方法的调查
目前缺少用于语义分割的 3D LiDAR 数据吗?关于三维点云数据集和方法的调查 原文 Are We Hungry for 3D LiDAR Data for Semantic Segmentatio ...
- 单眼测试_单眼鸟瞰自动驾驶语义分割
单眼测试 Autonomous driving requires an accurate representation of the environment around the ego vehicl ...
最新文章
- android用户引导页,android欢迎界面引导页
- 0.数据结构学习笔记大纲
- beego 显示html文件,[Beego] 内置的模板函数(不同格式的字符串和html的互转)
- springMVC文件下载
- spring入门(12)-spring与hibernate整合完成增删改查的操作(继承HibernateDaoSupport调用hibernateTemplate类)
- 027-日期和时间组件
- chrome下的img.onload
- 升讯威微信营销系统开发实践:(3)功能介绍与此项目推广过程的一些体会( 完整开源于 Github)...
- isinstance和issubclass
- 3. 跟踪标记 (Trace Flag) 1204, 1222 抓取死锁信息
- c#程序中使用quot;like“查询access数据库查询为空的问题
- LDA的Gibbs抽样详细推理与理解
- Java案例:几种方式拷贝文件的耗时比较
- CURL命令模拟Http Get/Post以及带cookies调用接口
- 三菱电机NC monitor 序列号申请
- java 校验银行卡号_Java + OpenCV 实现银行卡号识别 (3)
- 天涯论坛--只看楼主
- 【Keil 5】STM32F401CCU6 固件库配置(超详细教程)
- 教你如何利用python调用摄像头
- 06Java学习笔记——运算符
热门文章
- Output argument ‘state‘ is Output argument ‘state‘ is not assignot assigned on some execution paths.
- 一起认识下浏览器的5种观察器
- 祥腾财富广场、祥腾公寓、祥腾财富公寓(坐标上海市静安区汶水路地铁口)
- 玩EXSI前先看这个,让你避开多数的坑
- MATLAB 美国标准普尔500指数(sp500)的资产收益率分布的拟合与检验 统计图 拟合检验 描述性统计量分析 matlab
- 一次性提取网页中所有图片的代码
- PTA 哈利·波特的考试 (25分)
- day06_XML_dom_sax_dom4j编程
- Ubuntu20.04安装Torque-6.1.2单机版(踩坑篇)
- 网络爬虫从入门到实践(三)————动态网页的爬取