# Independent Notes
[TOC]
## PICCLOUD

## 建立env環境
* 找到要用的PyTorch版本

* 下載對應的CUDA及CUDnn
確認CUDA及CUDnn都有正確安裝
[***CUDA及CUDnn下載教學***](https://medium.com/@zera.tseng888/%E5%9C%A8windows11%E7%92%B0%E5%A2%83%E4%B8%8B%E5%AE%89%E8%A3%9Dcuda%E8%88%87cudnn-dd85575187ae)
* 打開anaconda prompt
```
#建立虛擬環境
conda create env --name filename python=3.11
```
==filename==:env名稱, 選擇適用python
```
#確認虛擬機創建成功
conda env list
#激活環境
conda acitvate filename
```
=="filename"自行更改命名的env==
* 下載Pytorch有兩種方式 :
1. 普通下載 -
```
conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
```
2. 若用到PyTorch&Ultralytics使用以下程式碼避免出錯 -
```
conda install -c pytorch -c nvidia -c conda-forge pytorch torchvision pytorch-cuda=11.8 ultralytics
```
* Compilter選擇
1. Spyder
```
#下載spyder並顯示在開始頁面
conda install spyder
```
2. VScode
點選step1.在step2.中找到命名的env.

環境架設完畢後即可測試Pytorch及GPU的運行
[Code Link](#Pytorch確認GPU可用)
## Segmentation 正規化
### ++txt.檔++ 格式
```
class_id x1_normalized y1_normalized x2_normalized y2_normalized ... xn_normalized yn_normalized
```
[Detect&Segment++txt.++還原圖片](#DetectampSegmenttxt還原圖片)
### 正規化公式:
x_normalized = x_point / image_width
y_normalized = y_point / image_height
## Models 簡介
### models速度解析

==高的 mAP、精確率和召回率==:數值越高,模型性能越好。
==低的損失值==:訓練過程中的損失值應逐漸減少。
==整體趨勢==:損失值降低,同時 mAP、精確率、召回率增加,表明模型訓練有效。
==對比分析==:通過對比不同模型或訓練輪次的指標,評估模型效果。
## Code
### Pytorch確認GPU可用
```
import torch
import time
# 檢查 PyTorch 是否可以使用 CUDA(GPU)
if torch.cuda.is_available():
print("CUDA is available. PyTorch is using the GPU.")
print(f"Device name: {torch.cuda.get_device_name(0)}") # 顯示 GPU 的名稱
else:
print("CUDA is not available. PyTorch is using the CPU.")
print("\n")
# 創建一個張量並將其移動到 GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 測試 GPU 運算的性能
x = torch.randn(10000, 10000).to(device)
y = torch.randn(10000, 10000).to(device)
# 計時 GPU 運算
start_time = time.time()
result = torch.matmul(x, y)
end_time = time.time()
print(f"GPU運算時間: {end_time - start_time} 秒")
# 如果運算在 GPU 上進行,運算速度應該比在 CPU 上快
#3060ti:0.1-0.3s, 3080:0.005-0.2s
```
### Detect&Segment++txt.++還原圖片
```
import cv2
import numpy as np
# 讀取圖像
image = cv2.imread('otherprocess/1.png')
# 圖像尺寸
img_height, img_width, _ = image.shape
# 從txt文件中讀取標記的數據
annotations = [
[0, 0.41201117318435754 ,0.2942271880819367, 0.46648044692737434, 0.3054003724394786, 0.48324022346368717, 0.32774674115456237, 0.4930167597765363,
0.35940409683426444,0.5013966480446927, 0.4022346368715084, 0.4930167597765363 ,0.43202979515828677, 0.4916201117318436,
0.45251396648044695, 0.479050279329609, 0.45623836126629425, 0.44832402234636876 ,0.4487895716945996, 0.41480446927374304,
0.441340782122905, 0.388268156424581, 0.41899441340782123, 0.3756983240223464 ,0.3985102420856611, 0.3715083798882682,
0.3780260707635009 ,0.3743016759776536, 0.3463687150837989, 0.37988826815642457, 0.3240223463687151, 0.38966480446927376 ,0.3091247672253259
],
[0, 0.6983240223463687, 0.6163873370577281, 0.6717877094972067, 0.6163873370577281,0.659217877094972, 0.6163873370577281, 0.6508379888268156,
0.6070763500931099, 0.6452513966480448, 0.5754189944134078, 0.6536312849162011, 0.5679702048417132 ,0.6787709497206704,
0.5661080074487895 ,0.6913407821229051, 0.5698324022346368, 0.6997206703910615, 0.5810055865921787
]
]
# detection: 將正規化的標註還原成像素座標,並畫出矩形框
"""
for annotation in annotations:
class_id, x_center_norm, y_center_norm, width_norm, height_norm = annotation[:5]
# 還原成像素坐標
x_center = int(x_center_norm * img_width)
y_center = int(y_center_norm * img_height)
width = int(width_norm * img_width)
height = int(height_norm * img_height)
# 計算左上角和右下角的點
x1 = int(x_center - width / 2)
y1 = int(y_center - height / 2)
x2 = int(x_center + width / 2)
y2 = int(y_center + height / 2)
# 在圖像上畫出矩形框
cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
"""
#segmention
for annotation in annotations:
class_id = annotation[0] # 物件的類別ID
polygon_points = annotation[1:] # 分割物件的多邊形座標
# 將標註的座標轉為圖像的絕對像素座標
points = [(int(p[0] * img_width), int(p[1] * img_height)) for p in zip(polygon_points[::2], polygon_points[1::2])]
# 畫出多邊形 (這裡使用 cv2.polylines 來繪製分割物件的邊界)
points = np.array(points, np.int32)
points = points.reshape((-1, 1, 2))
cv2.polylines(image, [points], isClosed=True, color=(0, 255, 0), thickness=2)
# 顯示結果
cv2.imshow('Image with Annotations', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 或者保存圖像
cv2.imwrite('otherprocess/1.txt', image)
```
### 灰階圖轉RGB,對比度增強
```
import cv2
import os
# 定義路徑
input_folder = "C:/Users/curti/Desktop/yolo/datasets1/val/images"
output_folder = "C:/Users/curti/Desktop/yolo/datasets1/processed/val/image"
# 確保輸出文件夾存在
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 設定圖片大小
img_size = (640, 640)
for filename in os.listdir(input_folder):
if filename.endswith(".jpg"):
img_path = os.path.join(input_folder, filename)
img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) # 讀取灰度圖像
# 對比度增強
img_eq = cv2.equalizeHist(img)
# 將增強後的灰度圖轉為RGB
img_rgb = cv2.cvtColor(img_eq, cv2.COLOR_GRAY2RGB)
# 調整大小
resized_img = cv2.resize(img_rgb, img_size)
# 保存處理後的圖像
output_path = os.path.join(output_folder, filename)
cv2.imwrite(output_path, resized_img)
```
### XML批量轉TXT
```
import os
import xml.etree.ElementTree as ET
# 定義類別名稱與其對應的 class_id
classes = ["rfa"] # 根據你的類別進行調整
def convert_to_yolo(size, points):
dw = 1.0 / size[0] # 圖片寬度
dh = 1.0 / size[1] # 圖片高度
norm_points = []
for i in range(0, len(points), 2):
x = points[i] * dw
y = points[i + 1] * dh
if not (0 <= x <= 1) or not (0 <= y <= 1):
raise ValueError(f"正規化座標超出範圍: ({x}, {y})")
norm_points.extend([x, y])
return norm_points
def convert_xml_to_txt(xml_file, output_txt):
tree = ET.parse(xml_file)
root = tree.getroot()
# 取得圖片的寬度和高度
width = int(root.find('imagesize').find('ncols').text)
height = int(root.find('imagesize').find('nrows').text)
with open(output_txt, 'w') as txt_file:
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
continue
cls_id = classes.index(cls)
points = []
for pt in obj.find('polygon').iter('pt'):
x = float(pt.find('x').text)
y = float(pt.find('y').text)
points.extend([x, y])
# 正規化座標
try:
norm_points = convert_to_yolo((width, height), points)
txt_file.write(f"{cls_id} {' '.join(map(str, norm_points))}\n")
except ValueError as e:
print(f"錯誤: {e} 檔名: {xml_file}")
return
# 設定 XML 目錄
xml_directory = "otherprocess/XML"
txt_directory = "otherprocess/TXT"
os.makedirs(txt_directory, exist_ok=True)
for filename in sorted(os.listdir(xml_directory)):
if filename.endswith(".xml"):
xml_file = os.path.join(xml_directory, filename)
txt_output = os.path.join(txt_directory, f"{os.path.splitext(filename)[0]}.txt")
convert_xml_to_txt(xml_file, txt_output)
```
### UnetCode(not completing&uncheck)
```
import os
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as T
import torch.optim as optim
from torch.util.data import Dataset
from PIL import Image
import numpy as np
class DoubleConv(nn.Module):
def __init__(self, in_channels, out_channels):
super().__init__()
self.conv == nn.Sequential(
nn.Conv2d(in_channels, out_channels, 3, 1, 1, bias=False),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True),
nn.Conv2d(out_channels, out_channels, 3, 1, 1, bias=False),
nn.BatchNorm2d(out_channels),
nn.ReLU(inplace=True)
)
def forward(self, x):
return self.conv(x)
class UNet(nn.module):
def __init__(self, in_channels=3, out_channels=1, features=[64, 128, 256, 512]):
super.__init__()
self.downs = nn.ModuleList()
self.ups = nn.ModuleList()
for feature in features:
self.downs.append(DoubleConv(in_channels, feature))
in_channels = feature
self.bottleneck = DoubleConv(feature[-1], feature[-1]*2)
for feature in reversed(features):
self.ups.append(nn.ConvTranspose2d(feature*2, feature, 2, 2))
self.ups.append(DoubleConv(feature*2, feature))
self.final_conv = nn.Conv2d(features[0], out_channels, 1)
def forward(self,x):
skip_connections = []
for down in self.downs:
x = down(x)
skip_connections.append(x)
x = F.max_pool2s(x, (2, 2))
x = self.bottleneck(x)
skip_connections.reverse()
for i in range (0,len(self.ups),2):
x = self.ups[i](x)
skip_connections = skip_connections(i//2)
concat = torch.cat((skip_connections, x), dim=1)
x = self.ups[i+1](concat)
return self.final_conv(x)
#Create an Unet model object
model = UNet()
toy_data = torch.ones((16, 3, 240, 160))
output = model(toy_data)
print(output.shape)
model = model.cuda()
```