發佈日期:

使用現有模型標記新圖片

Auto Labeling

因為在標記時常會花費很多的時間和力氣,現在市面上有許多auto labeling的工具,例如前一陣子meta有發表一個模型,還引起注目叫做SAM: https://segment-anything.com/

以下為一個簡單的使用範例

from segment_anything import sam_model_registry, SamAutomaticMaskGenerator, SamPredictor
import matplotlib.pyplot as plt
import cv2
import numpy as np
def show_anns(anns):
    if len(anns) == 0:
        return
    sorted_anns = sorted(anns, key=(lambda x: x['area']), reverse=True)
    ax = plt.gca()
    ax.set_autoscale_on(False)

    img = np.ones((sorted_anns[0]['segmentation'].shape[0], sorted_anns[0]['segmentation'].shape[1], 4))
    img[:,:,3] = 0
    for ann in sorted_anns:
        m = ann['segmentation']
        color_mask = np.concatenate([np.random.random(3), [0.35]])
        img[m] = color_mask
    ax.imshow(img)
    
image = cv2.imread('./train/IMG_5208_jpg.rf.d85b8d233845117f0362c17ca2222c21.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

sam_checkpoint = "sam_vit_h_4b8939.pth"
model_type = "vit_h"

device = "cpu"

sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device=device)

mask_generator = SamAutomaticMaskGenerator(sam)
masks = mask_generator.generate(image)
print(len(masks))
print(masks[0].keys())

plt.figure(figsize=(20,20))
plt.imshow(image)
show_anns(masks)
plt.axis('off')
plt.show() 

成果如下:

Roboflow的智慧圈選工具

在Roboflow也有類似的智慧圈選工具,可以自動為我們圈選目標的形狀,使用方式如下

使用現有模型標記YOLO格式label

但是若我們想要使用既有的模型訓練一些新的圖片,在新的圖片,若要標記一些常見的物品,如汽車、人、機車等…。這些東西因為在YOLO這種模型,預設的偵測狀況就很不錯了,有的時候為了要讓標記更快速,可以使用現有模型把預測的結果轉為標記檔案,再匯入Roboflow等標記軟體檢視標記狀況並修正錯誤的標記,會可以使標記工作更輕鬆。

預測結果轉標記程式碼

這邊是預測的result的相關文件: https://docs.ultralytics.com/reference/engine/results/#ultralytics.engine.results.Results.tojson

我真的覺得yolov8做的很用心的點,在於他的說明超級清楚,尤其是在程式碼本身上面,我們可以單單藉由下面程式碼印出詳細返回的物件結構,然後就可以了解該如何取得我們所需的物件資訊

from ultralytics import YOLO

# Load a model
model = YOLO('yolov8n.pt')  # pretrained YOLOv8n model

# Run batched inference on a list of images
results = model(['im1.jpg', 'im2.jpg'])  # return a list of Results objects

# Process results list
for result in results:
    boxes = result.boxes  # Boxes object for bbox outputs
    masks = result.masks  # Masks object for segmentation masks outputs
    keypoints = result.keypoints  # Keypoints object for pose outputs
    probs = result.probs  # Probs object for classification outputs
    print(masks )

從API我們可以得知,若我們使用的是yolo-seg,則吐回的座標資訊可參考這個返回值

完整預測結果轉標記的程式範例

設定folder_path到images的資料夾,label會放到相對應的labels資料夾下

from ultralytics import YOLO
from PIL import Image
import cv2
import os

# 資料夾路徑
folder_path = './datasets/coco8-seg/images/train'
images = []
# 確保資料夾存在
if not os.path.exists(folder_path):
    print("資料夾不存在")
else:
    # 取得資料夾內所有檔案
    file_list = os.listdir(folder_path)
    
    # 遍歷每個檔案
    for filename in file_list:
        # 確保檔案是圖片檔案(可根據您的需求調整)
        if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
            # 構建完整的檔案路徑
            file_path = os.path.join(folder_path, filename)
            
            images.append(file_path)

# Load a model
model = YOLO('yolov8n-seg.pt')  # pretrained YOLOv8n model

# Run batched inference on a list of images
results = model(images)  # return a list of Results objects


# Show the results
for r in results:
    formatted_string = ""
    if r is not None and r.masks is not None:
        for i in range(len(r.masks.xyn)):
            mask = r.masks.xyn[i]
            cls = int(r.boxes.cls[i].item())
            formatted_rows = []
            formatted_rows.append(cls)
            for row in mask:
                formatted_rows.append(row[0])
                formatted_rows.append(row[1])

            formatted_string = ((formatted_string + '\n') if formatted_string != "" else "") + " ".join(str(x) for x in formatted_rows)
        with open(r.path.replace('.jpg', '.txt').replace('images', 'labels'), "a") as file:
            file.write(formatted_string)

把YOLO格式轉為COCO格式

請參考此專案: https://github.com/Taeyoung96/Yolo-to-COCO-format-converter/tree/master

發佈日期:

尋找pretrain model的好地方

https://paperswithcode.com/sota

“SOTA” 是 “State-of-the-Art” 的縮寫,意為 “最先進技術”。在計算機科學和人工智能領域,SOTA模型指的是當前被認為是在某個特定任務或領域內表現最優秀的模型或方法。這些模型通常代表了當前領域內的最高水平,並在諸如自然語言處理、計算機視覺、語音識別等各種任務中發揮著重要作用。

發佈日期:

如何把docker image推到AKS

請參考此說明: https://docs.docker.com/cloud/aci-integration/

首先請登入Azure

會跳出瀏覽器登入Azure的帳號和docker做連接

docker login azure

接著創立aci的context

docker context create aci myacicontext

使用docker context ls可以檢視現在有哪些context

接著這樣就可以把image部屬上AKS了

docker --context myacicontext run -p 80:80 nginx

推送自建的container

https://learn.microsoft.com/zh-tw/training/modules/intro-to-containers/7-exercise-deploy-docker-image-to-container-instance

1.建立容器

2. 改名並推送上去

docker tag reservationsystem:latest <registry-name>.azurecr.io/reservationsystem:latest
docker image ls
docker login <login-server>
docker push <registry-name>.azurecr.io/reservationsystem:latest
發佈日期:

Swift初探

條件編譯

這是 Swift 的條件編譯(Conditional Compilation)的一個示例,它允許你根據特定的條件選擇性地編譯代碼。在這段代碼中,它確定代碼是在 iOS 模擬器中運行還是在實際的 iOS 裝置上運行。

    #if targetEnvironment(simulator)
    self.videoCapturer = RTCFileVideoCapturer(delegate: videoSource)
    #else
    self.videoCapturer = RTCCameraVideoCapturer(delegate: videoSource)
    #endif

判斷變數是否存在

Swift的空值會是nil

什麼 是 Protocol 與 Delegate

1. Protocol

在 Swift 中,協議(Protocol)定義了一套規範或合約,但不提供具體的實現。任何型別(如 classstructenum)都可以遵循(implement)這些協議,並為協議中的要求提供具體的實現。

例如,我們可以定義一個表示可序列化對象的 Serializable 協議:

protocol Serializable {
    func serialize() -> String
}

然後,我們可以讓某個 structclass 遵循這個協議:

struct Person: Serializable {
    var name: String
    var age: Int

    func serialize() -> String {
        return "\(name),\(age)"
    }
}

2. Delegate

Delegate 是一種設計模式,允許一個物件將某些決策或功能外包給另一個物件。在 Swift 中,Delegate 通常是通過協議來實現的。這意味著當一個類想要成為另一個類的代理時,它必須遵循一個特定的協議。

例如,假設我們有一個 Downloader 類,當下載完成時,我們希望通知另一個物件。我們可以定義一個 DownloaderDelegate 協議:

protocol DownloaderDelegate: AnyObject {
    func didFinishDownloading(data: Data)
}

然後,Downloader 類可以有一個 delegate 屬性:

class Downloader {
    weak var delegate: DownloaderDelegate?

    func download() {
        // 下載過程...
        // 完成後通知代理:
        delegate?.didFinishDownloading(data: someData)
    }
}

其他類(例如 ViewController)可以遵循 DownloaderDelegate 協議並成為 Downloader 的代理,以響應下載完成事件。

這兩個概念在 iOS 和 Swift 開發中都是核心的,用於很多不同的場景和功能。

強大的extension

在 Swift 中,類別 (class)、結構體 (struct)、列舉 (enum)、或者協定 (protocol) 都可以使用 extension 來增加功能。這是 Swift 中一個非常強大的功能,使得你可以將類別或結構體的定義分散到多個區塊,使其更具組織性和可讀性。

以下是使用 extension 的一些常見原因:

  1. 組織性: 你可以使用 extension 來組織你的程式碼,將相似的功能或者與某個特定主題相關的方法放在一起。
  2. 遵循協定: 如果你的類別需要遵循某個協定 (protocol),你可以使用 extension 來隔離所有與該協定相關的實現。
  3. 可讀性: 將類別或結構體分成小區塊可以提高程式碼的可讀性。
  4. 重用和模組化: 你可以定義多個 extension,並將它們放在不同的檔案中,以便於重用或者模組化。

在你給出的例子中,原始的 WebRTCClient 類別可能已經有了一些基本功能。然後,通過使用 extension,增加了關於視頻控制的功能。這種方式可以讓每個 extension 專注於一個特定的功能或者主題,從而使得整體的程式碼更加清晰和有組織性。

總的來說,Swift 中的 extension 功能允許我們對既有的類別或其他資料結構進行進一步的擴展,這樣可以使得程式碼更具組織性、可讀性,並且更容易維護。

分開寫 extension 和將其寫在一起,從功能的角度來看,並沒有區別。不過,程式碼的組織方式往往是為了達到更好的可讀性和易於維護。將不同的功能或與特定主題相關的方法分開在不同的 extension 中,可以幫助讀者和開發者更快地了解該區塊的主要功能,也更容易定位和修改相關的代碼。

使用guard控制流結構

guard 是 Swift 語言中的一個控制流結構,用於提前退出(early exit)方法或函數的執行,當某些條件不成立時。它是為了減少嵌套(nested)的深度和提高程式碼的可讀性。

以下是 guard 的一些特點:

  1. guard 之後必須跟一個條件,如果這個條件為 false,則執行 else 裡面的代碼。
  2. else 裡面必須有一個轉移控制語句,例如 returnbreakcontinuethrow,以確保退出當前的執行流程。
  3. 如果 guard 的條件為 true,則會繼續執行 guard 之後的代碼。

例如:

guard let dataToSend = alert.textFields?.first?.text?.data(using: .utf8) else {
    return
}

這段代碼試圖從 alert 的第一個文本欄位中獲取文本,然後將其轉換為 UTF-8 編碼的 Data 對象。如果其中任何一步失敗(例如,文本欄位為 nil、文本為空或轉換失敗),則整個條件為 false,並執行 else 裡面的 return 語句,從當前函數或方法中提前退出。

使用 guard 而不是嵌套的 if-let 可以使程式碼更加整潔、易讀,特別是當有多個條件需要檢查時。

在Swift中使用閉包

在Swift中,$0, $1, $2, … 是在閉包中使用的隱式名稱,代表閉包的第一個、第二個、第三個…參數。

peerConnection.transceivers
    .compactMap { return $0.sender.track as? T }
    .forEach { $0.isEnabled = isEnabled }

這裡有兩個閉包:一個是用於 compactMap 的閉包,另一個是用於 forEach 的閉包。

  1. 對於 compactMap 的閉包:$0 代表 peerConnection.transceivers 集合中的每一個元素,即每一個 RTCRtpTransceiver 對象。在這個閉包中,它試圖取出每個 transceiver 的 sender 的 track 並嘗試將其轉型為指定的 T 類型。
  2. 對於 forEach 的閉包:在 compactMap 運行之後,我們獲得一個包含符合指定類型 T 的軌道的集合。在 forEach 的閉包中,$0 代表這些軌道。閉包的作用是設置這些軌道的 isEnabled 屬性。
發佈日期:

常見的Computer Vision Tasks

下面是四種常見的計算機視覺任務的簡要介紹:

分類(Classification)

分類任務是將輸入圖像分為不同的類別或類別之一。例如,給定一張圖像,分類任務的目標是確定圖像中顯示的對像是什麼,比如貓、狗、汽車、飛機等。這通常涉及訓練一個分類器,以便它能夠識別圖像中的特定特徵並將其歸類到正確的類別中。

語義分割(Semantic Segmentation)

語義分割任務是為圖像中的每個像素分配一個類別標籤,從而實現像素級別的分類。與分類任務不同,語義分割不僅關注對象的類型,還考慮了對象的位置和邊界。這在許多應用中很有用,比如圖像分割、醫學圖像分析等。

語義分割是一種計算機視覺任務,旨在將圖像中的每個像素分配給預定義的語義類別。在語義分割中,每個像素都被標記為屬於某個特定的類別,如人、車、樹等。語義分割遵循像素級別的分類,因此通常使用像素級別的掩碼(即”masks”)來表示圖像中每個類別的區域。這些分割掩碼是二進製圖像,其中每個像素要嘛屬於某個類別,要嘛不屬於。

有名模型: U-Net 

和實例分割最大的不同是他的輸入會是兩張圖片,一張為原圖,一張為掩碼的圖

目標檢測(Object Detection)

目標檢測任務涉及在圖像中識別並定位多個不同類別的對象。相比於分類任務,目標檢測不僅需要標識對象的類別,還需要確定它們的位置和邊界框。常見的目標檢測算法可以提供每個檢測到的對象的邊界框和類別信息。具代表性的演算法包括Faster R-CNN, YOLO, SSD等

這篇文章介紹了許多我們常用的物件偵測模型: https://zhuanlan.zhihu.com/p/38709522

實例分割(Instance Segmentation)

實例分割任務結合了目標檢測和語義分割的概念,不僅要對每個對象進行分類,還需要在像素級別區分出每個對象的邊界。實例分割旨在識別圖像中的每個獨立實例並為每個實例分配獨特的標籤,從而在一個圖像中區分出不同的對象。

例如: COCO Segmentation
COCO(Common Objects in Context)是一個廣泛使用的圖像識別和分割數據集,其中包含了多種物體類別的圖像以及每個圖像中物體的分割標註。 COCO Segmentation 數據集中的分割信息通常是用多邊形輪廓來表示物體的形狀。這種分割方法在標註上更靈活,可以準確地表示物體的複雜形狀,但同時也需要更多的標註工作。

發佈日期:

使用ffmpeg濾鏡功能做影片合成

下載ffmpeg

https://ffmpeg.org/download.html

推一個時鐘文字的影片

ffmpeg的指令如下

ffmpeg  -f lavfi -i color=c=0x00ff00:s=800x450 -vf "settb=AVTB, setpts='trunc(PTS/1K)*1K+st(1,trunc(RTCTIME/1K))-1K*trunc(ld(1)/1K)', drawtext=text='STREAM2-%{localtime}.%{eif\:1M*t-1K*trunc(t*1K)\:d}':x=100:y=100:fontsize=32:fontcolor=white" -c:v libx264 -f flv rtmp://192.168.189.11/live/test2
  1. -f lavfi -i color=c=0x00ff00:s=800×450:這部分使用lavfi作為輸入來源,並創建一個顏色填充的視頻流。 c=0x00ff00指定填充的顏色為綠色,s=800×450指定分辨率為 800×450。
  2. -vf “settb=AVTB, setpts=’trunc(PTS/1K)1K+st(1,trunc(RTCTIME/1K))-1Ktrunc(ld(1)/1K)’, drawtext=text=’STREAM2 -%{localtime}.%{eif\:1Mt-1Ktrunc(t*1K)\:d}’:x=100:y=100:fontsize=32:fontcolor=white”:這部分使用- vf標誌來應用視頻過濾器。其中有兩個主要的過濾器:
    • settb=AVTB, setpts=’trunc(PTS/1K)1K+st(1,trunc(RTCTIME/1K))-1Ktrunc(ld(1)/1K)’:這個過濾器設置視頻時間戳。 settb=AVTB設置時間基準,setpts用於計算新的時間戳,其中包括根據PTS(顯示時間戳)和RTCTIME(實時時鐘時間)進行一些計算。
    • drawtext=text=’STREAM2-%{localtime}.%{eif\:1Mt-1Ktrunc(t1K)\:d}’:x=100:y=100:fontsize=32:fontcolor=white “:這個過濾器使用drawtext來在視頻上繪製文本。它在視頻左上角繪製了一個文本,其中包含了時間戳信息。%{localtime}插入本地時間,%{eif\:1Mt-1K* trunc(t*1K)\:d}用於插入一個經過格式化的時間戳。
  3. -c:v libx264:這部分設置視頻編碼器為libx264,用於將視頻編碼為H.264格式。
  4. -f flv rtmp://192.168.189.11/live/test2:這部分設置輸出格式為FLV,並指定RTMP服務器的地址。視頻會通過RTMP流式傳輸到指定的地址。在這裡,rtmp://192.168.189.11/live/test2是RTMP服務器的地址。

使用虛擬鏡頭來推流

ffmpeg -f dshow -rtbufsize 200M -i video=OBS-Camera -pix_fmt yuv420p -c:v libx264 -profile:v baseline -level:v 3.1 -preset:v ultrafast -s 480x270 -g 240 -an -f flv -y rtmp://172.16.46.89/live/0101_dealerPC1 
  1. -f dshow -rtbufsize 200M -i video=OBS-Camera:這部分設置輸入來源為DirectShow,並指定攝像頭的名稱為 “OBS-Camera”。 -rtbufsize 200M 設置了實時緩衝區的大小為 200MB。
  2. -pix_fmt yuv420p:這部分設置輸出視頻的像素格式為YUV 4:2:0,這是常見的視頻格式。
  3. -c:v libx264 -profile:v baseline -level:v 3.1 -preset:v ultrafast:這部分設置視頻編碼器為libx264,使用baseline配置文件,3.1級別,並設置預設(編碼速度)為ultrafast,這意味著編碼速度非常快。
  4. -s 480×270:這部分設置輸出視頻的分辨率為 480×270,即寬度為480,高度為270。
  5. -g 240:這部分設置關鍵幀(I幀)之間的間隔為 240 幀,用於控制視頻的GOP結構。
  6. -an:這部分錶示不捕獲音頻。
  7. -f flv:這部分設置輸出格式為FLV格式。
  8. -y:這部分錶示在輸出文件存在時覆蓋已存在的文件。
  9. rtmp://172.16.46.89/live/0101_dealerPC1:這部分是輸出URL,指定了通過RTMP傳輸的目標地址。視頻將會通過RTMP協議傳輸到 rtmp://172.16.46.89/live/0101_dealerPC1 這個地址。

極低延遲播放串流

ffplay -fflags nobuffer -flags low_delay -rtmp_buffer 0 -rtmp_live live -framedrop -infbuf %desc%
  1. -fflags nobuffer: 禁用緩衝。這意味著ffplay將盡可能地減少緩衝,以減少播放的延遲。
  2. -flags low_delay: 啟用低延遲模式。這將優化播放以減少延遲,適用於實時音視頻流。
  3. -rtmp_buffer 0: 設置 RTMP 緩衝大小為 0。 RTMP 是一種流媒體協議,這個選項設置緩衝大小為 0 表示盡可能地減少緩衝,從而減少延遲。
  4. -rtmp_live live: 表示要播放的是實時流。
  5. -framedrop: 如果幀太多,ffplay 將刪除一些幀以避免播放過慢。這有助於保持播放的實時性。
  6. -infbuf: 禁用緩衝輸入。與 -fflags nobuffer 相似,這有助於減少延遲。
  7. %desc%: 這可能是一個佔位符,用於指定音視頻流的 URL 或描述符。

把虛擬鏡頭和某個線上串流做綠幕合成

ffmpeg -f dshow -rtbufsize 1M -i video="OBS Virtual Camera" -f flv -i rtmp://172.17.22.89/live/test1 -filter_complex "[0:v]colorkey=0x00ff00:0.3:0.2[keyed];[1:v][keyed]overlay[o]" -map "[o]" -c:v h264_nvenc -f flv rtmp://127.0.0.1/live/test3
  1. -f dshow: 指定輸入的多媒體設備類型為 DirectShow(Windows 平台上的多媒體框架)。
  2. -rtbufsize 1M: 設置輸入緩衝區大小為 1MB。這可能有助於減少輸入的延遲。
  3. -i video=”OBS Virtual Camera”: 指定輸入的視頻設備名稱為 “OBS Virtual Camera”。這是一個虛擬攝像頭,通常由 OBS(Open Broadcaster Software)等軟件創建,用於虛擬攝像頭設備的捕獲。
  4. -f flv -i rtmp://172.17.22.89/live/test1: 指定輸入的媒體流為 RTMP 流,其 URL 為 rtmp://172.17.22.89/live/test1。這是從另一個 RTMP 流獲取的視頻。
  5. -filter_complex “[0:v]colorkey=0x00ff00:0.3:0.2[keyed];[1:v][keyed]overlay[o]”: 使用濾鏡複雜處理,這裡進行了以下操作:
  6. [0:v]colorkey=0x00ff00:0.3:0.2[keyed]:應用顏色鍵(chroma key)效果來移除綠色(0x00ff00)背景。生成一個帶有透明背景的圖像。
    [1:v][keyed]overlay[o]:將第一個輸入流(來自虛擬攝像頭)與經過顏色鍵處理的圖像進行疊加,產生混合後的圖像。
    -map “[o]”: 從混合後的圖像中選擇 [o] 這個輸出流。
  7. -c:v h264_nvenc: 使用 NVIDIA GPU 的硬件編碼器 h264_nvenc 進行視頻編碼。這將利用 GPU 進行加速,提高編碼效率。
  8. -f flv rtmp://172.17.22.89/live/test3: 指定輸出為 RTMP 流,其 URL 為 rtmp://172.17.22.89/live/test3。這是輸出混合後的視頻流。

更多詳細設置串流的方式

set ffmpegBin=C:\apps\ffmpeg\
set PATH=%PATH%;%ffmpegBin%

set camName="OBS Virtual Camera"
set camBufferSize=1000
set desc=rtmp://127.0.0.1:1935/live/demo

set codec=libx264
set fps=24
set /a "keyint=%fps%*5"
set x264opts=keyint=120:min-keyint=%fps%:scenecut=0
set preset=medium
set profile=baseline
set level=3.1
set resolution=800x450
set bitrate=700

:: publish stream
ffmpeg -f dshow -rtbufsize %camBufferSize%M -i video=%camName% ^
       -vf format=yuv420p ^
       -vcodec %codec% -x264-params %x264opts% ^
       -preset %preset% -profile:v %profile% -level:v %level% ^
       -tune:v zerolatency ^
       -s %resolution% ^
       -r %fps% ^
       -b:v %bitrate%k -minrate %bitrate%k -maxrate %bitrate%k -bufsize %bitrate%k ^
       -an ^
       -f flv %desc%

`-r` 轉成多少 fps

`-y` (global) Overwrite output files without asking.

`-i` 輸入檔案

`-c:v` video codec

`-profile:v` video profile, streaming 用 baseline

`-level:v` video level, streaming 用 3.1

`-preset:v` 編碼速度 streaming 用 ultrafast

`-b:v` 設定 bitrate, 例如 700k 486k

`-s` 尺寸

`-g` GOP size (-4 24 -g 240 相當於 Keyframe frequency = 10s)

`-an` 不需要 audio

`-f flv` flv 格式

`-f dshow -i video=OBS-Camera` window 使用 direct show來抓 camera

`-rtbufsize 200M` 設定 buffer size 避免 drop frame

`-re` 串流轉碼會變慢 因為要求 encoder 根據 native frame rate 讀檔按維持品值,要做串流轉發不要延遲時要拿掉。

https://www.wowza.com/docs/how-to-restream-using-ffmpeg-with-wowza-streaming-engine

FFREPORT 環境變數設好 ffmpeg 就會根據設定存log

linux format for date
https://www.opencli.com/linux/linux-date-format-shell-script

偵測 video frame 資訊

取得 stream 資訊

ffprobe -v quiet -show_streams -select_streams v:0 input.flv

抓出所有 i-frame

ffprobe -show_frames input.flv | grep pict_type | grep -n I

FME 設定 24fps, keyframe frequency = 10s
在理想狀況,會每 240 frame 插入一個 i-frame

example:

1:pict_type=I
241:pict_type=I
481:pict_type=I
721:pict_type=I
961:pict_type=I
1201:pict_type=I
發佈日期:

conda無法安裝套件,缺少OpenSSL解決方案

錯誤訊息

Collecting package metadata (current_repodata.json): failed CondaSSLError: OpenSSL appears to be unavailable on this machine. OpenSSL is required to download and install packages. Exception: HTTPSConnectionPool(host=’conda.anaconda.org’, port=443): Max retries exceeded with url: /conda-forge/win-64/current_repodata.json (Caused by SSLError(“Can’t connect to HTTPS URL because the SSL module is not available.”))

使用pip install/conda install跳出的錯誤

解決方法

在anaconda3>Library>bin尋找這兩個檔案

  • libcrypto-1_1-x64.dll
  • libssl-1_1-x64.dll

然後複製到anaconda3>DLLs.

相關討論串

https://github.com/conda/conda/issues/11982

發佈日期:

資料增強好工具 – Albumentations

官方資訊

GITHUB: https://github.com/albumentations-team/albumentations

官方文檔: https://albumentations.ai/docs/getting_started/transforms_and_targets/

官方範例: https://github.com/albumentations-team/albumentations_examples/blob/master/notebooks/pytorch_semantic_segmentation.ipynb

Albumentations介紹

Albumentations 是一個流行的計算機視覺數據增強庫,專門設計用於圖像分類、目標檢測、分割等任務。它提供了豐富的圖像增強技術,可以幫助您在訓練深度學習模型時提升模型的性能和魯棒性。 Albumentations 支持多種常用的深度學習框架,如PyTorch和TensorFlow。

以下是 Albumentations 的一些特點和功能:

  • 多樣的增強技術: Albumentations 提供了大量的圖像增強技術,包括但不限於旋轉、翻轉、裁剪、縮放、亮度調整、對比度調整、顏色變換、模糊效果、噪聲添加等。
  • 高性能: Albumentations 以速度和內存效率為目標,因此它在圖像增強方面表現出色。這使得您能夠在訓練過程中高效地應用增強,不會成為訓練的瓶頸。
  • 靈活性: 您可以通過組合不同的增強操作來構建自定義的數據增強流水線。這使得您能夠根據任務和數據集的特點選擇適合的增強操作。
  • 易於集成: Albumentations 支持多種主流深度學習框架,可以方便地與您的模型訓練流程集成,無需複雜的配置。
  • 實時預覽: Albumentations 提供了實時預覽功能,可以在應用增強之前查看圖像的效果,以確保增強操作設置正確。
  • 多線程支持: 對於大規模數據集,Albumentations 支持多線程應用增強,加速數據準備過程。
  • 大量示例: Albumentations 提供了豐富的示例和文檔,幫助您了解每個增強操作的用法和效果。

使用範例

以下是一個使用 Albumentations 的簡單示例,演示如何將一些常見的增強操作應用於圖像數據:

https://github.com/albumentations-team/albumentations_examples/blob/master/notebooks/pytorch_semantic_segmentation.ipynb

import albumentations as A
from albumentations.pytorch import ToTensorV2
import cv2
import matplotlib.pyplot as plt

# 示例图像路径
image_path = 'path_to_your_image.jpg'
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 定义增强操作
transform = A.Compose([
    A.Resize(width=256, height=256),
    A.HorizontalFlip(p=0.5),
    A.VerticalFlip(p=0.5),
    A.Rotate(limit=30, p=0.5),
    A.RandomBrightnessContrast(p=0.2),
    A.Normalize(),
    ToTensorV2(),
])

# 应用增强
transformed_image = transform(image=image)['image']

# 可视化原始图像和增强后的图像
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image)
plt.title('Original Image')

plt.subplot(1, 2, 2)
plt.imshow(transformed_image[0])  # 转换后的图像是 PyTorch 张量,选择通道 0 进行显示
plt.title('Transformed Image')
plt.show()

發佈日期:

把標記轉成YOLO格式 – JSON2YOLO

JSON2YOLO介紹

官方網站: https://github.com/ultralytics/JSON2YOLO

JSON2YOLO 是一個用於將JSON格式標註數據轉換為YOLO格式標註數據的工具。 YOLO(You Only Look Once)是一種流行的目標檢測算法,它能夠在單次前向傳遞中同時預測圖像中的多個目標邊界框和類別。

在計算機視覺中,標註數據用於告知模型在圖像中的哪些位置存在目標以及目標的類別。 JSON和YOLO是兩種常用的標註數據格式,其中JSON通常用於描述目標的邊界框和類別,而YOLO格式則將目標的邊界框和類別信息結合在一起,以便更有效地訓練目標檢測模型。

JSON2YOLO 工具的主要目的是簡化將JSON格式標註數據轉換為YOLO格式標註數據的過程。通常,這種轉換涉及將目標的邊界框坐標映射到YOLO格式的網格單元,並將類別信息進行編碼。這使得標註數據能夠更好地適應YOLO模型的訓練和預測需求。

何時會需要做格式轉換

當我們使用別人的資料集,很有可能別人並不是使用YOLO格式去輸出資料集的,如果我們想要使用YOLO做訓練,勢必就得做標註資料的轉換,針對YOLO的狀況,就會需要使用這個轉換工具來將其他格式轉為YOLO標記格式

或者像是roboflow支持的輸出格式並不包含YOLO semgemt,所以也會需要先下載一般JSON格式的標記,再使用這個工具來做轉換

Roboflow支持的輸出格式

如何使用

接著再呼叫JSON2YOLO-master>python general_json2yolo.py

轉換好的資料就會出現在new_dir

發佈日期:

好用的線上標記工具-Roboflow

Roboflow介紹

官網: https://roboflow.com/

文檔: https://docs.roboflow.com/

Roboflow 是一個用於計算機視覺項目的平台,它旨在幫助開發人員和團隊更輕鬆地構建、訓練和部署計算機視覺模型。 Roboflow 提供了一系列工具和功能,使您能夠有效地處理圖像數據、訓練機器學習模型,並將這些模型集成到您的應用程序中。以下是 Roboflow 的一些主要特點和功能:

  • 數據預處理和清理: Roboflow 提供了數據預處理工具,可以幫助您對圖像數據進行清理、轉換和增強,以提高模型的訓練質量和性能。
  • 數據標註和註釋: 為了訓練計算機視覺模型,您需要標註圖像中的對象和特徵。 Roboflow 提供了圖像標註工具,可幫助您在圖像上繪製邊界框、進行分類標籤等操作。
  • 模型訓練: 您可以使用 Roboflow 訓練您的計算機視覺模型,選擇適當的架構並使用您的數據進行訓練。 Roboflow 支持多種常見的深度學習框架,如TensorFlow和PyTorch。
  • 模型評估和優化: 在訓練完成後,您可以使用 Roboflow 的評估工具來檢查模型在測試數據集上的表現,並進行模型的調優。
  • 模型部署: Roboflow 提供了將訓練好的模型部署到不同環境的選項,包括本地環境、移動設備和雲端。
  • 集成和 API: 您可以使用 Roboflow 的 API 將計算機視覺能力集成到您的應用程序中,以便自動處理圖像數據和執行預測。
  • 教程和資源: Roboflow 提供了豐富的教程、文檔和資源,幫助您了解計算機視覺的基礎知識和最佳實踐。

可讓團隊於線上共同標記圖片

這個功能是我覺得Roboflow大勝labelImg的原因,當團隊有很多人要負責標記時,這個工具可以非常方便的檢視、確認、共同標記。

可匯入現有的資料集及標記

Roboflow可以直接匯入以標記好的檔案,可以在線上去觀察以標記的資料的標記樣態,這些都是labelImg沒有辦法做到的,我們可以直接把含有標記和圖片的資料夾拉近網頁裡面,他會問你是否資料夾內的檔案全部放入,選擇Upload

就會可以看到已經標記好的狀況,我覺得這個功能在使用別人標記的圖檔時非常重要,才可以知道別人是如何去標記圖片的

線上做資料增強

Roboflow 提供了豐富的在線數據增強工具,用於處理圖像數據,改善數據集的多樣性,提高模型的泛化能力。數據增強是在保持圖像語義信息的前提下,通過應用各種變換和處理來生成多樣性的圖像,從而增加模型對於不同場景的適應能力。以下是 Roboflow 在線數據增強工具的一些功能和特點:

  • 旋轉和翻轉: 您可以輕鬆地對圖像進行旋轉、水平翻轉和垂直翻轉,從而生成不同角度和方向的圖像。
  • 縮放和裁剪: Roboflow 允許您調整圖像的尺寸、剪裁圖像以及生成不同分辨率的圖像,以增加模型對於不同大小的物體和場景的適應能力。
  • 亮度和對比度調整: 您可以調整圖像的亮度、對比度和飽和度,從而改變圖像的外觀和光照條件。
  • 噪聲和擾動: 添加噪聲、模糊效果和其他擾動可以幫助模型更好地應對真實世界中的噪聲和不確定性。
  • 顏色變換: 改變圖像的色彩分佈、色調和色溫,使模型能夠在不同的環境下進行準確的預測。
  • 隨機變換: Roboflow 提供了隨機化參數,可以在每次增強時以隨機方式應用不同的變換,從而生成更多樣化的數據。
  • 多模態增強: 對於多通道圖像(如RGB圖像),您可以單獨處理每個通道,或者應用通道之間的特定變換,以增加數據的多樣性。
  • 實時預覽: 在進行數據增強時,Roboflow 提供實時預覽功能,讓您可以在應用增強之前查看變換後的圖像。
  • 保存和導出: 您可以保存增強後的圖像,以便後續在模型訓練中使用。 Roboflow支持將增強後的數據導出到各種格式,如Yolo、COCO等。

按Generate可以做圖像預處理並選擇資料增強的方法,不過這邊圖片要輸出的若太多,就會要升級方案,免費方案沒辦法輸出破千張

線上建模

選擇Deploy頁籤,可以線上建模,並可以看到在測試資料及上的偵測狀況,我覺得最酷的是這一切都完全使用點、按就可以達成,完全no code