代码
import os, json, numpy as np
from tqdm import tqdm
from imantics import Mask, Image, Category, Dataset
import cv2
dataset = Dataset('windmill') # 先定义一个数据库对象,后续需要往里面添加具体的image和annotation
path1 = r'E:\windmillvideo\images' # image对应的mask的文件路径
path =r'E:\windmillvideo\mask'
for index, i in enumerate(tqdm(os.listdir(path))):
mask_file = os.path.join(path, i)
name = i.split('.')[0]
name = name.split('_')[1]
file = os.path.join(path1, '{}.jpg'.format(name))
image = cv2.imread(file)[:, :, ::-1]
image = Image(image, id=index + 1) # 定义一个Image对象
image.file_name = '{}.jpg'.format(name) # 为上面的Image对象添加coco标签格式的'file_name'属性
image.path = file # 为Image对象添加coco标签格式的'path'属性
mask = cv2.imread(mask_file, 0)
ret, mask = cv2.threshold(mask, 30, 255, cv2.THRESH_BINARY)
t = cv2.imread(file)
if t.shape[:-1] != mask.shape:
h, w, _ = t.shape
mask = cv2.resize(mask, (w, h), cv2.INTER_CUBIC)
mask = Mask(mask) # 定义一个Mask对象,并传入上面所定义的image对应的mask数组
categ = 'windmill'
t = Category(categ) # 这里是定义Category对象
t.id = 1
image.add(mask, t) # 将mask信息和类别信息传给image
dataset.add(image) # 往dataset里添加图像以及gt信息
t = dataset.coco() # 将dataset转化为coco格式的,还可以转化为yolo等格式
with open(r'E:\windmillvideo\windmill.json', 'w') as output_json_file: # 最后输出为json数据
json.dump(t, output_json_file)
知识点详解
一
-
os.listdir(path)
:从指定路径中获取文件和文件夹的列表。这是来自Python的os模块的函数。
-
enumerate(iterable, start=0)
:从可迭代对象中获取元素以及对应的索引。它返回一个枚举对象,每个元素都是一个元组,包含索引和对应的元素。在这段代码中,我们将os.listdir(path)
的结果作为可迭代对象传递给enumerate()
函数。
-
tqdm()
:在命令行界面中创建进度条。这是一个第三方库,可以用来在循环中显示进度条,以便显示任务的进行情况。
-
for index, i in enumerate(tqdm(os.listdir(path))):
:这是一个for
循环,它使用了上述提到的enumerate()
和tqdm()
函数。循环迭代os.listdir(path)
的结果,并将每个元素及其索引分配给index
和i
变量。
二
-
mask_file = os.path.join(path, i)
:将文件名 i
与目录 path
进行连接,得到完整的路径名 mask_file
。
-
name = i.split('.')[0]
:通过使用 split
函数以点号 .
为分隔符,将文件名 i
分割为多个部分,并选择索引为 0
的部分作为名字 name
。
-
name = name.split('_')[1]
:通过使用 split
函数以下划线 _
为分隔符,将名字 name
分割为多个部分,并选择索引为 1
的部分作为新的名字 name
。
-
file = os.path.join(path1, '{}.jpg'.format(name))
:将目录 path1
与 name
拼接起来,形成最终的图像文件路径名 file
。
-
image = cv2.imread(file)[:, :, ::-1]
:使用OpenCV库的imread
函数读取文件 file
,并将通道顺序从BGR转换为RGB格式。
-
image = Image(image, id=index + 1)
:创建一个Image对象,其中包含图像数据和一个唯一的ID index + 1
。
-
image.file_name = '{}.jpg'.format(name)
:为Image对象添加一个名为file_name
的属性,表示文件名。
-
image.path = file
:为Image对象添加一个名为path
的属性,表示文件的完整路径。
-
mask = cv2.imread(mask_file, 0)
:使用OpenCV库的imread
函数读取mask_file
的灰度图像。
-
ret, mask = cv2.threshold(mask, 30, 255, cv2.THRESH_BINARY)
:使用OpenCV库的threshold
函数,将灰度图像二值化,将低于阈值30的像素值设为0,高于阈值的像素值设为255。
-
t = cv2.imread(file)
:再次使用OpenCV库的imread
函数读取图像文件file
,并将其存储在t
变量中。
三
-
if t.shape[:-1] != mask.shape:
:检查变量 t
(图像数据)的形状的前两个维度(高度和宽度)是否与 mask
(mask数据)的形状相同。如果不相同,则执行下一行的代码。
-
h, w, _ = t.shape
:从变量 t
的形状中获取高度和宽度。下划线 _
用于省略未使用的维度。
-
mask = cv2.resize(mask, (w, h), cv2.INTER_CUBIC)
:使用OpenCV库的resize
函数,将 mask
调整为与 t
相同的高度和宽度。使用INTER_CUBIC
插值方法进行图像的缩放。
-
mask = Mask(mask)
:创建一个Mask对象,将之前处理过的 mask
传递给该对象。
-
categ = 'windmill'
:指定类别名为 'windmill'。
-
t = Category(categ)
:创建一个Category对象,并将类别名 'windmill' 传递给该对象。
-
t.id = 1
:为Category对象设置一个唯一的ID,此处为1。
-
image.add(mask, t)
:将之前创建的Mask对象和Category对象作为参数,添加到之前定义的Image对象中,即将mask信息和类别信息与图像关联起来。
-
dataset.add(image)
:将之前定义的Image对象添加到Dataset中,即将图像和相关的ground truth信息添加到数据集中。