yolo 자동차 인식 프로그램
이 코드는 OpenCV의 딥 러닝 모듈(cv2.dnn)을 사용하여, YOLO(You Only Look Once) 딥 러닝 객체 감지 모델을 불러오는 과정입니다.
- cv2.dnn.readNet(weight_file, cfg_file) 함수는 가중치 파일(weight_file)과 설정 파일(cfg_file)을 읽어와서 딥 러닝 모델(net)을 생성합니다.
- weight_file은 미리 학습된 모델의 가중치(weight) 파일의 경로를 나타냅니다. 이 파일은 모델이 학습된 가중치 값을 포함하고 있습니다.
- cfg_file은 모델의 구성(configuration) 파일의 경로를 나타냅니다. 이 파일은 모델의 구조와 학습에 사용된 하이퍼파라미터(hyperparameters) 등의 정보를 포함하고 있습니다.
- net은 딥 러닝 모델 객체를 나타내는 변수입니다. net 객체에는 학습된 모델의 구조와 가중치 값이 포함되어 있습니다. 이 모델은 이미지나 비디오에서 객체 감지를 수행하는 데 사용됩니다.
이 코드는 YOLO 객체 감지 알고리즘에서 사용되는 네트워크에서 감지할 클래스 이름을 포함하고 있는 파일을 읽어와서, 해당 클래스들과 연관된 랜덤한 색상을 생성합니다.
- name_file은 클래스 이름을 포함하고 있는 파일의 경로입니다.
- with open(name_file, 'r') as f:은 name_file을 읽기 모드로 열고, 이를 f 객체에 할당합니다. with 구문을 사용하면 파일을 열고, 작업이 끝나면 자동으로 닫히게 됩니다.
- classes = [line.strip() for line in f.readlines()]은 f에서 읽어온 각 줄을 strip()하여 클래스 이름을 구성하는 리스트 classes에 저장합니다.
- layer_names = net.getLayerNames()는 딥러닝 모델의 레이어 이름들을 리스트 형태로 반환합니다.
- output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]는 객체 감지 결과를 출력하기 위한 레이어 이름들을 리스트 형태로 반환합니다.
- colors = np.random.uniform(0, 255, size=(len(classes), 3))는 classes 리스트의 길이와 같은 크기의 0에서 255 범위의 랜덤한 색상값을 생성하고, 이를 colors 배열에 저장합니다. 각 클래스마다 다른 랜덤한 색상을 지정하여, 객체 감지 결과를 시각적으로 구분할 수 있도록 합니다.
이 코드는 OpenCV의 dnn 모듈을 사용하여 이미지에서 객체 탐지를 수행하는 함수인 detectAndDisplay를 정의하고 있습니다.
해당 함수는 입력으로 이미지 frame을 받아들이고, net 객체(사전에 YOLOv3 모델을 로드하여 생성된 cv2.dnn_Net 객체)를 사용하여 frame에서 객체를 탐지합니다.
코드에서 사용된 cv2.dnn.blobFromImage 함수는 입력 이미지 frame을 전처리하는데 사용됩니다. 전처리 작업은 입력 이미지의 크기와 형식을 모델에 맞게 조정하고, 평균값을 빼거나 스케일링 등의 작업을 수행하여 모델의 입력 형식에 맞게 변경하는 작업입니다.
blobFromImage 함수에서는 다음과 같은 매개변수를 사용합니다.
- frame: 전처리할 이미지
- scalefactor: 입력 이미지의 크기 조정 비율
- size: 모델에 맞게 조정할 이미지의 크기
- mean: 입력 이미지에서 빼야 할 평균값
- swapRB: R, B 채널을 교환할 것인지 여부
- crop: 크롭(crop) 여부
그 다음, net.setInput 함수를 사용하여 blob을 모델의 입력으로 설정하고, net.forward 함수를 사용하여 YOLOv3 모델의 출력값을 계산합니다. output_layers는 모델의 출력 레이어 이름(들)을 저장하는 리스트입니다.
YOLOv3 모델은 3개의 출력 레이어를 가지며, 이 레이어들은 각기 다른 크기의 객체를 탐지합니다. 따라서, net.forward 함수는 모델의 3개 출력 레이어에서 나온 결과값들을 outs에 저장하고, outs를 사용하여 객체를 식별하고 경계 상자를 그리는 등의 작업을 수행합니다.
이 코드는 객체 감지 결과(outs)에서 각 객체의 정보를 추출하여 각 객체를 포함하는 bounding box의 좌표와 확률 등을 리스트(boxes, confidences, class_ids)에 저장하는 과정입니다.
- for out in outs:은 객체 감지 결과(outs)에서 각 객체의 정보를 추출하기 위해 outs를 반복(iterate)합니다.
- for detection in out:은 현재 객체(out)에서 각 detection(감지 결과)을 반복(iterate)합니다.
- scores = detection[5:]는 detection에서 5번 인덱스 이후의 값(각 클래스에 대한 확률)을 scores 변수에 저장합니다.
- class_id = np.argmax(scores)는 가장 높은 확률을 가진 클래스의 인덱스(class_id)를 찾습니다.
- confidence = scores[class_id]는 가장 높은 확률을 가진 클래스의 확률(confidence)을 찾습니다.
- if confidence > min_confidence:은 추출한 객체의 확률이 min_confidence보다 큰 경우에만 객체를 포함하는 bounding box 정보를 추출합니다.
- center_x, center_y, w, h는 detection에서 추출한 객체의 중심 좌표와 폭/높이 정보를 계산합니다.
- x, y는 bounding box의 좌측 상단 좌표를 계산합니다.
- boxes, confidences, class_ids 리스트에 bounding box의 좌표와 확률 등을 각각 추가합니다. 이렇게 함으로써 각 객체의 정보를 리스트에 저장할 수 있습니다.
이 코드는 OpenCV 라이브러리를 사용하여 동영상 파일을 읽어와서, 각 프레임에 대해 객체 감지 알고리즘을 적용하고 결과를 출력하는 루프를 수행합니다.
- cap = cv2.VideoCapture(file_name)은 file_name으로 지정한 동영상 파일을 열어 cap 변수에 저장합니다.
- if not cap.isOpened:은 cap 객체가 정상적으로 열렸는지 확인합니다. 만약 열리지 않았을 경우, 오류 메시지를 출력하고 프로그램을 종료합니다.
- while True:은 무한 루프를 시작합니다. 이 루프에서는 cap.read() 메소드를 사용하여 동영상 파일에서 프레임을 읽어옵니다.
- ret, frame = cap.read()은 cap 객체에서 다음 프레임을 읽어와 frame 변수에 저장합니다. ret은 읽기가 성공적으로 이루어졌는지를 나타내는 Boolean 값입니다.
- if frame is None:은 프레임이 정상적으로 읽혀지지 않은 경우에 대한 예외 처리를 수행합니다. 프레임이 없는 경우, 오류 메시지를 출력하고 루프를 종료합니다.
- detectAndDisplay(frame)은 현재 프레임에 대해 객체 감지 알고리즘을 적용하고 결과를 출력하는 함수입니다. frame을 함수의 인자로 전달하여 실행합니다. 이 함수는 frame에 대해 객체 감지 알고리즘을 수행하고, 결과를 프레임에 표시합니다. 이후 다음 프레임에 대해 반복적으로 실행됩니다.
출력 결과물