一、标定工具

在进行分割任务时,对分割工具进行预研和验证,现在AI辅助标定已经成熟,目标则是利用sam进行辅助标定。调研的三款标定工具情况如下:

  1. labelme:可以加载sam,但是在进行辅助标定后,对图像质量要求较高,真心不好用。主要体现在辅助标定后,无法调整。
  2. cvat:本地部署手工标注成功了,但在部署辅助标定时,按照教程各种失败,最后放弃了。从宣传效果上看起来挺好用,尤其团队能工作分工合作。
  3. x-Anylabeling:部署简单,在Windows有执行程序,当然还支持加载自己的模型(此处需要源码安装)。在加载sam模型后,通过point+/point-等操作能细化调整标定框,真心好用。后续直接用anylabeling进行标注了。

另外在通用检测模型中,尝试了大部分模型有较大优化空间,当然希望集成按照label进行目标标定,而不是点击“run”后所有目标都进行标定。当然自己后续可以通过脚本处理也是没有问题的。

二、标定json文件转化为maskID

在训练时使用的时mmsegmention,模型输入是原始图片和maskID,为此需要将标定后的json文件转化为maskID。anylabeling是参考labelme的输出格式相同,当然在anylabeling中有脚本为:polygon_mask_conversion.py,其中的核心代码为:

    def polygon_to_mask(self, img_file, mask_file, json_file):

        with open(json_file, 'r') as f:
data = json.load(f)
polygons = []
for shape in data['shapes']:
points = shape['points']
polygon = []
for point in points:
x, y = point
polygon.append((x, y))
polygons.append(polygon) image_width, image_height = self.get_image_size(img_file)
image_shape = (image_height, image_width)
binary_mask = np.zeros(image_shape, dtype=np.uint8)
for polygon_points in polygons:
np_polygon = np.array(polygon_points, np.int32)
np_polygon = np_polygon.reshape((-1, 1, 2))
#只是将区域内设置为255
cv2.fillPoly(binary_mask, [np_polygon], color=255)
cv2.imwrite(mask_file, binary_mask)

里面只是将poly区域内设置为255,则效果图为:

则不符合要求。

答案代码如下:

def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument("input_dir", help="input annotated directory")
parser.add_argument("output_dir", help="output dataset directory")
args = parser.parse_args() if not osp.exists(args.output_dir):
os.makedirs(args.output_dir) file_list = [i for i in os.listdir(args.input_dir) if i.endswith("json")]
for file in file_list:
file_name = os.path.join(args.input_dir, file)
json_data = json.load(open(file_name))
height, width = json_data["imageHeight"], json_data["imageWidth"]
#核心代码是labelme实现的,直接调用即可
lbl, lbl_names = utils.shape.labelme_shapes_to_label([height, width], json_data['shapes'])
out_file = osp.join(args.output_dir, '{}.png'.format(os.path.basename(file)))
lbl_pil = Image.fromarray(lbl.astype(np.uint8), mode="P")
lbl_pil.save(out_file)
# utils.lblsave(out_file, lbl)
print('Saved to: %s' % out_file)

核心代码可以去labelme寻找答案。在保存后,效果图如下:

因为数值是1,2,3所以全是黑色,此时要实现将像素值打印在图片上。

三、像素值打印在图片上

在打印上如果每个像素都打上数字,因为像素位置挨着近,数字小,则无法看出,此时需要进行临近区域处理,具体的代码为:

def check_mask():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument("input_dir", help="input annotated directory")
args = parser.parse_args()
file_list = [i for i in os.listdir(args.input_dir) if i.endswith("png")]
file_name = os.path.join(args.input_dir, file_list[0])
image = Image.open(file_name)
image = image.convert("RGB") # 获取图片的像素数据
pixels = list(image.getdata()) # 创建一个可以在图像上绘制文本的对象
draw = ImageDraw.Draw(image) # 设置字体和字体大小
font = ImageFont.truetype("arial.ttf", size=12) # 这里使用了Arial字体,你可以替换为其他字体 # 设置绘制像素值的间隔(每隔多少个像素绘制一次)
interval = 10 # 合并像素值的范围(以此范围内的像素值取平均值并绘制)
merge_range = 5 # 在图像上绘制像素值
for y in range(image.height):
for x in range(image.width):
if x % interval == 0 and y % interval == 0:
# 计算合并范围内像素的平均值
total= 0
count = 0
for i in range(-merge_range, merge_range + 1):
for j in range(-merge_range, merge_range + 1):
nx, ny = x + i, y + j
if 0 <= nx < image.width and 0 <= ny < image.height:
pixel = pixels[ny * image.width + nx]
total += pixel[0]
count += 1 # 计算平均值
if count > 0:
avg = total // count
if avg == 0:
continue
pixel_str = str(avg) # 格式化平均像素值
draw.text((x, y), pixel_str, fill=(255, 0, 0), font=font) # 在图像上绘制文本,使用黑色文本颜色 output_path = "output_image.jpg" # 保存的图片路径
image.save(output_path, "JPEG")

效果图如下:

如此便将像素值打印在图片上了。

四、总结

在maskID中,如果调用

utils.lblsave(out_file, lbl)

里面的核心代码是:

def lblsave(filename, lbl):
import imgviz if osp.splitext(filename)[1] != ".png":
filename += ".png"
# Assume label ranses [-1, 254] for int32,
# and [0, 255] for uint8 as VOC.
if lbl.min() >= -1 and lbl.max() < 255:
lbl_pil = PIL.Image.fromarray(lbl.astype(np.uint8), mode="P")
#增加了此处代码
colormap = imgviz.label_colormap()
lbl_pil.putpalette(colormap.flatten())
lbl_pil.save(filename)
else:
raise ValueError(
"[%s] Cannot save the pixel-wise class label as PNG. "
"Please consider using the .npy format." % filename
)

其结果为:

此时将像素打印在图片上结果是:

AnyLabeling标定及转化成labelmaskID的更多相关文章

  1. [zt]摄像机标定(Camera calibration)笔记

    http://www.cnblogs.com/mfryf/archive/2012/03/31/2426324.html 一 作用建立3D到2D的映射关系,一旦标定后,对于一个摄像机内部参数K(光心焦 ...

  2. 直接线性变换解法(DLT)用于标定相机

    直接线性变换法是建立像点坐标和相应物点物方空间坐标之间直接的线性关系的算法.特点:不需要内外方位元素:适合于非量测相机:满足中.低精度的测量任务:可以标定单个相机. 1 各坐标系之间的关系推导直接线性 ...

  3. PPT转化成Image、PPTX、XPS、EMF

    最近工作经常用到演示文稿,接触到了一款不错的免费软件—Free Spire.Presentation.使用之后发现这款软件非常轻巧,功能还挺齐全.这款软件的转化功能也是非常不错的,平时遇到的各种转换难 ...

  4. DSO之光度标定

    光度标定(Photometric Camera Calibration)是DSO(Direct Sparse Odometry)论文中比较特别的一部分.常规的vSLAM不太考虑光度标定的问题.比如基于 ...

  5. 相机标定简介与MatLab相机标定工具箱的使用(未涉及原理公式推导)

    相机标定 一.相机标定的目的 确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,建立摄像机成像的几何模型,这些几何模型参数就是摄像机参数. 二.通用摄像机模型 世界坐标系.摄像机坐标 ...

  6. .net 将List序列化成Json字符串

    将List类型转化为Json,是我们平常开发时最常见的了.在使用中,有很多种方法,也可以使用. 第一种 第三方组件:Newtonsoft.Json.dll //转化成Json Newtonsoft.J ...

  7. LL谱面分析和难度标定

    LL谱面分析和难度标定 先介绍一下LL谱面的存储方式:TimeLine序列(简称TL序列),TL序列中的每一个元素(即音符)可以由一个C语言中的结构体来表示: struct note{ int lin ...

  8. [转]opencv3.0 鱼眼相机标定

    [原文转自]:http://blog.csdn.net/qq_15947787/article/details/51441031 前两天发表的时候没注意,代码出了点错误,所以修改了一下,重新发上来.  ...

  9. 机器人操作臂运动学入门一--D-H参数标定

    最近重新学习机器人方面的知识,想到一年以前在学校选修<机器人学技术基础>这门课的时候,老师虽然讲机器人的各个方面的知识都讲到了,但只是浮光绿影的的提到,并没有真正讲到深处,我的理解也没有更 ...

  10. 【图像】Matlab图像标定工具箱

    参考教程: Matlab工具箱教程  http://www.vision.caltech.edu/bouguetj/calib_doc/ 摄像机模型  http://oliver.zheng.blog ...

随机推荐

  1. awk 内置变量与自定义变量

    点击上方" 生信科技爱好者 ",马上关注 真爱,请置顶或星标 作者:ghostwu 原文:https://www.cnblogs.com/ghostwu/p/9085653.htm ...

  2. 小技巧 | 使用 mv 重命名文件无需两次键入文件名称

    使用过 Bash 的童鞋都知道 mv 是一个可以用于文件改名的命令,而且使用这个命令修改文件名时我们需要输入两次文件名(旧名字和新名字). 如果有一种情况是只需要你改动文件名中的一个字母,而文件名又特 ...

  3. Adobe 构建 IDP 之路的经验与教训

    在过去的25年多时间里,我创建了软件组件和分布式框架,建立并领导了相关团队.近几年我致力于推动 Adobe 服务开发.部署和管理系统的开发人员生产力. 抽象陷阱 在云时代早期,Adobe 的每个团队都 ...

  4. WPF中控件转命令

    WPF不是所有控件都有Command属性,如果窗体需要在ViewModel 使用System.Windows.Interactivity事件 在nuget浏览搜索 下载System.Windows.I ...

  5. 【建议收藏】Log4j配置详解

    大家在日常开发中必然会使用到日志组件,Log4j是Java方向上比较常用的日志组件,今天给大家分享下Log4j支持的配置项,强烈建议收藏,以便配置时查看 #展示log4j各种配置,私有部分见文件中注释 ...

  6. Git使用教程(带你玩转GitHub)

    Git使用教程(理论实体结合体系版) 下载安装: 按照这个博客来就好 Windows系统Git安装教程(详解Git安装过程) - 学为所用 - 博客园 (cnblogs.com) Git命令大全: G ...

  7. 使用Stable Diffusion生成艺术二维码

    在数字艺术的世界中,二维码已经从单纯的信息承载工具转变为可以展示艺术表达的媒介.这是通过使用Stable Diffusion的技术实现的,它可以将任何二维码转化为独特的艺术作品.接下来,我们将一步步教 ...

  8. [最长回文字符串]manacher马拉车

    manacher马拉车 https://www.luogu.com.cn/problem/P3805 闲言一下:花了一个中午终于把 manacher 给搞懂了.本文将以一个蒟蒻的身份来,来写写马拉车算 ...

  9. 利用shell脚本交互式运行jar任务

    如题,废话不多说,直接上代码: #!/bin/bash APP_PATH=/root/bigdata/neural_networks/width_control_model/predict/uploa ...

  10. Ubuntu18.04 软件源更新:图形界面

    通过图形UI界面更新Ubuntu的软件源,手动修改虽然简单,但是要自己去找源,选一个系统配置好的更简单.但是新版的好像没有该功能,找到个奇葩的路径: 将Ubuntu16.04升级为Ubuntu18.0 ...