728x90
반응형
YOLO - Camera 객체탐지
사용할 라이브러리
import cv2
import numpy as np
데이터 읽어들이기
- 웹캠 신호 받기
- 어떤 카메라를 사용할지 채널 선택
- 여러개의 카메라가 있으면, 카메라 별로 번호가 부여된다.
- 내 PC에 1개만 연결되어 있다면, 0번 카메라 번호가 부여된다.
VideoSignal = cv2.VideoCapture(0) VideoSignal
Yolo 모델 생성하기
YOLO_net = cv2.dnn.readNet("./yolo/config/yolov2-tiny.weights",
"./yolo/config/yolov2-tiny.cfg")
YOLO_net

라벨링 명칭(이름 ) 데이터 읽어들이기
# - coco.names : 인식(감지)된 객체의 레이블 명칭(이름)이 저장된 파일
''' 저장할 변수 정의 '''
classes = []
# open() : 파일 열기
# - 모드 : r 읽기모드, w 쓰기모드, b 바이너리
# as(별칭) f에는 열려있는 파일 정보가 담겨있음
with open("./yolo/config/coco.names", "r") as f :
# strip() : 왼쪽 오른쪽 공백제거
# readlines() : 파일 내에 문장들을 행단위로 모두 읽어들이기
classes = [line.strip() for line in f.readlines()]
classes

출력계층 이름 추출하기
''' YOLO 레이어 전체 추출 '''
layer_names = YOLO_net.getLayerNames()
''' YOLO 출력 레이어(계층)만 추출 '''
output_layer = [layer_names[i - 1] for i in YOLO_net.getUnconnectedOutLayers()]
layer_names, output_layer

윈도우 창 관리 영역 : 카메라 영상 처리 영역
import cv2
import numpy as np
VideoSignal = cv2.VideoCapture(0)
YOLO_net = cv2.dnn.readNet("./yolo/config/yolov2-tiny.weights",
"./yolo/config/yolov2-tiny.cfg")
classes = []
# open() : 파일 열기
# - 모드 : r 읽기모드, w 쓰기모드, b 바이너리
# as(별칭) f에는 열려있는 파일 정보가 담겨있음
with open("./yolo/config/coco.names", "r") as f :
# strip() : 왼쪽 오른쪽 공백제거
# readlines() : 파일 내에 문장들을 행단위로 모두 읽어들이기
classes = [line.strip() for line in f.readlines()]
''' YOLO 레이어 전체 추출 '''
layer_names = YOLO_net.getLayerNames()
''' YOLO 출력 레이어(계층)만 추출 '''
output_layer = [layer_names[i - 1] for i in YOLO_net.getUnconnectedOutLayers()]
'''
대표 윈도우 설정
- 윈도우 창 관리는 이름으로 한다.
'''
cv2.namedWindow("YOLO3_CM_01")
'''
카메라를 통한 영상처리 시에는 윈도우 창을 계속 띄어 놓아야 한다.
- 정지 옵션(윈도우 창 닫기)은 필수
'''
while True :
'''
카메라에서 영상 읽어들이기 : read() 함수 사용
- 영상파일 또는 카메라로부터 프레임을 읽어오는 역할 수행
* ret : 읽어들이는 프레임이 있는지 여부 판단(True or False)
: 더 이상 읽어들일 프레임이 없으면 False가 됨
* frame : 실제로 읽어들이는 프레임(이미지) 자체
: 더 이상 읽어들일 프레임이 없으면 None이 됨
: 우리가 사용할 변수
'''
ret, frame = VideoSignal.read()
''' frame 정보에서 높이, 너비, 채널(흑백 또는 컬러) 추출하기 '''
h, w, c = frame.shape
''' --------------------------------------------------------- '''
''' BLOB 데이터 구조화 '''
blob = cv2.dnn.blobFromImage(
### 카메라에서 읽어들인 frame(이미지) 데이터
image = frame,
### 이미지 픽셀 값 정규화(스케일링)
scalefactor = 1/255.0,
### Yolo 모델이 사용할 크기로 조정
size=(416, 416),
### BRG, RGB 선택
# - True이면 OpenCV의 기본 BGR 생상 순서를 RGB로 변경
swapRB=True,
### 위에 size로 조정 후 어떻게 할지 결정
# - True이면 잘라내기
# - Fasle이면 size 전체 조정하기
crop=False
)
''' YOLO 입력 데이터로 넣어주기 '''
YOLO_net.setInput(blob)
''' YOLO모델에 출력계층 이름을 알려주고, 출력 결과 받아오기 '''
outs = YOLO_net.forward(output_layer)
''' 라벨(명칭, 이름) 담을 리스트 변수 '''
class_ids = []
''' 인식률(정확도) 담을 리스트 변수 '''
confidences = []
''' 바운딩 박스의 좌표를 담을 리스트 변수 '''
boxes = []
''' 출력 결과 여러개(인식된 객체 여러개)'''
for out in outs :
''' 실제 객체 인식 데이터 처리 '''
for detection in out :
''' 인식 데이터의 인식률(정밀도) '''
scores = detection[5:]
''' 인식률(정밀도)가 가장 높은 인덱스 위치 얻기 : 라벨(명칭, 이름)의 위치값 '''
class_id = np.argmax(scores)
''' 인식률(정밀도) 값 추출하기 : class_id의 인덱스 번호 위치값이 정밀도 '''
confidence = scores[class_id]
''' 정밀도가 50% 이상인 경우만 처리 : 기준은 자유롭게 정의 '''
if confidence > 0.5 :
''' 중앙값의 좌표 비율에 실제 너비로 연산하여 중앙 x값 추출 '''
center_x = int(detection[0] * w)
''' 중앙값의 좌표 비율에 실제 높이로 연산하여 중앙 y값 추출 '''
center_y = int(detection[1] * h)
''' 바운딩 박스의 실제 너비와 높이 계산하기 '''
dw = int(detection[2] * w)
dh = int(detection[3] * h)
''' 바운딩 박스의 시작 좌표(x, y) 계산하기 '''
x = int(center_x - dw /2)
y = int(center_x - dh / 2)
boxes.append([x, y, dw, dh])
confidences.append(float(confidence))
class_ids.append(class_id)
'''
중복된 바운딩 박스 제거하기
-정확도가 0.45보다 작으면 제거
'''
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.45, 0.4)
''' 인식된 객체마다 바운딩 박스 처리하기 '''
for i in range(len(boxes)) :
''' 중복 제거 이후 남은 바운딩 박스의 정보만 이용 '''
if i in indexes :
''' 해당 객체에 대한 좌표값 '''
x, y, w, h = boxes[i]
''' 해당 객체에 대한 라벨값 '''
label = str(classes[class_ids[i]])
''' 해당 객체에 대한 정확도 '''
score = confidences[i]
''' 바운딩 박스 그리기 '''
cv2.rectangle(
### 원본 이미지(frame)
frame,
### 시작좌표
(x, y),
### 종료좌표
(x+w, y+h),
### 선 색상
(0, 0, 255),
### 선 굵기
5
)
''' 라벨, 정확도 이미지에 텍스트 그리기 '''
cv2.putText(
### 지금까지 그려진 frame 이미지
img = frame,
### 추가할 텍스트(문자열 타입으로)
text = label,
### 텍스트 시작위치 지정
org=(x, y-20),
### 텍스트 font 스타일
fontFace=cv2.FONT_ITALIC,
### font 크기
fontScale=0.5,
### font 색상
color=(255, 255, 255),
### font 굵기
thickness=1
)
''' 윈도우 창 open하기 '''
cv2.imshow("YOLO3_CM_01", frame)
''' 윈도우 창 크기 조절하기 '''
cv2.resizeWindow("YOLO3_CM_01", 650, 500)
''' 키보드에서 아무키 눌리면, while문 종료하기 '''
if cv2.waitKey(100) > 0 :
''' 윈도우 무조건 종료 '''
cv2.destroyAllWindows()
break
''' 키보드에서 q 입력 시 종료시키기 '''
if cv2.waitKey(1) & 0xFF == ord("q") :
''' 윈도우 무조건 종료 '''
cv2.destroyAllWindows()
break
'''
위도우 종료 후 재실행 시 안되는 경우가 발생할 수 있음.
이때는 주피터가 실행된 프롬프트 창에서 [CTRL+C]
'''
YOLO - Camera 객체탐지 이미지로 추출하기
- 정확도가 0.8 이상일 때 이미지 저장
import cv2
import numpy as np
VideoSignal = cv2.VideoCapture(0)
YOLO_net = cv2.dnn.readNet("./yolo/config/yolov2-tiny.weights",
"./yolo/config/yolov2-tiny.cfg")
classes = []
# open() : 파일 열기
# - 모드 : r 읽기모드, w 쓰기모드, b 바이너리
# as(별칭) f에는 열려있는 파일 정보가 담겨있음
with open("./yolo/config/coco.names", "r") as f :
# strip() : 왼쪽 오른쪽 공백제거
# readlines() : 파일 내에 문장들을 행단위로 모두 읽어들이기
classes = [line.strip() for line in f.readlines()]
''' YOLO 레이어 전체 추출 '''
layer_names = YOLO_net.getLayerNames()
''' YOLO 출력 레이어(계층)만 추출 '''
output_layer = [layer_names[i - 1] for i in YOLO_net.getUnconnectedOutLayers()]
cv2.namedWindow("YOLO3_CM_01")
############################
### 인식된 객체 이미지로 저장
# - 이미지 파일 저장 시 파일명에 번호 붙이기
img_cnt = 1
############################
'''
카메라를 통한 영상처리 시에는 윈도우 창을 계속 띄어 놓아야 한다.
- 정지 옵션(윈도우 창 닫기)은 필수
'''
while True :
'''
카메라에서 영상 읽어들이기 : read() 함수 사용
- 영상파일 또는 카메라로부터 프레임을 읽어오는 역할 수행
* ret : 읽어들이는 프레임이 있는지 여부 판단(True or False)
: 더 이상 읽어들일 프레임이 없으면 False가 됨
* frame : 실제로 읽어들이는 프레임(이미지) 자체
: 더 이상 읽어들일 프레임이 없으면 None이 됨
: 우리가 사용할 변수
'''
ret, frame = VideoSignal.read()
''' frame 정보에서 높이, 너비, 채널(흑백 또는 컬러) 추출하기 '''
h, w, c = frame.shape
''' --------------------------------------------------------- '''
''' BLOB 데이터 구조화 '''
blob = cv2.dnn.blobFromImage(
### 카메라에서 읽어들인 frame(이미지) 데이터
image = frame,
### 이미지 픽셀 값 정규화(스케일링)
scalefactor = 1/255.0,
### Yolo 모델이 사용할 크기로 조정
size=(416, 416),
### BRG, RGB 선택
# - True이면 OpenCV의 기본 BGR 생상 순서를 RGB로 변경
swapRB=True,
### 위에 size로 조정 후 어떻게 할지 결정
# - True이면 잘라내기
# - Fasle이면 size 전체 조정하기
crop=False
)
''' YOLO 입력 데이터로 넣어주기 '''
YOLO_net.setInput(blob)
''' YOLO모델에 출력계층 이름을 알려주고, 출력 결과 받아오기 '''
outs = YOLO_net.forward(output_layer)
''' 라벨(명칭, 이름) 담을 리스트 변수 '''
class_ids = []
''' 인식률(정확도) 담을 리스트 변수 '''
confidences = []
''' 바운딩 박스의 좌표를 담을 리스트 변수 '''
boxes = []
''' 출력 결과 여러개(인식된 객체 여러개)'''
for out in outs :
''' 실제 객체 인식 데이터 처리 '''
for detection in out :
''' 인식 데이터의 인식률(정밀도) '''
scores = detection[5:]
''' 인식률(정밀도)가 가장 높은 인덱스 위치 얻기 : 라벨(명칭, 이름)의 위치값 '''
class_id = np.argmax(scores)
''' 인식률(정밀도) 값 추출하기 : class_id의 인덱스 번호 위치값이 정밀도 '''
confidence = scores[class_id]
''' 정밀도가 50% 이상인 경우만 처리 : 기준은 자유롭게 정의 '''
if confidence > 0.5 :
''' 중앙값의 좌표 비율에 실제 너비로 연산하여 중앙 x값 추출 '''
center_x = int(detection[0] * w)
''' 중앙값의 좌표 비율에 실제 높이로 연산하여 중앙 y값 추출 '''
center_y = int(detection[1] * h)
''' 바운딩 박스의 실제 너비와 높이 계산하기 '''
dw = int(detection[2] * w)
dh = int(detection[3] * h)
''' 바운딩 박스의 시작 좌표(x, y) 계산하기 '''
x = int(center_x - dw /2)
y = int(center_x - dh / 2)
boxes.append([x, y, dw, dh])
confidences.append(float(confidence))
class_ids.append(class_id)
'''
중복된 바운딩 박스 제거하기
-정확도가 0.45보다 작으면 제거
'''
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.45, 0.4)
''' 인식된 객체마다 바운딩 박스 처리하기 '''
for i in range(len(boxes)) :
''' 중복 제거 이후 남은 바운딩 박스의 정보만 이용 '''
if i in indexes :
''' 해당 객체에 대한 좌표값 '''
x, y, w, h = boxes[i]
''' 해당 객체에 대한 라벨값 '''
label = str(classes[class_ids[i]])
''' 해당 객체에 대한 정확도 '''
score = confidences[i]
''' 바운딩 박스 그리기 '''
cv2.rectangle(
### 원본 이미지(frame)
frame,
### 시작좌표
(x, y),
### 종료좌표
(x+w, y+h),
### 선 색상
(0, 0, 255),
### 선 굵기
5
)
''' 라벨, 정확도 이미지에 텍스트 그리기 '''
cv2.putText(
### 지금까지 그려진 frame 이미지
img = frame,
### 추가할 텍스트(문자열 타입으로)
text = label,
### 텍스트 시작위치 지정
org=(x, y-20),
### 텍스트 font 스타일
fontFace=cv2.FONT_ITALIC,
### font 크기
fontScale=0.5,
### font 색상
color=(255, 255, 255),
### font 굵기
thickness=1
)
''' 윈도우 창 open하기 '''
cv2.imshow("YOLO3_CM_01", frame)
''' 윈도우 창 크기 조절하기 '''
cv2.resizeWindow("YOLO3_CM_01", 650, 500)
###########################################################
### 이미지로 저장하기
print(f">>>>>>>>>>>>>>정확도 평균 : {np.mean(confidences)}")
### 정확도 평균이 0.8이상인 경우만 저장시키기
if np.mean(confidences) >= 0.8 :
# 이미지 저장 함수 : imwrite() 함수 사용
cv2.imwrite(f"./yolo/images_new/img_{img_cnt}.jpg", frame)
img_cnt = img_cnt + 1
############################################################
''' 키보드에서 아무키 눌리면, while문 종료하기 '''
if cv2.waitKey(100) > 0 :
''' 윈도우 무조건 종료 '''
cv2.destroyAllWindows()
break
''' 키보드에서 q 입력 시 종료시키기 '''
if cv2.waitKey(1) & 0xFF == ord("q") :
''' 윈도우 무조건 종료 '''
cv2.destroyAllWindows()
break
'''
위도우 종료 후 재실행 시 안되는 경우가 발생할 수 있음.
이때는 주피터가 실행된 프롬프트 창에서 [CTRL+C]
'''


728x90
반응형
'Digital Boot > 인공지능' 카테고리의 다른 글
[인공지능][DL] Deep Learning - YOLO / 이미지 증식 (5) | 2024.01.11 |
---|---|
[인공지능][DL] Deep Learning - YOLO / 객체탐지 (0) | 2024.01.10 |
[인공지능][DL] Deep Learning - 합성곱신경망(CNN) (1) | 2024.01.08 |
[인공지능][DL] Deep Learning - RNN 응용 / 규칙기반 챗봇 (2) | 2024.01.08 |
[인공지능][DL] Deep Learning - 순환신경망(RNN), 장기기억 순환신경망(LSTM), 게이트웨이 반복 순환신경망(GRU) (1) | 2024.01.08 |