欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python目標(biāo)檢測實現(xiàn)黑花屏分類任務(wù)示例

 更新時間:2022年07月23日 15:08:41   作者:opentest-oper@#  
這篇文章主要為大家介紹了python目標(biāo)檢測實現(xiàn)黑花屏分類任務(wù)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

背景

視頻幀的黑、花屏的檢測是視頻質(zhì)量檢測中比較重要的一部分,傳統(tǒng)做法是由測試人員通過肉眼來判斷視頻中是否有黑、花屏的現(xiàn)象,這種方式不僅耗費人力且效率較低。

為了進一步節(jié)省人力、提高效率,一種自動的檢測方法是大家所期待的。目前,通過分類網(wǎng)絡(luò)模型對視頻幀進行分類來自動檢測是否有黑、花屏是比較可行且高效的。

然而,在項目過程中,視頻幀數(shù)據(jù)的收集比較困難,數(shù)據(jù)量較少,部分花屏和正常屏之間差異不夠明顯,導(dǎo)致常用的分類算法難以滿足項目對分類準(zhǔn)確度的要求。

因此本文嘗試了一種利用目標(biāo)檢測算法實現(xiàn)分類的方式,幫助改善單純的分類的算法效果不夠理想的問題。

核心技術(shù)與架構(gòu)圖

一般分類任務(wù)的流程如下圖,首先需要收集數(shù)據(jù),構(gòu)成數(shù)據(jù)集;

并為每一類數(shù)據(jù)定義一個類型標(biāo)簽,例如:0、1、2;再選擇一個合適的分類網(wǎng)絡(luò)進行分類模型的訓(xùn)練,圖像分類的網(wǎng)絡(luò)有很多,常見的有 VggNet, ResNet,DenseNet 等;

最后用訓(xùn)練好的模型對新的數(shù)據(jù)進行預(yù)測,輸出新數(shù)據(jù)的類別。

目標(biāo)檢測任務(wù)的流程不同于分類任務(wù),其在定義類別標(biāo)簽的時候還需要對目標(biāo)位置進行標(biāo)注;

目標(biāo)檢測的方法也有很多,例如 Fast R-CNN, SSD,YOLO 等;

模型訓(xùn)練的中間過程也比分類模型要復(fù)雜,其輸出一般為目標(biāo)的位置、目標(biāo)置信度以及分類結(jié)果。

由于分類算法依賴于一定量的數(shù)據(jù),在項目實踐中,數(shù)據(jù)量較少或圖像類間差異較小時,傳統(tǒng)分類算法效果不一定能滿足項目需求。這時,不妨考慮用目標(biāo)檢測的方式來做 ‘分類’。

接下來以 Yolov5 為例來介紹如何將目標(biāo)檢測框架用于實現(xiàn)單純的分類任務(wù)。

技術(shù)實現(xiàn)

除了分類之外,目標(biāo)檢測還可以從自然圖像中的大量預(yù)定義類別中識別出目標(biāo)實例的位置。

大家可能會考慮目標(biāo)檢測模型用于分類是不是過于繁瑣或者用目標(biāo)檢測框架來做單純的分類對代碼的修改比較復(fù)雜。

這里,我們將用一種非常簡單的方式直接在數(shù)據(jù)標(biāo)注和輸出內(nèi)容上稍作修改就能實現(xiàn)單純的分類了。接下來將介紹一下具體實現(xiàn)方法:

1.數(shù)據(jù)的標(biāo)注

實現(xiàn)目標(biāo)檢測時,需要對數(shù)據(jù)中的目標(biāo)進行標(biāo)注,這一過程是十分繁瑣的。但在用于純粹的分類上可以將這一繁瑣過程簡單化,無需手動標(biāo)注,直接將整張圖作為我們的目標(biāo),目標(biāo)中心也就是圖像的中心點。

只需讀取整張圖像,獲得其長、寬以及中心點的坐標(biāo)就可以完成標(biāo)注了。并定義好類別標(biāo)簽,正常屏為 0,花屏為:1,黑屏為 2。具體實現(xiàn)如下:

OBJECT_DICT = {"Normalscreen": 0, "Colorfulscreen": 1, "Blackscreen": 2}
def parse_json_file(image_path):
    imageName = os.path.basename(image_path).split('.')[0]
    img = cv2.imread(image_path)
    size = img.shape
    label = image_path.split('/')[4].split('\\')[0]
    label = OBJECT_DICT.get(label)
    imageWidth = size[0]
    imageHeight = size[1]
    label_dict = {}
    xmin, ymin = (0, 0)
    xmax, ymax = (imageWidth, imageHeight)
    xcenter = (xmin + xmax) / 2
    xcenter = xcenter / float(imageWidth)
    ycenter = (ymin + ymax) / 2
    ycenter = ycenter / float(imageHeight)
    width = ((xmax - xmin) / float(imageWidth))
    heigt = ((ymax - ymin) / float(imageHeight))
    label_dict.update({label: [str(xcenter), str(ycenter), str(width), str(heigt)]})
    label_dict = sorted(label_dict.items(), key=lambda x: x[0])
    return imageName, label_dict

2.訓(xùn)練過程

該過程與目標(biāo)檢測的訓(xùn)練過程一致,不需要進行大的修改,只需要根據(jù)數(shù)據(jù)集的特性對參數(shù)進行調(diào)整。

# 加載數(shù)據(jù),獲取訓(xùn)練集、測試集圖片路徑
with open(opt.data) as f:
    data_dict = yaml.load(f, Loader=yaml.FullLoader)  
    with torch_distributed_zero_first(rank):
        check_dataset(data_dict) 
train_path = data_dict['train']
test_path = data_dict['val']
Number_class, names = (1, ['item']) if opt.single_cls else (int(data_dict['nc']), data_dict['names']) 
# 創(chuàng)建模型
model = Model(opt.cfg, ch=3, nc=Number_class).to(device)
# 學(xué)習(xí)率的設(shè)置
lf = lambda x: ((1 + math.cos(x * math.pi / epochs)) / 2) * (1 - hyp['lrf']) + hyp['lrf']  
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lf)
# 訓(xùn)練
for epoch in range(start_epoch, epochs):  
model.train()

3.損失的計算

損失由三部分組成,邊框損失,目標(biāo)損失,分類損失,具體如下:

def compute_loss(p, targets, model):
    device = targets.device
    loss_cls, loss_box, loss_obj = torch.zeros(1, device=device), torch.zeros(1, device=device), torch.zeros(1, device=device)
    tcls, tbox, indices, anchors = build_targets(p, targets, model) 
h = model.hyp
    # 定義損失函數(shù)
    BCEcls = nn.BCEWithLogitsLoss(pos_weight=torch.Tensor([h['cls_pw']])).to(device)
    BCEobj = nn.BCEWithLogitsLoss(pos_weight=torch.Tensor([h['obj_pw']])).to(device)
    cp, cn = smooth_BCE(eps=0.0)
    # 損失
    nt = 0  
    np = len(p) 
    balance = [4.0, 1.0, 0.4] if np == 3 else [4.0, 1.0, 0.4, 0.1] 
for i, pi in enumerate(p): 
        image, anchor, gridy, gridx = indices[i]  
        tobj = torch.zeros_like(pi[..., 0], device=device) 
        n = image.shape[0]  
        if n:
            nt += n  # 計算目標(biāo)
            ps = pi[anchor, image, gridy, gridx]
            pxy = ps[:, :2].sigmoid() * 2. - 0.5
            pwh = (ps[:, 2:4].sigmoid() * 2) ** 2 * anchors[i]
            predicted_box = torch.cat((pxy, pwh), 1).to(device)                    giou = bbox_iou(predicted_box.T, tbox[i], x1y1x2y2=False, CIoU=True)                 
       loss_box += (1.0 - giou).mean() 
            tobj[image, anchor, gridy, gridx] = (1.0 - model.gr) + model.gr *   giou.detach().clamp(0).type(tobj.dtype) 
            if model.nc > 1:
                t = torch.full_like(ps[:, 5:], cn, device=device)
                t[range(n), tcls[i]] = cp
                loss_cls += BCEcls(ps[:, 5:], t)  
        loss_obj += BCEobj(pi[..., 4], tobj) * balance[i]  
    s = 3 / np
    loss_box *= h['giou'] * s
    loss_obj *= h['obj'] * s * (1.4 if np == 4 else 1.)
    loss_cls *= h['cls'] * s
    bs = tobj.shape[0]
    loss = loss_box + loss_obj + loss_cls
    return loss * bs, torch.cat((loss_box, loss_obj, loss_cls, loss)).detach()

4.對輸出內(nèi)容的處理

進行預(yù)測時,會得到所有檢測到的目標(biāo)的位置(x,y,w,h),objectness 置信度和分類結(jié)果。由于最終目的是對整張圖進行分類,可以忽略位置信息,重點考慮置信度和分類結(jié)果:將檢測到的目標(biāo)類別作為分類結(jié)果,如果同時檢測出多個目標(biāo),可以將置信度最大的目標(biāo)的類別作為分類結(jié)果。代碼如下:

def detect(opt,img):
    out, source, weights, view_img, save_txt, imgsz = \
        opt.output, img, opt.weights, opt.view_img, opt.save_txt, opt.img_size
    device = select_device(opt.device)
    half = device.type != 'cpu'
    model = experimental.attempt_load(weights, map_location=device)
    imgsz = check_img_size(imgsz, s=model.stride.max())
    if half:
        model.half()
    img = letterbox(img)[0]
    img = img[:, :, ::-1].transpose(2, 0, 1)
    img = np.ascontiguousarray(img)
    img_warm = torch.zeros((1, 3, imgsz, imgsz), device=device)
    _ = model(img_warm.half() if half else img_warm) if device.type != 'cpu' else None 
    img = torch.from_numpy(img).to(device)
    img = img.half() if half else img.float()
    img /= 255.0
    if img.ndimension() == 3:
        img = img.unsqueeze(0)
    pred = model(img, augment=opt.augment)[0]
    # 應(yīng)用非極大值抑制
    pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, classes=opt.classes, agnostic=opt.agnostic_nms)
    # 處理檢測的結(jié)果
    for i, det in enumerate(pred): 
        if det is not None and len(det):
            det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img.shape).round()
            all_conf = det[:, 4]
            if len(det[:, -1]) > 1:
                ind = torch.max(all_conf, 0)[1]
                c = torch.take(det[:, -1], ind)
detect_class = int(c)
            else:
                for c in det[:, -1]:
                    detect_class = int(c)
            return detect_class

效果展示

為了將視頻幀進行黑、花屏分類,測試人員根據(jù)經(jīng)驗將屏幕分為正常屏(200 張)、花屏(200 張)和黑屏(200 張)三類,其中正常屏幕標(biāo)簽為 0,花屏的標(biāo)簽為 1,黑屏的標(biāo)簽為 2。

為了進一步說明該方法的有效性,我們將基于 Yolov5 的 ‘分類’ 效果與 ResNet 分類效果做了對比。根據(jù)測試人員對 ResNet 分類效果的反饋來看,ResNet 模型容易將正常屏與花屏錯誤分類,例如,下圖被測試人員定義為正常屏:

ResNet 的分類結(jié)果為 1,即為花屏,顯然,這不是我們想要的結(jié)果。

基于 Yolov5 的分類結(jié)果為 0,即為正常屏,這是我們所期待的結(jié)果。

同時,通過對一批測試數(shù)據(jù)的分類效果來看,Yolov5 的分類效果比 ResNet 的分類準(zhǔn)確度更高,ResNet 的分類準(zhǔn)確率為 88%,而基于 Yolov5 的分類準(zhǔn)確率高達 97%。

總結(jié)

對于較小數(shù)據(jù)集的黑、花屏的分類問題,采用 Yolov5 來實現(xiàn)分類相較于 ResNet 的分類效果會更好一些。當(dāng)我們在做圖像分類任務(wù)時,純粹的分類算法不能達到想要的效果時,不妨嘗試一下用目標(biāo)檢測框架來分類吧!雖然過程稍微復(fù)雜一些,但可能會有不錯的效果。

目前目標(biāo)檢測框架有很多,用它們完成分類任務(wù)的處理方式大致和本文所描述的類似,可以根據(jù)數(shù)據(jù)集的特征選擇合適目標(biāo)檢測架構(gòu)來實現(xiàn)分類。

本文主要介紹了如何將現(xiàn)有的目標(biāo)檢測框架直接用于單純的圖像分類任務(wù),當(dāng)然,為了使得結(jié)構(gòu)更簡潔,也可以將目標(biāo)檢測中的分類網(wǎng)絡(luò)提取出來用于分類,更多關(guān)于python目標(biāo)檢測黑花屏分類的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用Python的time庫格式化時間的方法

    使用Python的time庫格式化時間的方法

    通過使用Python的time庫,我們可以方便地進行時間處理、格式化、解析和計算等操作,本文介紹了time庫的一些常見功能和使用方法,包括格式化時間、解析時間戳、獲取當(dāng)前時間、計算時間差等,感興趣的朋友一起看看吧
    2023-11-11
  • Python 冒泡,選擇,插入排序使用實例

    Python 冒泡,選擇,插入排序使用實例

    這里簡單介紹了下Python中冒泡,選擇,插入排序的使用方法,推薦給需要的小伙伴們參考下。
    2015-02-02
  • python數(shù)字圖像處理之基本圖形的繪制

    python數(shù)字圖像處理之基本圖形的繪制

    這篇文章主要為大家介紹了python數(shù)字圖像處理之基本圖形的繪制,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Python列表倒序輸出及其效率詳解

    Python列表倒序輸出及其效率詳解

    在本篇文章里小編給大家整理的是關(guān)于Python列表倒序輸出及其效率詳解內(nèi)容,需要的朋友們學(xué)習(xí)下。
    2020-03-03
  • Python3如何根據(jù)函數(shù)名動態(tài)調(diào)用函數(shù)

    Python3如何根據(jù)函數(shù)名動態(tài)調(diào)用函數(shù)

    這篇文章主要介紹了Python3如何根據(jù)函數(shù)名動態(tài)調(diào)用函數(shù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Python中subprocess模塊的用法詳解

    Python中subprocess模塊的用法詳解

    這篇文章主要介紹了Python中subprocess模塊的用法詳解,subprocess是Python 2.4中新增的一個模塊,它允許你生成新的進程,連接到它們的 input/output/error 管道,并獲取它們的返回狀態(tài)碼,這個模塊的目的在于替換幾個舊的模塊和方法,需要的朋友可以參考下
    2023-08-08
  • Django保護敏感信息的方法示例

    Django保護敏感信息的方法示例

    這篇文章主要介紹了Django保護敏感信息的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • 使用 prometheus python 庫編寫自定義指標(biāo)的方法(完整代碼)

    使用 prometheus python 庫編寫自定義指標(biāo)的方法(完整代碼)

    這篇文章主要介紹了使用 prometheus python 庫編寫自定義指標(biāo)的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • python學(xué)習(xí)實操案例(五)

    python學(xué)習(xí)實操案例(五)

    這篇文章主要介紹了pyth學(xué)習(xí)實操案例,主要分享的小練習(xí)有我的咖啡館你做主、顯示2019中超聯(lián)賽中前五名排行、模擬手機通訊錄,適合初學(xué)者,需要的小伙伴可以參考一下
    2022-02-02
  • Django框架中方法的訪問和查找

    Django框架中方法的訪問和查找

    這篇文章主要介紹了Django框架中方法的訪問和查找,包括各種列表和字典的查找,是Python的Django框架使用的必備技巧,需要的朋友可以參考下
    2015-07-07

最新評論