loader = SegmentLoader(img_path=train_data_seg, batch_size=cfg.train_batch_size, is_train=True, pos_number=cfg.pos_number, neg_number=cfg.neg_number, defect_ratio=cfg.seg_train_defect_ratio) train_data, test_data = loader.provide()
首先创建了一个
SegmentLoader
的实例loader
,并将相关参数传递给它。然后,通过调用loader.provide()
方法,我们可以获得train_data
和test_data
,即训练数据和测试数据。
class SegmentLoader(object): def __init__(self, img_path, batch_size, pos_number=50, neg_number=50, defect_ratio=0,is_train=True, is_read=False, is_save=False): self.img_path = img_path self.batch_size = batch_size self.is_train = is_train self.labels = [] self.images = [] self.masks = [] self.is_read = is_read self.is_save = is_save self.pos_number = pos_number self.neg_number = neg_number self.positive_num = 0 self.negative_num = 0 self.img_paths = [] self.defect_ratio = defect_ratio self.eval_scale = 0.05
定义了一个名为
SegmentLoader
的类,并在构造函数__init__()
中初始化了各个属性。在 Python 中,类中的
def __init__()
构造函数用于初始化类的实例(对象)。当创建一个类的实例时,构造函数会自动调用,并允许我们对对象的属性进行初始化。构造函数的主要作用如下:
对象属性初始化:构造函数允许我们在创建对象时为其属性赋初始值。我们可以通过构造函数中的参数来接收外部传入的值,并将其赋给对象的属性。这样,在创建对象后,对象就具有了特定的初始状态和属性值。
设置默认值:通过在构造函数中定义参数的默认值,我们可以为对象的属性提供默认值。如果在创建对象时没有为这些参数提供值,那么构造函数会使用默认值来初始化相应的属性。
执行其他初始化操作:除了属性初始化,构造函数还可以执行其他必要的初始化操作。这可能包括打开文件、建立数据库连接、加载数据等。构造函数提供了一个在对象创建时执行这些操作的机会。
总之,构造函数在类的实例化过程中起着重要的作用,它确保对象在创建后具有正确的初始状态和属性值,并允许执行其他必要的初始化操作。
import file_list as data_list #将 file_list.py文件导入,并访问其中的两个列表 def provide(self): images_files = [] labels_files = [] orig_roots_pos = data_list.orig_roots_pos seg_roots_pos = data_list.seg_roots_pos type_list = ['.bmp', '.jpg']
for i in range(len(orig_roots_pos)): orig_file_paths = os.listdir(orig_roots_pos[i]) seg_file_paths = os.listdir(seg_roots_pos[i]) print("{} {} Files Loading... ".format(orig_roots_pos[i], len(orig_file_paths))) for orig_file_path in orig_file_paths: orig_type = os.path.splitext(orig_file_path)[-1].lower() if not orig_type in type_list: continue if orig_file_path.replace(orig_type, '.png') not in seg_file_paths: print('%s image has no seg.' % orig_file_path) continue images_files.append(os.path.join(orig_roots_pos[i], orig_file_path)) labels_files.append(os.path.join(seg_roots_pos[i], orig_file_path.replace(orig_type, '.png')))
在 Python 中,
len()
函数用于获取数据结构(例如字符串、列表、元组、字典等)的长度或元素个数。
在 Python 中,
for
循环结构通常与range()
函数一起使用。range()
函数用于生成一个整数序列,可以在for
循环中进行迭代。
range()
函数有三种常见的用法:
range(stop)
:生成从 0 到stop-1
的整数序列。range(start, stop)
:生成从start
到stop-1
的整数序列。range(start, stop, step)
:生成从start
到stop-1
的整数序列,并指定步长为step
。
os.listdir() 函数返回一个列表,其中包含指定路径下的所有文件和文件夹的名称。因此,输出的数据类型是一个列表(list)。
在 Python 中,列表是一种有序的可变数据类型,可以包含多个元素,并且可以根据需要进行修改。列表用方括号 [ ] 表示,其中的元素通过逗号 , 分隔。
os.listdir(path)
是一个用于获取指定路径下所有文件和文件夹的函数。它返回一个包含指定路径下所有项的列表,其中每个项表示一个文件或文件夹的名称。
path
参数是一个字符串,表示要获取列表的路径。可以是相对路径或绝对路径。如果未提供路径参数,则默认为当前工作目录。返回的列表包含路径下所有的文件和文件夹的名称,但不包括子文件夹中的内容。如果需要获取子文件夹中的项,可以进一步遍历子文件夹并调用
os.listdir()
。
使用
os.path.splitext(filename)[-1].lower()
来获取文件的扩展名:
os.path.splitext(filename)
函数将给定的文件名filename
分割为文件名和扩展名的元组。返回的元组包含两个元素,第一个元素是文件名(不包含扩展名),第二个元素是扩展名。
[-1]
索引表示获取元组的最后一个元素,即扩展名部分。
.lower()
方法用于将扩展名转换为小写字母,以便进行不区分大小写的比较和处理。
import os
filename = "example.txt"
extension = os.path.splitext(filename)[-1].lower()
print(extension) # 输出:.txtfilename = "image.JPG"
extension = os.path.splitext(filename)[-1].lower()
print(extension) # 输出:.jpg
type_list = ['.bmp', '.jpg', '.png']
for orig_file_path in orig_file_paths:
orig_type = os.path.splitext(orig_file_path)[-1].lower()
if not orig_type in type_list:
continue
# 在这里处理满足条件的文件
# 其他操作...
这段代码判断变量
orig_type
是否存在于列表type_list
中,如果不存在,则执行continue
跳过当前循环迭代,进入下一次循环。具体来说,代码使用
not orig_type in type_list
条件来检查orig_type
是否不在type_list
列表中。如果条件为真(即orig_type
不在type_list
中),则执行continue
跳过当前循环迭代。这段代码的作用是过滤掉不在
type_list
中的文件扩展名,只处理在列表中定义的文件类型。
在 Python 中,
continue
是一个控制流语句,用于跳过当前循环迭代的剩余部分,并继续进行下一次迭代。
continue
语句通常与循环语句(如for
、while
)配合使用。当
continue
语句被执行时,程序将立即跳过当前循环迭代的剩余部分,并开始下一次迭代。
filename.replace('.bmp', '.png')
是一个字符串方法调用,用于将字符串中的子字符串'.bmp'
替换为'.png'
。具体来说,
replace()
方法用于在字符串中找到指定的子字符串,并将其替换为新的字符串。它返回一个新的字符串,原始字符串不会被修改。
filename = 'image.bmp'
new_filename = filename.replace('.bmp', '.png')
print(new_filename) # 输出:image.png
将子字符串
'.bmp'
替换为'.png'
,并将结果存储在new_filename
变量中。最后,我们打印new_filename
,得到替换后的新字符串'image.png'
。需要注意的是,
replace()
方法执行的是完全匹配替换。如果要替换的子字符串在原始字符串中多次出现,所有匹配的子字符串都会被替换。
如果希望只替换第一次出现的子字符串,可以使用可选的
count
参数。例如,
filename.replace('bmp', '.png', 1)
将只替换第一个匹配的'bmp'
子字符串为'.png'
。在下面示例中,只有第一个
'bmp'
被替换为'.png'
,而其他的'bmp'
保持不变。输出结果为'image1.png, image2.bmp, image3.bmp'
。
filename = 'image1.bmp, image2.bmp, image3.bmp'
new_filename = filename.replace('bmp', '.png', 1)
print(new_filename) # 输出:image1.png, image2.bmp, image3.bmp
os.path.join()
是一个用于构建文件路径的函数,它接受多个字符串参数,并根据当前操作系统的规范将它们连接起来形成一个有效的路径。具体来说,
os.path.join()
方法会根据操作系统的规范使用适当的路径分隔符(例如,反斜杠\
在Windows上,正斜杠/
在Unix/Linux上)将给定的字符串参数连接起来,形成一个路径字符串。使用
os.path.join()
方法可以确保在不同操作系统上构建的路径具有正确的格式,而无需手动处理路径分隔符的差异。
os.path.join()
方法可以接受任意数量的参数,并将它们依次连接起来。无论是文件夹路径还是文件名,都可以作为参数传递给os.path.join()
。输出的是一个字符串
list.append()
是一个列表方法,用于在列表的末尾添加一个元素。具体来说,
append()
方法用于将给定的元素添加到列表的末尾,修改了原始列表,并且不会返回任何值。在 Python 中,
append()
方法主要用于列表(list
)对象,用于在列表的末尾添加元素。需要注意的是,大多数其他类型的对象(如字符串、元组、字典等)没有
append()
方法,因为它们是不可变的,无法在现有对象中直接添加元素。对于这些类型的对象,需要使用其他适当的方法或操作来实现所需的功能。
对于不可变的对象(如字符串、元组和字典),确实没有
append()
方法,因为它们是不可变的,无法直接在现有对象中添加元素。对于不可变的对象,要实现类似于
append()
的功能,您需要使用其他方法或操作。对于字符串(
str
)和元组(tuple
),您可以通过连接操作符(+
)创建一个新的对象,将原始对象和要添加的元素组合在一起。这样可以创建一个新的字符串或元组,而不会修改原始对象。
my_string = 'Hello'
new_string = my_string + ' World'
print(new_string) # 输出:Hello Worldmy_tuple = (1, 2, 3)
new_tuple = my_tuple + (4,)
print(new_tuple) # 输出:(1, 2, 3, 4)
对于字典(
dict
),您可以使用索引操作符([]
)来添加新的键值对。通过将新的键值对分配给字典中不存在的键,可以在字典中添加新的元素。
my_dict = {'key1': 'value1'}
my_dict['key2'] = 'value2'
print(my_dict) # 输出:{'key1': 'value1', 'key2': 'value2'}
my_dict = {'key1': 'value1'}
my_dict['key2'] = 'value2'
print(my_dict) # 输出:{'key1': 'value1', 'key2': 'value2'}
需要注意的是,上述操作都是创建新的对象,而不是在原始对象上进行修改。这是因为字符串、元组和字典是不可变的,无法直接更改其内容。如果您需要在原始对象上进行修改,可能需要考虑使用其他可变的数据结构,如列表(
list
)或集合(set
),它们提供了更多的修改操作方法。
assert
, 其中:
是一个布尔表达式,用于判断是否满足某个条件。
是一个字符串,用于在断言失败时提供错误提示信息。
在condition为 false时输出error_message
列表切片是一种通过指定索引范围来获取列表中的子列表的操作。它允许您从原始列表中选择特定的元素子集,并返回一个新的列表。
切片操作的一般形式是
list[start:end:step]
,其中:
start
是切片的起始索引(包含在切片结果中)。end
是切片的结束索引(不包含在切片结果中)。step
是切片的步长(可选参数,默认为1)。
在Python中,常用的图片数据类型有以下几种:
NumPy 数组:NumPy 是Python中用于科学计算的重要库,它提供了多维数组对象 ndarray。在图像处理中,常用的表示图像的数据类型是三维的数组,分别表示图像的高度、宽度和通道数(如 RGB 图像的三个颜色通道)。使用NumPy数组,可以方便地对图像进行处理和操作。
OpenCV 中的 Mat:OpenCV 是一个强大的计算机视觉库,它提供了许多图像处理和计算机视觉算法。OpenCV 使用自己的 Mat 类型来表示图像数据,它是一个多维数组,类似于NumPy数组。Mat 类型在OpenCV中广泛使用,并且提供了许多图像处理和分析的函数。
PyTorch 或 TensorFlow 中的 Tensor:PyTorch 和 TensorFlow 是深度学习框架,它们提供了张量(Tensor)作为主要的数据结构。张量是高维数组,类似于NumPy数组,但具有额外的功能,如自动求导和GPU加速。在深度学习中,图像通常表示为张量,可以在模型中进行处理和传递。
这些数据类型在图像处理和深度学习中具有广泛的应用,可以根据具体的需求和使用的库选择适合的数据类型。在处理图像数据时,常用的做法是将图像从文件加载为NumPy数组或OpenCV的Mat对象,然后根据需要将其转换为张量类型进行深度学习模型的训练和推理。
np.fromfile()
是 NumPy 库中的一个函数,用于从文件中读取数据并返回一个 NumPy 数组。np.fromfile(file, dtype=float, count=-1, sep='')
参数说明如下:
file
:要读取数据的文件名或文件对象。dtype
:所读取数据的类型,默认为float
。可以是任何有效的 NumPy 数据类型。count
:要读取的数据元素个数,默认为 -1,表示读取整个文件。sep
:数据元素之间的分隔符,默认为空字符串。
np.fromfile()
函数将文件中的数据按照指定的数据类型和格式读取到一个 NumPy 数组中,并返回该数组。请注意,在使用
np.fromfile()
函数时,需要确保文件中的数据与指定的数据类型和格式相匹配,否则读取的结果可能会不正确。
np.fromfile(img_path[i], dtype=np.uint8)使用 NumPy 库中的
fromfile
函数从文件中读取数据,并将其解释为无符号8位整数(dtype=np.uint8
)的NumPy数组。具体来说,
img_path[i]
是文件的路径,dtype=np.uint8
指定数据类型为无符号8位整数,即每个像素值在范围0到255之间。该代码将读取指定路径的文件,并将文件中的数据按照无符号8位整数的格式解释为NumPy数组。这在图像处理中常用于读取图像文件的像素数据,并进行后续的操作和分析。
cv2.imdecode()
函数是 OpenCV 库中用于解码图像的函数。cv2.imdecode(buf, flags)
buf
是一个包含图像数据的缓冲区,可以是一个字节数组、字节字符串或类似对象。flags
是解码标志,用于指定解码图像的颜色通道和解码方式。
buf
是一个包含图像数据的缓冲区,可以是一个字节数组、字节字符串或类似对象。这个参数接受原始的图像数据,通常是通过读取图像文件或网络传输获取的字节数据。
flags
是解码标志,用于指定解码图像的颜色通道和解码方式。它控制了如何解析图像数据并构建图像对象。常见的解码标志包括:
cv2.IMREAD_COLOR
:将图像以BGR颜色模式读取,默认值。cv2.IMREAD_GRAYSCALE
:将图像以灰度模式读取。cv2.IMREAD_UNCHANGED
:保持图像的原始通道和深度。可以使用这些标志中的一个或者按位或运算符
|
组合多个标志。
cv2.imdecode(image_data, -1)
和cv2.imdecode(image_data, cv2.IMREAD_UNCHANGED)
是等价的,都表示保持原始图像的通道数和深度不变。
字节数据是指由字节(8位)组成的二进制数据。在计算机中,所有的数据都以字节的形式存储和处理。字节数据可以表示各种信息,包括图像、音频、文本、文件等。
字节类型是指数据的存储类型,其中每个元素占用一个字节的内存空间,可以表示范围为 0 到 255 的整数值。在Python中,字节类型可以使用 np.uint8 来表示,其中 np 是引入的NumPy库的别名。
cv2.imdecode(np.fromfile(img_path[i], dtype=np.uint8), -1)
使用了
cv2.imdecode()
函数来解码图像数据。在这个代码中,
np.fromfile(img_path[i], dtype=np.uint8)
是使用 NumPy 的np.fromfile()
函数读取图像文件的内容,并将其作为字节数据转换为 NumPy 数组。img_path[i]
是图像文件的路径,dtype=np.uint8
指定了数组的数据类型为无符号8位整数(即字节类型)。然后,将这个读取的图像数据作为第一个参数传递给
cv2.imdecode()
函数,而-1
则是解码标志,表示保持原始图像的通道数和深度不变。这样的代码可以用于读取图像文件的内容,并使用 OpenCV 的
cv2.imdecode()
函数解码图像数据,返回解码后的图像对象供后续处理和分析使用。
在计算机视觉领域中,OpenCV 是一个常用的库,用于图像处理和计算机视觉任务。在 OpenCV 中,图像数据通常以
numpy.ndarray
对象的形式表示,作为主要的图像数据类型。这个numpy.ndarray
对象存储了图像的像素值和其他相关信息。
numpy.ndarray 对象与numpy的区别
numpy.ndarray
对象实际上是 NumPy 库的核心概念之一,没有明确的区别。以
NumPy:NumPy 是一个开源的 Python 扩展库,用于高性能科学计算和数据操作。它引入了一个新的数据结构,即多维数组(ndarray),以及一套用于操作这些数组的函数和方法。NumPy 提供了一些基础的数学、逻辑和统计运算,以及支持广播(broadcasting)和矢量化操作的功能。
numpy.ndarray
:numpy.ndarray
是 NumPy 库中用于表示多维数组的对象类型。它是一个具有相同数据类型和固定维度的多维数组,可以包含任意类型的元素。ndarray
对象提供了广泛的数学和逻辑操作,以及高效的内存管理和计算性能。它是 NumPy 库中最基本和核心的数据结构。因此,可以说
numpy.ndarray
是 NumPy 库中用于表示多维数组的对象类型,它是 NumPy 库的核心之一。通过使用ndarray
对象,可以进行高效的数值计算、数组操作和数据处理任务。
numpy.ndarray.shape
是一个属性,用于获取 NumPy 数组的维度信息,返回一个元组,其中包含数组在各个维度上的大小。在 Python 中,元组的元素可以通过索引来进行读取。元组的索引从 0 开始,表示元素在元组中的位置。可以使用方括号
[]
运算符来访问特定索引处的元素。元组是不可变的(immutable)对象,这意味着不能修改元组中的元素。如果尝试修改元组中的元素,将会引发 TypeError 错误。
总结来说,可以使用索引来读取元组中特定位置的元素,索引从 0 开始。通过方括号运算符和切片操作,可以读取单个或多个元素。
my_tuple = ('a', 'b', 'c', 'd', 'e')
# 通过索引读取元组的元素
print(my_tuple[0]) # 输出: 'a'
print(my_tuple[2]) # 输出: 'c'
print(my_tuple[-1]) # 输出: 'e'(使用负索引从末尾开始读取)# 使用切片操作读取多个元素
print(my_tuple[1:4]) # 输出: ('b', 'c', 'd')(索引 1 到 3 的元素)
print(my_tuple[:3]) # 输出: ('a', 'b', 'c')(前三个元素)
print(my_tuple[2:]) # 输出: ('c', 'd', 'e')(从索引 2 开始到最后的元素)
retval, threshold = cv2.threshold(src, thresh, maxval, type[, dst])
参数说明:
src
:输入图像,可以是灰度图像或彩色图像。thresh
:阈值,用于将像素值分为两个类别。maxval
:当像素值超过阈值时,所赋予的最大值。type
:阈值化的类型,用于指定阈值化的方法。dst
(可选):输出图像,与输入图像具有相同的大小和类型。函数返回值:
retval
:计算得到的阈值。threshold
:阈值化后的图像。具体的阈值化方法由
type
参数指定,常用的阈值化方法包括:
cv2.THRESH_BINARY
:超过阈值的像素设为maxval
,低于阈值的像素设为0。cv2.THRESH_BINARY_INV
:与cv2.THRESH_BINARY
相反,超过阈值的像素设为0,低于阈值的像素设为maxval
。cv2.THRESH_TRUNC
:超过阈值的像素设为阈值,低于阈值的像素保持不变。cv2.THRESH_TOZERO
:低于阈值的像素设为0,超过阈值的像素保持不变。cv2.THRESH_TOZERO_INV
:与cv2.THRESH_TOZERO
相反,低于阈值的像素保持不变,超过阈值的像素设为0。使用
cv2.threshold()
函数可以方便地进行全局阈值化处理,根据不同的阈值化方法和阈值选取,可以实现图像的二值化、灰度级压缩等效果。