benctw / TVideo

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TVideo

TVideo
├─ config.py
├─ controllers
│  └─ setting.py
├─ main.py
├─ models
│  ├─ communicate.py
│  ├─ CVModel
│  │  ├─ CVModel.py
│  │  └─ __init__.py
│  ├─ helper.py
│  ├─ RESAModel
│  │  ├─ RESAModel.py
│  │  └─ __init__.py
│  ├─ TVideo
│  │  ├─ Process.py
│  │  ├─ Record.py
│  │  ├─ TVideo.py
│  │  └─ __init__.py
│  ├─ YoloModel
│  │  ├─ YoloModel.py
│  │  └─ __init__.py
│  └─ __init__.py
├─ openh264-1.8.0-win64.dll
├─ README.md
├─ requirements.txt
├─ static
│  ├─ ico
│  ├─ img
│  ├─ model
│  │  ├─ lp.names
│  │  └─ lp_yolov4.cfg
│  └─ preset
│     └─ defaultSetting.json
├─ store
│  ├─ output
│  ├─ records
│  │  └─ lastRecordId.txt
│  └─ settings.json
└─ views
   └─ lang
      ├─ standard.json
      └─ zh-TW.json

structure


Command

檢測違規行為

$ python main.py detect VIDEOPATH NUMBER VIOLATIONTYPE

尋找車牌號碼

$ python main.py findNumber VIDEOPATH NUMBER 

VIDEOPATH: 影片路徑

NUMBER: 車牌號碼

VIOLATIONTYPE: 違規行為種類


some utils

加載 coco 模型

coco = YoloModel(
      namesPath   = 'coco.names',
      configPath  = 'yolov3.cfg',
      weightsPath = 'yolov3.weights',
      inputWidth  = '416',
      inputHeight = '416'
)

辨識圖片

img = cv2.imread('image path')

boxes, _, _ = coco.detect(img)
cv2.rectangle(img, (boxes[0][:2]), (boxes[0][2:]), (0, 0, 255), 2)

cv2.imshow(img)
cv2.waitKey(0)

辨識圖片(棄用的方法,還是可以嘗試一下下)

img = cv2.imread('image path')

detectResult = coco.detectImage(img)
detectResult.calcNMS()
resImg = detectResult.drawBoxes(detectResult.NMSIndexs, detectResult.msg)

cv2.imshow(resImg)
cv2.waitKey(0)

Developer's Documentation

Table of Contents


class CVModel

用於輸入為影像的模型的抽象對象

__init__(self) -> None

@staticmethod

getFrames(videoCapture: cv2.VideoCapture) -> List[np.ndarray]

獲取 videoCapture 中每一幀的影像

getCenterPosition(points: List[List[int]]) -> List[int]

獲取中心點位置。

boxArea(box: List[int]) -> float

計算 box 的面積。

IoU(rect1: List[int], rect2: List[int]) -> float

計算 rect1rect2 的 IoU。

crop(image: np.ndarray, box: List[int]) -> np.ndarray

根據 box 的位置裁剪 image,返回新的圖像。

expand(box: List[int], px: int) -> List[int]

擴大 box 的長寬 px 像素。

offset(box: List[int], x: int, y: int) -> List[int]

偏移 box 的整體位置。

overexPose(image: np.ndarray) -> np.ndarray

@abstractmethod

detectImage(self, image: cv.Mat) -> DetectResult

必須重新定義該方法。

定義:利用模型辨識傳入之圖像並回傳 DetectResult 的類型

Instance Method

detectVideo(self, videoCapture: cv.VideoCapture, interval: int = 1) -> List[DetectResult]

interval : 根據該值的間隔採樣辨識 videoCapture 中的幀。


helper

class dotdict(dict)

讓 dict 可以用 . 取值。

@staticmethod

deep(d: Dict[Any]) -> Dict[Any]

深度讓 dict 可以以 . 取值賦值。

imshow(img: np.ndarray, title = '')

以窗口顯示 img 圖像。

saveVideo(images, path, fps = 30, fourccType = 'mp4v')

存儲 images 圖像列表到 path 路徑上。


class YoloModel(CVModel)

__init__(
       self, 
       namesPath     : str, 
       configPath    : str, 
       weightsPath   : str, 
       confidence    : float = 0.5, 
       threshold     : float = 0.2, 
       minConfidence : float = 0.2
)

加載模型

namesPath : .names 文件的路徑

configPath : .cfg 文件的路徑

weightsPath : .weights 文件的路徑

預設:

confidence : 至少要在此信心以上

threshold : 閥值, 可重疊程度

minConfidence : 最小信心

加載 .names 文件中的 label 和定義各 label 的顔色

@staticmethod

yoloFormatToTwoPoint(centerX: int, centerY: int, width: int, height: int) -> List[int, int, int, int]

把中心點坐標和長寬轉換成左上角和右下角點的坐標。

返回 [p1x, p1y, p2x, p2y]

Instance Method

detect(self, image: np.ndarray) -> Tuple[List[List[int]], List[int], List[float]]

使用模型辨識圖像,返回 boxes, classIDs, confidences

detectImage(self, image: np.ndarray) -> DetectResult

使用模型辨識圖像(棄用)

showConfig(self) 

未定義


class TObj(Enum)

Undefined

Vehicle

LicensePlate

TrafficLight

Lane


class VehicleData

一載具的數據

__init__(self, image: np.ndarray, box: List, confidence: float, type: str)
calc(self)

class LicensePlateData

一車牌的數據

__init__(self, image: np.ndarray, box: List, confidence: float)
calc(self)

計算數據

cornerPoints : 車牌的四個角點

correctImage : 矯正的圖像

centerPosition : 車牌質心點位置

number : 車牌號碼

@staticmethod

getCornerPoints(image: np.ndarray) -> List

獲取車牌的4個角點

correct(image: np.ndarray, cornerPoints, w: int, h: int) -> np.ndarray

根據 cornerPoints 的 4 個角點矯正車牌圖片 image 返回新圖片

getNumber(image: np.ndarray) -> str

獲取辨識 image 得到的車牌號碼,根據台灣車牌號碼規則


class TrafficLightState(Enum)

紅綠燈狀態

unknow

red

yellow

green


class TrafficLightData

__init__(self,image: np.ndarray, box: List, confidence: float)
calc(self)

計算數據

state : 紅綠燈狀態

@staticmethod

getTrafficLightColor(image: np.ndarray) -> Tuple[TrafficLightState, np.ndarray]

辨識 image 的紅綠燈狀態。

threePartOfTrafficLight(image: np.ndarray) -> List[np.ndarray]

將 Blur 圖片分三等份

cntsOfeachPart(threePartImgs: List[np.ndarray]) -> TrafficLightState
ColorDectect(image: np.ndarray) -> TrafficLightState

class LaneData

車道線數據

__init__(self, image: np.ndarray, lane: List[List[int]], confidence: float)
calc(self)

計算數據

vanishingPoint : 消失點

getVanishingPoint

根據車道線獲取消失點


class TFrameData

一幀的數據

def __init__(self, frame: np.ndarray)
getTargetLicensePlatePosition(self, targetLicensePlateCodename) -> Union[List[int], None]

獲取目標車牌的位置


class Direct(Enum)

left : 向左

right : 向右

straight : 直行


class ProcessState(Enum)

next : 繼續下一個 Process

nextLoop : 繼續下一個 Schedule

stop : 結束當前 Schedule


class TVideo

一影片的數據

__init__(
   self, 
   path: str, 
   number: str = '', 
   lastCodename : int = 0
)

@staticmethod

__getVideoDetails(path: str) -> Any:

獲取 path 的影片的詳細數據

返回 list 中順序包含 frames : 影片幀的圖像 width : 影片寬度 height : 影片高度 fps frameCount : 影片幀的數目

runProcess(self, schedule: Callable[[List[indexType], int], indexType], *processes: ForEachFrameData, maxTimes: int = None)
findCorresponding(self, frameData1: TFrameData, frameData2: TFrameData, threshold: float = 0.1)

計算前幀 frameData1 與 後幀 frameData2 兩幀之間辨識結果的 boxes 的關係,位置與形狀接近會認為為同一物品,給予與前幀物品一樣的 codename,如果前幀沒有 codename 或沒對應物品會給予新的 codename。 計算方法是計算兩幀 box 之間的 IoU ,IoU 值大於 threshold 並且為計算的所有 box 中最大的,為同一物品。

newCodename(self) -> int

使用該方法獲取新 codename

getTargetLicensePlatePath(self) -> List[List[int]]

獲取目標車牌在影片中的路徑,返回車牌中心點坐標組成的 listlist 長度同影片幀數目 沒路徑位置的幀會儲存 Node

getVaildTargetLicensePlatePath(self) -> List[List[int]]

(未完善)

獲取多段目標車牌在影片中的路徑。

save(self, path: str, start: int = None, end: int = None, fps: float = None, fourccType: str = 'avc1')

儲存 framesData 中每一個 frame 成為影片。

path : 儲存在該路徑,路徑包含影片名稱和後綴

start : 從該幀數開始裁切

end : 裁切到該幀數

fps : 幀率,默認與原影片相同

fourccType : 視頻數據流格式,默認 avc1


class TVideoSchedule

@staticmethod

once(indexs: List[indexType], frameCount: int) -> indexType

處理一次。

index(i: int, times: int = 1)

處理第 itimes 次。

forEach(indexs: List[indexType], frameCount: int) -> indexType

順序處理每一幀。

forEachStep(step: int)

間隔 step 幀處理一幀。

range(start: int, end: int, step)

處理從 startend 每一幀。

forEachStepAll(step: int)

間隔 step 幀處理一幀,處理到最後,回到開頭從第 2 幀間隔 step 幀處理一幀,以此類推,直到影片全部幀都處理過。

random(indexs: List[indexType], frameCount: int) -> indexType

打亂處理的順序,處理全部幀,不會重複處理。

randomIndex(indexs: List[indexType], frameCount: int) -> indexType

隨機挑選一幀處理。

forward(start: int, length: int = None, step: int = 1)

start 開始順序間隔 step 處理,處理到 length 幀後。 length 包含跳過的幀數,length 默認到影片結束。

backward(start: int, length: int = None, step: int = -1)

start 開始順序間隔 step 處理,處理到 length 幀後。 length 包含跳過的幀數,length 默認到影片開始。


class Process

__init__(self, process)

@staticmethod

showIndex(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

打印出當前處理中的幀數。

yolo(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

使用載入之 yolo 模型辨識。

calcLicensePlateData(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

計算車牌的額外數據。

calcCenterPosition(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

計算車牌的中心點位置。

findCorresponding(reverse: bool = False)

計算當前幀與前一幀的物件的關係,如果位置與形狀接近,會標記相同的 codename 屬性。

reverse : 是否兩幀相反比較,用於在向前推敲關係的時候。

hasCorrespondingTargetLicensePlate(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

是否有對應的車牌號碼。

drawBoxes(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

繪畫模型辨識到物品的矩形。

drawPath(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

繪畫物品的路徑。

findTargetNumber(number: str = None)

尋找物品中是否有對應的車牌號碼 number

correspondingTrafficLights(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState
drawCurrentTrafficLightState(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

繪畫對應拍攝者所在車道的紅綠燈狀態在輸出圖像中。

cocoDetect(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

使用 coco 模型對幀辨識。

updateRangeOfTargetLicensePlate(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

更新對應車牌號碼所在的範圍。

calcPathDirection(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState

計算車輛的去向,左轉、直行或右轉。

intersectionOfLPAndTL(frameData: TFrameData, frameIndex: int, tvideo: TVideo) -> ProcessState


class DetectResult() (棄用)

__init__(
       self, 
       image      : np.ndarray, 
       labels     : List[str] = [], 
       threshold  : float     = 0.2, 
       confidence : float     = 0.2, 
       colors     : List      = None
)

classIDs : 辨識到的多個分類

boxes : 多個分類的邊框位置

confidences : 多個分類的可信程度

boxes 中每個位置應該儲存的的資料:

該分類在圖上的 [p1x, p1y, p2x, p2y] ,分別為左上角 p1x, p1y 和右下角 p2x, p2y 點的位置

三個參數中同 index 的值為同一個結果

@staticmethod

checkColor(color)
getAutoSelectColors(self)
setColors(self, colors)
setColor(self, index, color)
add(self, classID, box, confidence)

用於模型的辨識結果

@property
count(self)
hasResult(self)

是否有至少一個結果

getNMSDetectResult(self)
calcNMS(self)
@property
AllIndex(self)
crop(self, boxIndex)

boxes 中的第 boxIndex 個裁剪 image 圖片

cropAll(self, classID, indexs)
table(self)

打印出列表

msg(self, classID, _, confidence, i)
drawBoxes(self, indexs, callbackReturnText = None)
draw(self, indexs, callbackCroppedImage)

class DetectResults() (棄用)

__init__(self, labels = [], colors = None)
add(self, detectResult)
setColors(self, colors)
drawBoxes(self, indexs, callbackReturnTexts = None)
loop(self, indexs, callback)
draw(self, indexs, callbackCroppedImage)
table(self)

待續 ...

About


Languages

Language:Python 100.0%