【工業機器視覺】基于深度學習的水表盤讀數識別(3-數據標注與轉換)

【工業機器視覺】基于深度學習的儀表盤識讀(2)-CSDN博客

數據標注

標注擴展

Labelme 和 LabelImg 都是用于創建機器學習和計算機視覺項目所需標注數據的工具。它們都允許用戶通過圖形界面手動標注圖像,但各自有其特點和適用場景。

Labelme

  • 開發語言:Python
  • 標注類型:Labelme 支持多種標注類型,包括但不限于多邊形(polygon)、矩形(rectangle)、線段(line)、點(point)等。它非常適合需要精確標注物體邊界的情況,比如在醫療影像、自動駕駛等領域。
  • 文件格式:標注結果通常保存為 JSON 文件,其中包含每個標注對象的坐標信息、標簽名稱等。
  • 靈活性:Labelme 提供了插件系統,可以擴展其功能,如支持更多的圖像格式或添加自定義的標注類型。
  • 跨平臺:基于 Python 的 Qt 庫構建,可以在 Windows、macOS 和 Linux 上運行。

LabelImg

  • 開發語言:Python
  • 標注類型:主要支持矩形框(bounding box)標注,適合于目標檢測任務。對于需要簡單快速地對多個對象進行框選標注的任務來說非常方便。
  • 文件格式:標注結果可以保存為 Pascal VOC XML 格式或者 YOLO txt 格式,這兩種格式都是目標檢測任務中常用的標注文件格式。
  • 輕量化:相比于 Labelme,LabelImg 更加輕量化,易于安裝和使用,尤其適合初學者。
  • 跨平臺:同樣基于 Python 的 Qt 庫,可以在不同操作系統上運行。

安裝擴展包:

pip install labelme labelimg

指針區域

使用labelimg進行BOX標注,標簽類別:{'area_p', 'p0', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9'},p0~p9為最低位x0.001標簽類別,area_p為其他高位指針區域標簽類別。

示例:

標簽文件是VOC XML文件數據,后面再通過腳本轉換成YOLO格式數據。

梅花針分割

使用labelme進行實例切割,標簽類別:{'pointer', 'circle_area'},pointer是紅色梅花針區域,circel_area是刻度圓。

示例:

標簽文件是JSON格式文件數據,后面再通過腳本轉換成YOLO格式數據。

字輪區域

使用labelimg進行BOX標注,標簽類別:{'d0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', ?'d10', 'd11', 'd12', 'd13', 'd14', 'd15', 'd16', 'd17', 'd18', 'd19'},d0~9表示數字剛好在字輪窗口中心位置,也就是非過渡狀態,d10~19表示各個數字的過渡狀態。

示例:

標簽文件是VOC XML文件數據,后面再通過腳本轉換成YOLO格式數據。

數據劃分

在深度學習中,訓練集和驗證集是用于模型開發過程中的兩個重要數據集。它們各自扮演著不同的角色,確保最終模型的性能和泛化能力。

訓練集(Training Set)

  • 用途:訓練集主要用于訓練模型。即,在這個數據集上調整模型的權重或參數,使模型能夠學習到數據中的特征和模式。
  • 特點:通常包含大量帶標簽的數據樣本,這些數據樣本應該盡可能地代表實際應用環境中的數據分布。
  • 影響:如果訓練集的質量不高(如數據量不足、標注不準確或偏差),可能會導致模型過擬合或欠擬合,從而影響其性能。

驗證集(Validation Set)

  • 用途:驗證集用于在訓練過程中評估模型的表現,幫助選擇模型的最佳配置(例如,超參數調優)。它提供了一個獨立于訓練集的反饋機制,用以監測模型是否開始過擬合訓練數據。
  • 特點:與訓練集類似,驗證集也應該是有代表性的,并且它的標簽也是已知的。但是,它不應該被用來直接更新模型參數;相反,它是用來決定何時停止訓練(早停法)或選擇最佳模型架構/超參數。
  • 影響:通過驗證集可以有效防止過擬合,確保模型不僅在訓練數據上表現良好,而且在未見過的數據上也能保持良好的性能。

注意事項

  • 劃分比例:常見的是將數據劃分為70%訓練集和30%驗證集,或者采用交叉驗證的方法來更充分利用有限的數據。具體的比例可以根據實際情況調整
  • 測試集:除了訓練集和驗證集之外,有時還會有一個測試集(Test Set),用于最終評估模型的真實性能。測試集在整個訓練和驗證過程中都應該保持完全獨立,直到最后評估時才使用。

正確管理和使用訓練集和驗證集對于構建一個有效的深度學習模型至關重要。這有助于確保模型不僅能很好地適應訓練數據,還能對新數據做出準確預測。

數據劃分代碼:

import argparse
import os
import random
from os import getcwd# root = getcwd() + '\\my_datas\\pointer-seg\\'
root = getcwd() + '\\my_datas\\detect-pointer\\'
# root = getcwd() + '\\my_datas\\detect-digit\\'
parser = argparse.ArgumentParser()parser.add_argument('--img_path', default='IMAGES', type=str,help='input images file path')
parser.add_argument('--txt_path', default='TXT_LABELS', type=str,help='output txt label path')
opt = parser.parse_args()trainval_percent = 1.0
train_percent = 0.9
imgfilepath = root + opt.img_path
txtsavepath = root + opt.txt_path
total_img = os.listdir(imgfilepath)
if not os.path.exists(txtsavepath):os.makedirs(txtsavepath)num = len(total_img)
list_index = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)try:os.remove(txtsavepath + '/trainval.txt')os.remove(txtsavepath + '/train.txt')os.remove(txtsavepath + '/valid.txt')
except:pass
file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/valid.txt', 'w')for i in list_index:name = total_img[i] + '\n'if i in trainval:file_trainval.write(imgfilepath + '/' + name)if i in train:file_train.write(imgfilepath + '/' + name)else:file_val.write(imgfilepath + '/' + name)file_trainval.close()
file_train.close()
file_val.close()

IMAGES為所有需要學習的數據圖片目錄?

數據轉換

VOC XML 轉 YOLO

import os
import shutil
import xml.etree.ElementTree as ET
from tqdm import tqdmsets = ['train', 'valid']
project_name = 'detect-pointer'
classes = ['area_p', 'p0', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9']
# project_name = 'detect-digit'
# classes = ['d0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9',
#            'd10', 'd11', 'd12', 'd13', 'd14', 'd15', 'd16', 'd17', 'd18', 'd19']abs_path = os.getcwd()def convert(size, box):dw = 1. / (size[0])dh = 1. / (size[1])x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn x, y, w, hdef convert_annotation(image_id, image_set):in_file = open(r'my_datas\%s\ANNOTATIONS\%s.xml' % (project_name, image_id), encoding='UTF-8')out_file = open(r'my_datas\%s\%s\labels\%s.txt' % (project_name, image_set, image_id), 'w')tree = ET.parse(in_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):difficult = obj.find('difficult').textcls = obj.find('name').textif cls not in classes or int(difficult) == 1:continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))b1, b2, b3, b4 = b# 標注越界修正if b2 > w:b2 = wif b4 > h:b4 = hb = (b1, b2, b3, b4)bb = convert((w, h), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')# 刪除文件夾中所有文件
def del_all_file(path):for root, dirs, files in os.walk(path):for f in files:os.remove(os.path.join(root, f))del_all_file(f'my_datas\\{project_name}\\train\images')
print('train\images delete success.')
del_all_file(f'my_datas\\{project_name}\\train\labels')
print('train\labels delete success.')
del_all_file(f'my_datas\\{project_name}\\valid\images')
print('valid\images delete success.')
del_all_file(f'my_datas\\{project_name}\\valid\labels')
print('valid\labels delete success.')for image_set in sets:image_files = open(r'my_datas\%s\TXT_LABELS\%s.txt' % (project_name, image_set)).read().strip().split()for image_file in tqdm(image_files):image_id = os.path.basename(image_file)[:-4]convert_annotation(image_id, image_set)shutil.copyfile(image_file, r'my_datas\%s\%s\images\%s' % (project_name,image_set, os.path.basename(image_file)))

JSON 轉 YOLO

import json
import os
import shutil
from tqdm import tqdmimport numpy as npproject_name = 'pointer-seg'
sets = ['train', 'valid']
classes = ['pointer', 'circle_area']
abs_path = os.getcwd()def convert(size, box):dw = 1. / (size[0])dh = 1. / (size[1])x = (box[0] + box[1]) / 2.0 - 1y = (box[2] + box[3]) / 2.0 - 1w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn x, y, w, hdef pointer_distance(x1, y1, x2, y2):dis = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)return disdef json_to_yolo(path):with open(path, encoding='UTF-8') as f:labelme_data = json.load(f)width = labelme_data["imageWidth"]height = labelme_data["imageHeight"]yolo_lines = []for shape in labelme_data["shapes"]:if shape['shape_type'] == 'polygon':# 多邊形label = shape["label"]points = shape["points"]class_idx = classes.index(label)txt_string = f"{class_idx} "for x, y in points:x /= widthy /= heighttxt_string += f"{x} {y} "yolo_lines.append(txt_string.strip() + "\n")elif shape['shape_type'] == 'circle':# 圓label = shape["label"]points = shape["points"]class_idx = classes.index(label)txt_string = f"{class_idx} "# 圓心a, b = points[0]# 計算半徑r = pointer_distance(a, b, points[1][0], points[1][1])# 生成一些在圓上的點X = np.linspace(a - r, a + r - 1, 15)f = lambda x: np.sqrt(r ** 2 - (x - a) ** 2) + by1 = f(X)y2 = 2 * b - y1c_points = []for i, x in enumerate(X):c_points.append([x, y1[i]])c_points.append([x, y2[i]])for x, y in c_points:x /= widthy /= heighttxt_string += f"{x} {y} "yolo_lines.append(txt_string.strip() + "\n")return yolo_linesdef convert_annotation(image_id, image_set):lines = json_to_yolo(r'my_datas\%s\ANNOTATIONS\%s.json' % (project_name, image_id))with open(r'my_datas\%s\%s\labels\%s.txt' % (project_name, image_set, image_id), 'w') as out_file:out_file.writelines(lines)def del_all_file(path):for root, dirs, files in os.walk(path):for f in files:os.remove(os.path.join(root, f))del_all_file(f'my_datas\\{project_name}\\train\images')
print('train\images delete success.')
del_all_file(f'my_datas\\{project_name}\\train\labels')
print('train\labels delete success.')
del_all_file(f'my_datas\\{project_name}\\valid\images')
print('valid\images delete success.')
del_all_file(f'my_datas\\{project_name}\\valid\labels')
print('valid\labels delete success.')for image_set in sets:image_files = open(r'my_datas\%s\TXT_LABELS\%s.txt' % (project_name, image_set)).read().strip().split()for image_file in tqdm(image_files):image_id = os.path.basename(image_file)[:-4]convert_annotation(image_id, image_set)shutil.copyfile(image_file, r'my_datas\%s\%s\images\%s' % (project_name,image_set, os.path.basename(image_file)))

完整目錄結構:

至此,用于深度學習所需的所有訓練、驗證數據已準備好,下一篇開始基于Utralytics YOLO系列進行訓練和預測。

【工業機器視覺】基于深度學習的儀表盤識讀(讀數識別)(4)-CSDN博客

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62549.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62549.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62549.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

靜態路由與交換機配置實驗

1.建立網絡拓撲 添加2臺計算機,標簽名為PC0、PC1;添加2臺二層交換機2960,標簽名為S0、S1;添加2臺路由器2811,標簽名為R0、R1;交換機劃分的VLAN及端口根據如下拓撲圖,使用直通線、DCE串口線連接…

【Spark】Spark Join類型及Join實現方式

Spark Join類型 1. Inner Join (內連接) 示例:val result df1.join(df2, df1("id") df2("id"), "inner")執行邏輯:只返回那些在兩個表中都有匹配的行。 2. Left Join (左外連接) 示例:val result df1.jo…

socket UDP 環路回顯的服務端

基于socket通訊的方式&#xff0c;無論用http或者udp或者自定義的協議&#xff0c;程序結構都是類似的。這個以UDP協議為例簡要說明。 #include <stdio.h> // 標準輸入輸出庫 #include <sys/types.h> // 提供了一些數據類型&#xff0c;如ssize_t #include <sy…

Linux:network:添加ip的時候自動添加一個本地路由

文章目錄 問題問題 最近在看一個路由的問題,順便看內核代碼,發現在添加IP的時候,內核會自動添加一個local route。 net/ipv4/devinet.c inet_rtm_newaddr->__inet_insert_ifa /* Send message first, then call notifier.Notifier will trigger FIB update, so thatlis…

Magnet Player:一款基于Web的磁力鏈媒體播放器

Magnet Player&#xff1a;一款基于Web的磁力鏈媒體播放器 項目地址:https://gitcode.com/gh_mirrors/ma/magnet-player 是一個創新的開源項目&#xff0c;它允許用戶直接在瀏覽器中播放磁力鏈&#xff08;Magnet URI&#xff09;內容&#xff0c;無需下載或安裝任何桌面應用…

php:完整部署Grid++Report到php項目,并實現模板打印

一、下載Grid++Report軟件 路徑:開發者安裝包下載 - 銳浪報表工具 二、 安裝軟件 1、對下載的壓縮包運行內部的exe文件 2、選擇語言 3、 完成安裝引導 下一步即可 4、接收許可協議 點擊“我接受” 5、選擇安裝路徑 “瀏覽”選擇安裝路徑,點擊"安裝" 6、完成…

web安全攻防入門教程

Web安全攻防入門教程 Web安全攻防是指在Web應用程序的開發、部署和運行過程中&#xff0c;保護Web應用免受攻擊和惡意行為的技術與策略。這個領域不僅涉及防御措施的實現&#xff0c;還包括通過滲透測試、漏洞挖掘和模擬攻擊來識別潛在的安全問題。 本教程將帶你入門Web安全攻…

前端node環境安裝:nvm安裝詳細教程(安裝nvm、node、npm、cnpm、yarn及環境變量配置)

需求&#xff1a;在做前端開發的時候&#xff0c;有的時候 這個項目需要 node 14 那個項目需要 node 16&#xff0c;我們也不能卸載 安裝 。這豈不是很麻煩。這個時候 就需要 一個工具 來管理我們的 node 版本和 npm 版本。 下面就分享一個 nvm 工具 用來管理 node 版本。 這個…

Unity在運行狀態下,當物體Mesh網格發生變化時,如何讓MeshCollider碰撞體也隨之實時同步變化?

舊版源代碼地址&#xff1a;https://download.csdn.net/download/qq_41603955/90087225?spm1001.2014.3001.5501 舊版效果展示&#xff1a; 新版加上MeshCollider后的效果&#xff1a; 注意&#xff1a;在Unity中&#xff0c;當你動態地更改物體的Mesh時&#xff0c;通常期望…

OpenCV--特征匹配

OpenCV--特征匹配 代碼和筆記 代碼和筆記 import cv2 import numpy as np""" 特征匹配 """""" 暴力特征匹配&#xff1a;使用第一組&#xff08;第一幅圖&#xff09;中的一個特征描述子&#xff0c;使用一些距離計算與第二組中…

什么是自動化辦公

自動化辦公是指使用技術工具或軟件&#xff0c;通過預設流程或腳本&#xff0c;自動執行日常辦公任務&#xff0c;從而提升效率、減少錯誤、節約時間的辦公模式。它適用于需要重復性、規則明確的工作流程&#xff0c;讓員工將精力集中在更具創造性和戰略性的工作上。 自動化辦公…

常見排序算法總結 (四) - 快速排序與隨機選擇

快速排序 算法思想 每一輪在數組相應的范圍上隨機找一個元素進行劃分&#xff0c;將不大于它的所有元素都放到左邊&#xff0c;將大于它的元素都放到右邊。在左右兩個子數組上不斷地遞歸&#xff0c;直到整個數組上有序。 注意&#xff1a;實現時選擇的時參考荷蘭國旗問題優化…

unraid固態硬盤分區格式—默認1MiB對齊

背景 我的unraid中有三個機械硬盤和兩個固態硬盤&#xff0c;其中兩個固態硬盤組成zfs鏡像的cache&#xff0c;防止其中一個硬盤出問題導致數據丟失。然而&#xff0c;今天突然看到機械硬盤的分區格式為GPT 4k&#xff0c;而固態硬盤是MBR 1MiB。想到GPT更加優秀&#xff0c;并…

Flutter 圖片編輯板(一) 事件路由

一個圖片編輯板&#xff0c;有兩部分組成。編輯板和內容項。每一個內容項是被InteractiveViewer修飾的widget&#xff0c;具有縮放偏移的功能。 在圖片編輯板上&#xff0c; 會有多個內容相&#xff0c;圖片或文字&#xff08;添加文字目前還沒做過&#xff09;。 當要編輯其中…

數倉技術hive與oracle對比(一)

準備 包括軟硬件環境、數據、測試數據三方面的準備內容。 環境 虛擬機軟件virtualbox7&#xff0c;同樣的虛擬機配置&#xff1a;內存2G、cpu一核&#xff0c;物理主機同一臺macbookpro&#xff08;13-2020款&#xff09;&#xff0c;所以硬盤IO讀寫速度一致。 綜上&#x…

AR眼鏡_消費級工業AR智能眼鏡主板硬件解決方案

AR眼鏡的研發是一項復雜的軟硬件集成工程&#xff0c;它需要在攝影、音頻、交互和連接等多個方面提供卓越的基礎體驗&#xff0c;因此產品的每個細節都顯得尤為重要。 在設計AR眼鏡時&#xff0c;重量、體積和散熱性能都是必須認真考量的關鍵因素。在芯片平臺的選擇上&#xff…

通信原理概論復習筆記(1)

1 緒論 消息: 通信系統傳輸對象, 信息的載體和物理表現形式. 信息: 消息的有效內容和內涵. 信號: 消息的傳輸載體. 模擬通信: 信源 → \to → 調制器 → \to → 信道(噪聲) → \to → 解調器 → \to → 信宿. 數字通信: 信源 → \to → 信源編碼(壓縮數字化) → \to →…

ASPICE評估如何優化軟件開發、測試和部署流程

ASPICE&#xff08;Automotive SPICE&#xff0c;即汽車軟件過程改進及能力評定&#xff09;評估在提高軟件開發、測試、部署的速度和質量方面發揮著重要作用。以下是ASPICE評估如何具體提高這些環節的具體方式&#xff1a; 一、提高軟件開發效率 標準化流程&#xff1a;ASPIC…

【OpenCV】Canny邊緣檢測

理論 Canny 邊緣檢測是一種流行的邊緣檢測算法。它是由 John F. Canny 在 1986 年提出。 這是一個多階段算法&#xff0c;我們將介紹算法的每一個步驟。 降噪 由于邊緣檢測易受圖像中的噪聲影響&#xff0c;因此第一步是使用 5x5 高斯濾波器去除圖像中的噪聲。我們在前面的章…

Ubuntu 安裝 web 服務器

安裝 apach sudo apt install apache2 -y 查看 apach2 版本號 apache2 -v 檢查是否啟動服務器 sudo service apache2 status 檢查可用的 ufw 防火墻應用程序配置 sudo ufw app list 關閉防火墻 sudo ufw disable 更改允許通過端口流量 sudo ufw allow Apache Full 開啟…