- SIFT를 사용한 물체 감지
- ORB를 사용한 물체 감지
- 지향 기울기 (HOG)의 히스토그램
- 단계별 방향 기울기 (HOG)의 히스토그램 :
- HAAR 캐스케이드 분류기
- 얼굴 및 눈 감지
- 라이브 얼굴 및 눈 감지
- 캐스케이드 분류기 조정
- 비디오에서 자동차 및 보행자 감지
우리는 Windows에 python OpenCV를 설치하는 것으로 시작했으며 지금까지 Python을 사용하여 몇 가지 기본 이미지 처리, 이미지 분할 및 객체 감지를 수행했습니다. 이에 대해서는 아래 자습서에서 다룹니다.
- Python OpenCV 시작하기: 설치 및 기본 이미지 처리
- Python OpenCV의 이미지 조작 (1 부)
- OpenCV의 이미지 조작 (2 부)
- OpenCV를 사용한 이미지 분할-이미지의 특정 영역 추출
또한 다양한 알고리즘을 사용하여 모든 객체에 대해 몇 가지 핵심 포인트를 식별하는 객체 감지를위한 다양한 방법과 알고리즘에 대해 배웠습니다. 이 자습서에서는 이러한 알고리즘을 사용하여 실제 개체를 감지 할 것입니다. 여기서는 감지를 위해 SIFT 및 ORB 를 사용합니다.
SIFT를 사용한 물체 감지
여기서 객체 감지는 라이브 웹캠 스트림을 사용하여 수행 되므로 객체를 인식하면 발견 된 객체를 언급합니다. 코드에서 주요 부분은 SIFT 검출기라고하는 기능에 의해 수행되며 대부분의 처리는이 기능에 의해 수행됩니다.
코드의 나머지 절반에서는 웹캠 스트림을 열고 이미지 템플릿, 즉 프로그램이 실제로 웹캠 스트림을 통해보고있는 참조 이미지를로드합니다.
다음으로 무한 while 루프 를 사용하여 웹캠 스트림에서 이미지를 지속적으로 캡처 한 다음 웹캠 프레임의 해당 높이와 너비를 캡처 한 다음 관심 영역 (ROI) 상자의 매개 변수를 정의합니다. 우리의 개체는 웹캠 프레임의 해당 높이와 너비를 취하여 맞출 수 있습니다. 그런 다음 위에서 정의한 ROI 매개 변수에서 직사각형을 그립니다. 그런 다음 마지막으로 직사각형을 잘라내어 코드의 SWIFT 감지기 부분에 공급합니다.
이제 SIFT 감지기에는 기본적으로 두 개의 입력이 있습니다. 하나는 잘린 이미지이고 다른 하나는 이전에 정의한 이미지 템플릿입니다. 그런 다음 일치 항목을 제공합니다. 따라서 일치 항목은 기본적으로 잘린 이미지에서 유사한 객체 또는 키포인트의 수입니다. 및 대상 이미지. 그런 다음 일치에 대한 임계 값을 정의하고 일치 값이 임계 값보다 크면 화면에 찾은 이미지를 ROI 사각형의 녹색으로 표시합니다.
이제 코드의 주요 부분 인 SIFT 검출기로 돌아가 보겠습니다. 두 개의 이미지로 입력을받습니다. 하나는 객체를 찾고있는 이미지이고 다른 하나는 우리가 일치시키려는 객체입니다. (이미지 템플릿)에. 그런 다음 첫 번째 이미지를 그레이 스케일하고 이미지 템플릿을 두 번째 이미지로 정의합니다. 그런 다음 SIFT 감지기 객체를 만들고 OpenCV SIFT 감지 및 계산 기능을 실행하여 키포인트를 감지하고 설명자를 계산합니다. 설명자는 기본적으로 키포인트에 대한 정보를 저장하는 벡터이며 일치를 수행 할 때 정말 중요합니다. 이미지의 설명자 사이.
그런 다음 FLANN 기반 matcher 를 정의합니다. 우리는 그 뒤에있는 일치의 수학적 이론을 다루지는 않지만 쉽게 Google에서 검색 할 수 있습니다. 먼저 인덱스 kdtree 를 0으로 정의한 다음 사전 형식으로 인덱스 및 검색 매개 변수를 설정합니다. 사용할 알고리즘 인 KDTREE를 정의하고 사용할 트리의 수는 더 많은 트리입니다. 우리는 더 복잡해지고 느려질수록 사용합니다. 그리고 검색 매개 변수에서 검사 수를 정의합니다. 기본적으로 완료 될 일치 수입니다.
그런 다음 인덱스 매개 변수 및 검색 매개 변수 인 이전에 정의한 매개 변수를로드하여 FLANN 기반 매처 객체를 만들고이를 기반으로 KNN이 K- 최근 접 이웃 인 KNN 매 처인 FLANN 기반 매처를 생성합니다. 기본적으로 가장 가까운 매처와 디스크립터를 찾고 초기화 상수 k로 매칭을합니다. 이제이 FLANN 기반 매처는 우리가 얻은 일치 수를 반환합니다.
FLANN 기반 일치는 근사치 일 뿐이므로 FLANN 기반 일치 자의 정확도를 높이기 위해 Lowe의 비율 테스트를 수행하고 knn flann 기반 일치 자에서 일치하는 항목을 찾고 여기에 거리 인 몇 가지 매트릭스 매개 변수를 정의합니다., 거리가 numpy 함수이고 기준을 충족하면 일치 항목을 좋은 일치 항목에 추가하고 찾은 일치 항목을 반환하므로 라이브 비디오 스트림은 화면 모서리에서 찾은 일치 항목 수를 알려줍니다.
이제 위의 설명에 대한 코드를 살펴 보겠습니다.
import cv2 import numpy as np def sift_detector (new_image, image_template): # 입력 이미지를 템플릿과 비교하는 함수 # 그런 다음 그들 사이의 SIFT 일치 수를 반환합니다. image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Create SIFT 검출기 객체 #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2 = sift.detectAndCompute (image2, None) # Flann Matcher에 대한 매개 변수 정의 FLANN_INDEX_KDTREE = 0 index_params = dict (algorithm = FLANN_INDEX_KDTREE, trees = 3) search_params = dict (checks = 100) # Flann Matcher 객체 만들기 flann = cv2.FlannBasedMatcher (index_params, search_params) # K-Nearest Neighbor Method를 사용하여 일치 항목 가져 오기 # 결과 'matchs'는 두 이미지 일치 에서 찾은 유사한 일치의 수입니다. = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Lowe의 비율 테스트를 사용하여 좋은 매치 저장 good_matches = for m, n in match: if m.distance <0.7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # 이미지 템플릿을로드합니다. 이것은 참조 이미지입니다. image_template = cv2.imread ('phone.jpg', 0) while True: # 웹캠 이미지 가져 오기 ret, frame = cap.read () # 웹캠 프레임 높이와 너비 가져 오기 , width = frame.shape # ROI 상자 크기 정의 top_left_x = int (너비 / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2)-(height / 4)) # 관심 영역에 대한 직사각형 창을 그 립니다 cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # 위에서 정의한 관찰의 자르기 창 cropped = frame # 프레임 방향을 수평으로 뒤집기 frame = cv2.flip (frame, 1) # 일치하는 SIFT 수 가져 오기 = sift_detector (cropped, 이미지 _ 템플릿) # 현재 번호를 보여주는 상태 문자열을 표시합니다. 일치 항목 수 cv2.putText (frame, str (matches), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # 객체 결정을 나타내는 임계 값 # SIFT 감지기가 잘못된 긍정을 거의 반환하지 않으므로 10을 사용합니다. threshold = 10 # 일치가 임계 값을 초과하면 일치하는 경우 개체가 감지 된 것입니다> threshold: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Object Found', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Object Detector using SIFT', frame) if cv2.waitKey (1) == 13: # 13은 Enter 키 브레이크입니다. cap.release () cv2.destroyAllWindows ()
ORB를 사용한 물체 감지
SIFT를 사용하는 객체 감지는 키포인트를 기반으로 훨씬 정확한 수의 일치를 생성하기 때문에 상당히 멋지고 정확하지만 특허를 받았기 때문에 상용 응용 프로그램에 사용하기 어렵습니다. 다른 방법은 ORB 알고리즘입니다. 물체 감지를 위해.
프로그램을 두 부분으로 나눈 SIFT에 의한 물체 감지 방법과 유사하게 여기에서 동일한 내용을 따를 것입니다.
먼저, 두 개의 입력을받는 ORB_detector 함수를 정의합니다. 하나는 웹캠에서 오는 라이브 스트림 이미지이고 다른 하나는 이미지와 일치시킬 기반이되는 이미지 템플릿입니다. 그런 다음 웹캠 이미지를 그레이 스케일 한 다음 ORB 검출기를 초기화 합니다. 여기서 1000 개의 키 포인트와 1.2의 스케일링 매개 변수로 설정합니다. 이러한 매개 변수를 쉽게 가지고 놀 수 있으며 이미지에 대한 키포인트 (kp) 및 설명자 (des)를 감지하고 detectANDCompute 함수 에서 정의하는 두 번째 매개 변수 가 NONE 인 경우 이미지 마스크 사용 여부를 묻습니다. 우리는 여기서 그것을 부정하고 있습니다.
그런 다음 이전에 FLANN 기반 매처를 사용하고 있었지만 여기서는 BFMatcher를 사용하고 BFMatcher 내부에서 두 개의 매개 변수를 정의하고 하나는 NORM_HAMMING이고 다른 하나는 값이 TRUE 인 crossCheck입니다.
그런 다음 위에 정의 된 설명자를 사용하여 두 이미지 간의 일치를 계산합니다.이 일치 항목은 근사치가 아니므로 일치 항목 수를 반환합니다. 따라서 Lowe의 비율 테스트를 수행 할 필요가 없습니다. 대신 거리를 기준으로 일치 항목을 정렬합니다., 최소한 일치하는 거리가 길수록 더 좋습니다 (여기서 거리는 점 사이의 거리를 의미합니다). 마지막에 길이 함수를 사용하여 일치 수를 반환합니다.
그리고 주 기능에서 우리 는 임계 값을 훨씬 더 높은 값으로 설정했습니다. 구 감지기는 많은 노이즈를 생성하기 때문입니다.
이제 ORB 기반 탐지를위한 코드를 살펴 보겠습니다.
import cv2 import numpy as np def ORB_detector (new_image, image_template): # 입력 이미지를 템플릿과 비교하는 함수 # 그런 다음 둘 사이의 ORB 일치 수를 반환합니다. image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # 다음을 사용하여 ORB 감지기 만들기 1.2의 스케일링 피라미드 계수를 가진 1000 개의 키포인트 orb = cv2.ORB_create (1000, 1.2) # 원본 이미지의 키포인트 감지 (kp1, des1) = orb.detectAndCompute (image1, None) # 회전 된 이미지의 키포인트 감지 (kp2, des2) = orb.detectAndCompute (image_template, None) # 매처 생성 # 우리는 더 이상 Flann 기반 매칭을 사용하지 않습니다. bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # 일치 일치 수행 = bf.match (des1, des2) # 거리를 기준으로 일치 항목을 정렬합니다. Least distance # is better matches = sorted (matches, key = lambda val: val.distance) return len (matches) cap = cv2.VideoCapture (0) # 이미지 템플릿을로드합니다. 이것은 참조 이미지입니다. image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) while True: # 웹캠 이미지 가져 오기 ret, frame = cap.read () # 웹캠 프레임 높이 의 높이와 너비 가져 오기 , width = frame.shape # ROI 상자 치수 정의 (이 중 일부는 루프 외부에 있어야 함) top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2)-(height / 4)) # 직사각형 창을 그 립니다. 관심 영역 cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # 위에서 정의한 관찰의 자르기 창 cropped = frame # 프레임 방향을 수평으로 뒤집기 frame = cv2.flip (frame, 1) # 일치하는 ORB 개수 가져 오기 = ORB_detector (cropped, image_template) # 현재 번호를 보여주는 상태 문자열을 표시합니다. 일치 수 output_string = "일치 ="+ str (일치) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # 물체 감지를 나타내는 임계 값 # 새로운 이미지 또는 조명 조건에 대해 약간의 실험이 필요할 수 있습니다 . # 참고: 상위 1000 개 일치 항목을 얻기위한 ORB 감지기는 기본적으로 최소 35 % 일치 임계 값 = 250입니다 . 임계 값 과 일치하는 경우 개체가 감지 된 경우> threshold: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Object Found', (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Object Detector using ORB', frame) if cv2.waitKey (1) == 13: # 13은 Enter 키 브레이크 캡입니다..release () cv2.destroyAllWindows ()
지향 기울기 (HOG)의 히스토그램
이제 HOG (Histogram of Oriented Gradients)라는 다른 설명자에 대해 이야기하겠습니다.
HOG는 매우 멋지고 유용한 설명자이며 이전에 SIFT 및 ORB와 같은 이미지 설명자에서 볼 수 있듯이 키포인트를 계산 한 다음 해당 키포인트에서 설명자를 계산해야하는 것처럼 객체 감지에 광범위하고 성공적으로 사용됩니다. HOG는 해당 프로세스를 수행합니다. 다르게. 그것은 하나의 특징 벡터로서 오브젝트를 나타내는 각 이미지의 세그먼트를 나타내는 특징 벡터의 세트에 대향한다. 이는 전체 이미지에 대해 단일 벡터 기능 이 있음을 의미 합니다.
이미지에 대한 슬라이딩 윈도우 감지기에 의해 계산되며, HOG 설명자는 각 위치에 대해 계산됩니다. 그런 다음 각 위치가 단일 특성 벡터에 대해 결합됩니다.
SIFT와 마찬가지로 이미지의 배율은 피라미드 방식으로 조정됩니다.
이전에는 FLANN 및 BFMatcher와 같은 매처를 사용했지만 HOG는 SVM (지원 벡터 머신) 분류기를 사용하여 다르게 수행합니다. 여기서 계산 된 각 HOG 설명자는 SVM 분류기에 공급되어 객체가 발견되었는지 여부를 결정합니다.
다음은 인간 탐지를위한 HOG 사용에 대한 Dalal & Triggs의 Great Paper 링크입니다.
단계별 방향 기울기 (HOG)의 히스토그램:
HOG를 이해하는 것은 매우 복잡 할 수 있지만 여기서는 HOG와 관련된 수학에 더 깊이 들어 가지 않고 HOG 이론 만 다룰 것입니다.
이 사진을 찍어 보겠습니다. 조금 픽셀 화 되어 있고 위쪽 모서리에는 8x8 픽셀 상자가 있습니다.이 상자에서 각 픽셀의 그라디언트 벡터 또는 가장자리 방향을 계산합니다. 즉,이 상자에서 상자 내부 픽셀의 이미지 그라디언트 벡터를 계산하고 (이미지 강도 자체의 방향 또는 흐름의 일종) 64 (8 x 8) 그라디언트 벡터를 생성하여 히스토그램으로 표시합니다.. 따라서 각 그라디언트 벡터를 나타내는 히스토그램을 상상해보십시오. 따라서 모든 포인트 또는 강도가 한 방향에 놓여 있다면 해당 방향에 대한 히스토그램이 45 도라고 가정하면 히스토그램은 45도에서 최고점을 갖게됩니다.
이제 우리가하는 일은 각 셀을 각도 빈으로 분할하는 것입니다. 각 빈은 기울기 방향 (예: x, y)에 해당합니다. Dalal 및 Triggs 논문에서는 9 개의 bins0-180 ° (각 bin 20 °)를 사용했습니다. 이는 64 개의 벡터를 9 개의 값으로 효과적으로 줄입니다. 그래서 우리가 한 일은 크기를 줄 였지만 필요한 모든 핵심 정보를 유지하는 것입니다.
돼지를 계산하는 다음 단계 는 정규화입니다. 밝기 및 대비와 같은 조명 변화에 대한 불변성을 보장하기 위해 그라디언트를 정규화합니다.
이 이미지에서 강도 값은 각 방향에 따라 정사각형으로 표시되며 모두 50의 차이가 있습니다.
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70.72, 70.72 / 100 = 0.707
우리는 벡터를 0.707의 기울기 크기로 나눕니다. 이것이 정규화입니다.
마찬가지로 강도를 변경하거나 대비를 변경하면 아래 값을 얻습니다.
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70.72, 70.72 / 100 = 0.707; ∆ H = 100, ∆ v = 100; │∆│ = √100 2 +100 = 141.42, 141.42 / 100 = 1.41
정규화 는 셀 수준에서 발생하지 않고 대신 블록 수준 에서 발생하므로 여기에서 블록은 기본적으로 4 개의 셀 그룹입니다. 이것은 이미지의 더 큰 세그먼트를 고려하면서 정규화되도록 인접 블록을 고려합니다.
이제 코드를 살펴 보겠습니다.
import numpy as np import cv2 import matplotlib.pyplot as plt # 이미지로드 후 회색조 이미지 = cv2.imread ('elephant.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # 원본 이미지보기 cv2.imshow (' Input Image ', image) cv2.waitKey (0) # 파라미터, 셀 크기 및 블록 크기 정의 # 픽셀 단위 hxw cell_size = (8, 8) # 셀 단위 hxw block_size = (2, 2) # 방향 bin 수 nbins = 9 # OpenCV의 HOG Descriptor 사용 # winSize는 셀 크기의 배수로 잘린 이미지의 크기입니다 hog = cv2.HOGDescriptor (_winSize = (gray.shape // cell_size * cell_size, gray.shape // cell_size * cell_size), _blockSize = ( block_size * cell_size, block_size * cell_size), _blockStride = (cell_size, cell_size), _cellSize = (cell_size, cell_size), _nbins = nbins) # 우리가 사용하는 numpy 배열 모양 생성 to create hog_features n_cells = (gray.shape // cell_size, gray.shape // cell_size) # 먼저 행별로 블록을 인덱싱합니다. # hog_feats에는 이제 각 그룹에 대한 그룹의 각 셀에 대한 각 방향에 대한 # 그라디언트 진폭이 포함 됩니다. 인덱싱은 행과 열을 기준으로합니다. hog_feats = hog.compute (gray).reshape (n_cells-block_size + 1, n_cells-block_size + 1, block_size , block_size, nbins).transpose ((1, 0, 2, 3, 4)) # 그라디언트 방향을 저장하기 위해 nbin 차원으로 그라디언트 배열을 생성합니다. gradients = np.zeros ((n_cells, n_cells, nbins)) # 차원 배열 생성 cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # 범위 내 off_y에 대한 블록 정규화 (block_size): 범위 내 off_x (block_size): gradients-block_size + off_y + 1, off_x: n_cells-block_size + off_x + 1] + = \ hog_feats cell_count-block_size + off_y + 1, off_x: n_cells-block_size + off_x + 1] + = 1 # 평균 그라디언트 그라디언트 / = cell_count # Matplotlib를 사용하여 HOG 플롯 # 각도는 360 / nbins * 방향 color_bins = 5 plt.pcolor (gradients) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('equal', Adjustable = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
이미지는 입력 이미지가 HOG 표현으로 어떻게 표현되는지 보여줍니다.
HAAR 캐스케이드 분류기
앞서 논의했듯이 이미지에서 특징을 추출하고 이러한 특징을 사용하여 객체를 분류하거나 감지 할 수 있습니다.
HAAR 캐스케이드 분류기는 무엇입니까? Haar 기능 을 일련의 분류기 (캐스케이드)에 입력하여 이미지에서 개체를 식별
하는 개체 감지 방법입니다. 그들은 한 유형의 물체 를 식별하도록 훈련 되었지만, 우리는 그것들 중 여러 가지를 병렬로 사용할 수 있습니다 (예: 눈과 얼굴을 함께 감지).
HAAR 분류기 설명:
HAAR 분류기는 많은 양의 이미지 (즉, 물체가있는 이미지)와
음의 이미지 (즉, 물체가없는 이미지)를 사용하여 훈련됩니다.
이러한 이미지가 있으면 직사각형 블록의 슬라이딩 창을 사용하여 특징을 추출합니다. 이러한 기능 (HAAR 기능)은 단일 값이며 검은 색 사각형에서 흰색 사각형 아래의 픽셀 강도 합계를 빼서 계산됩니다.
그러나 이것은 24 x 24 픽셀의 기본 창 (180,000 개의 피처 생성)에서도 엄청난 수의 계산입니다.
그래서 연구원들은 4 개의 배열 참조로 이것을 계산하는 Integral Images 라는 방법을 고안했습니다. 그러나 여전히 180,000 개의 기능이 있었고 대부분은 실제 가치를 추가하지 않았습니다.
그런 다음 Freund & Schapire의 AdaBoost 와 함께 가장 유익한 기능을 결정하는 데 Boosting 이 사용되었으며 이미지에서 대부분의 유익한 기능을 찾았습니다. 부스팅은 단순히 잘못된 분류에 대해 더 무거운 가중치를 부여함으로써 강력한 분류기를 구축하기 위해 약한 분류기를 사용하는 프로세스입니다. 180,000 개 기능을 6000 개로 줄이면 여전히 상당한 기능입니다.
이러한 6000 개 기능에서 일부는 다른 것보다 더 많은 정보를 제공합니다. 따라서 가장 유익한 기능을 사용하여 지역이 잠재적으로 얼굴을 가질 수 있는지 여부를 먼저 확인한 경우 (거짓 긍정은 별 문제가되지 않습니다). 이렇게하면 6000 개의 모든 기능을 한 번에 계산할 필요가 없습니다. 이 개념을 Cascade of Classifiers라고합니다. 얼굴 감지를 위해 Viola Jones 방법은 38 단계를 사용했습니다.
얼굴 및 눈 감지
그래서 HAAR 캐스케이드에 대한 이론적 지식을 얻은 후에 마침내 그것을 구현할 것입니다. 그래서 우리는 부분적으로 교훈을 깨뜨릴 것입니다. 마지막으로 웹캠을 통해 얼굴과 눈을 실시간으로 감지합니다.
따라서이를 위해 OpenCV에서.xml 파일로 제공 한 사전 훈련 된 분류자를 사용할 것입니다. xml은 확장 가능한 마크 업 언어를 의미하며이 언어는 방대한 양의 데이터를 저장하는 데 사용되며 데이터베이스를 구축 할 수도 있습니다.
이 링크 에서 이러한 분류 자에 액세스 할 수 있습니다 .
얼굴 인식
정면 얼굴 검출을 시도해 보겠습니다. 여기에서 정면 얼굴 검출기의 캐스케이드에 액세스 할 수 있습니다. zip 파일을 추출하여 xml 파일을 얻으십시오.
import numpy as np import cv2 # OpenCV의 CascadeClassifier 함수를 # 분류 자 (XML 파일 형식)가 저장된 위치로 지정합니다. 코드와 분류 자를 동일한 폴더에 보관해야합니다. face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') #로드 이미지를 그레이 스케일로 변환합니다. image = cv2.imread ('Trump.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # 분류기는 감지 된 얼굴의 ROI를 튜플로 반환합니다. # 왼쪽 상단을 저장합니다. 좌표 및 오른쪽 하단 좌표 # 감지 된 다른 얼굴의 위치 인 목록 목록을 반환합니다. faces = face_cascade.detectMultiScale (gray, 1.3, 5) # 어떤 얼굴이 감지되지 않을 때, face_classifier 반품 및 빈 튜플 () 얼굴 경우: 인쇄 ("아니오 발견 면들") 우리는 반복 처리는 우리의 얼굴 배열을 통해 # 및 사각형 그리기 얼굴의 각 얼굴에 #을 , Y, 승, (x의 h) 얼굴: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('얼굴 인식', 이미지) cv2.waitKey (0) cv2.destroyAllWindows ()
이제 얼굴과 눈 감지를 함께 결합 해 보겠습니다. 동일한 zip 파일에서 눈 감지기의 캐스케이드에 액세스 할 수 있습니다.
import numpy as np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) # 얼굴이 감지되지 않으면 face_classifier가 반환되고 얼굴이 ()이면 튜플을 비 웁니다 : print ("No Face Found") for (x, y, w, h) 얼굴: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = 회색 roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) for (ex, ey, ew, eh) in eyes: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (255,255,0), 2) cv2.imshow ('img', img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
우리가 선택한 볼 수 있듯이 얼굴 인식을위한 코드, 그러나 여기에서 우리가 추가 한 눈 폭포와 방법은 그들을 감지하는 것과이 코드는만큼 동일 그래서 회색은 대한 매개 변수로 얼굴의 버전을 조정 detectMultiScale 에 대한 눈은 그 영역에서만 눈을 감지하기 때문에 계산이 감소합니다.
라이브 얼굴 및 눈 감지
지금까지 얼굴 및 눈 감지를 수행 했으므로 이제 웹캠의 라이브 비디오 스트림을 사용하여 동일한 방법을 구현해 보겠습니다. 여기에서는 얼굴과 눈의 동일한 감지를 수행하지만 이번에는 웹캠의 라이브 스트림에 대해 수행합니다. 대부분의 응용 프로그램에서 주위에 상자로 강조 표시된 얼굴을 찾을 수 있지만 여기에서는 얼굴이 잘리고 눈이 그 안에서만 식별 할 수있는 다른 작업을 수행했습니다.
그래서 여기에서는 얼굴과 눈 분류자를 모두 가져오고 얼굴과 눈 감지를위한 모든 처리를 수행하는 함수를 정의했습니다. 그 후 웹캠 스트림을 시작하고 얼굴과 눈을 감지하는 얼굴 감지기 기능을 호출했습니다. 얼굴 감지기 기능 내에서 정의하는 매개 변수는 라이브 웹 캠 스트림의 연속 이미지입니다.
import cv2 import numpy as np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5): # 이미지를 회색조로 변환 gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) if faces is (): return img for (x, y, w, h) in faces: x = x-50 w = w + 50 y = y-50 h = h + 50 cv2.rectangle (img, (x, y), (x + w, y + h), ( 255,0,0 ), 2) roi_gray = 회색 roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) for (ex, ey, ew, eh) in eyes: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) return roi_color cap = cv2.VideoCapture (0) while True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) if cv2.waitKey (1) == 13: # 13은 Enter 키 브레이크입니다. cap.release () cv2.destroyAllWindows ()
캐스케이드 분류기 조정
입력 이미지가 아닌 detectMultiScale 내부에 정의 된 매개 변수 는 다음과 같은 의미를 갖습니다.
ourClassifier. detectMultiScale (입력 이미지, 스케일 팩터, 최소 이웃)
- 배율 요소 배율 을 조정할 때마다 이미지 크기를 줄이는 정도를 지정합니다. 예를 들어 얼굴 감지에서는 일반적으로 1.3을 사용합니다. 즉, 크기를 조정할 때마다 이미지를 30 % 씩 줄입니다. 1.05와 같이 값이 작을수록 계산하는 데 시간이 오래 걸리지 만 탐지율이 높아집니다.
- Min Neighbors 양성 탐지로 간주하기 위해 각 잠재적 창에 있어야하는 인접 항목 수를 지정합니다. 일반적으로 3-6 사이로 설정됩니다. 감도 설정으로 작동하며 낮은 값은 때때로 단일 얼굴에 여러 얼굴을 감지합니다. 값이 높으면 오탐이 줄어들지 만 일부 얼굴을 놓칠 수 있습니다.
비디오에서 자동차 및 보행자 감지
이제 HAAR 캐스케이드를 사용하여 비디오에서 보행자와 자동차를 감지하지만 비디오가로드되지 않고 오류없이 코드가 컴파일되는 경우 다음 단계를 따라야합니다.
더 비디오 부하가 코드를 실행 한 후, 당신은 우리의 복사 할 필요가 없습니다 수 있습니다 경우 에서 opencv_ffmpeg.dl을 : OpenCV의 \ 소스 \ 3rdparty \는 FFmpeg 그것을 붙여 파이썬은 예를 들어 설치되어있는 \ Anaconda2: C
:이 복사 된 후에는 OpenCV의 당신이 당신이 다음과 같은 파일의 이름을 변경 OpenCV의 2.4.13을 사용하는 경우있는 거 using.eg의 버전에 따라 파일의 이름을 변경해야합니다 opencv_ffmpeg2413_64.dll 당신이 있다면 (또는 opencv_ffmpeg2413.dll을 X86 시스템을 사용하는 경우) opencv_ffmpeg310_64.dll 또는 opencv_ffmpeg310.dll (X86 시스템을 사용하는 경우)
python.exe가 설치된 위치 를 찾으 려면 이 두 줄의 코드를 실행하면 python이 설치된 위치가 인쇄됩니다.
import sys print (sys.executable)
이제이 단계를 성공적으로 완료했다면 보행자 감지 코드로 이동해 보겠습니다 .
보행자 감지 용 캐스케이드와 여기에 첨부 된 zip 파일을 사용할 수 있습니다.
import cv2 import numpy as np # 신체 분류기 생성 body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # 비디오 파일에 대한 비디오 캡처를 시작합니다. 여기에서는 보행자가 감지되는 비디오 파일을 사용합니다. cap = cv2.VideoCapture ('walking.avi') # cap.isOpened () 동안 비디오가 성공적으로로드되면 루프 : # 비디오의 각 프레임 읽기 ret, frame = cap.read () # 여기서 프레임 크기를 절반으로 조정합니다., 우리는 분류 속도를 높이기 위해 노력하고 있습니다. # 큰 이미지에는 슬라이드 할 창이 더 많으므로 전반적으로 해상도를 줄입니다. 비디오의 절반은 0.5가 나타내는 것이고, 우리는 또한 #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) gray = cv2 와 같은 더 빠른 보간 방법을 사용하고 있습니다. cvtColor (frame, cv2.COLOR_BGR2GRAY) # 우리 몸 분류기로 프레임 전달 body = body_classifier.detectMultiScale (gray, 1.2, 3) # body: cv2 에서 (x, y, w, h)로 식별 된 모든 바디에 대한 경계 상자를 추출 합니다. rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Pedestrians', frame) if cv2.waitKey (1) == 13: # 13은 Enter 키 브레이크입니다. cap.release () cv2.destroyAllWindows ()
영상에서 보행자를 성공적으로 감지 한 후에는 자동차 감지 코드로 이동해 보겠습니다. 여기에서 보행자 감지를위한 캐스케이드를 가질 수 있습니다.
import cv2 import time import numpy as np # 우리 몸 분류기 만들기 car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # 비디오 파일에 대한 비디오 캡처 시작 cap = cv2.VideoCapture ('cars.avi') # 비디오가 성공적으로 완료되면 루프 load while cap.isOpened (): time.sleep (.05) # 첫 번째 프레임 읽기 ret, frame = cap.read () gray = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # 프레임을 자동차 분류기에 전달 cars = car_classifier.detectMultiScale (gray, 1.4, 2) # 자동차에서 (x, y, w, h)로 식별 된 모든 몸체에 대한 경계 상자 추출 : cv2.rectangle (frame, (x, y), (x + w, y + h)), (0, 255, 255), 2) cv2.imshow ('Cars', frame) if cv2.waitKey (1) == 13: # 13은 Enter 키 브레이크입니다. cap.release () cv2.destroyAllWindows ()
time.sleep (.05) 을 추가 했습니다. 프레임 속도가 지연된 것이므로 모든 차량이 올바르게 식별되었는지 확인하거나 주석 라벨을 추가하기 만하면 쉽게 제거 할 수 있습니다.
이 기사는 Rajeev Ratan이 만든 Udemy의 Deep Learning 과정이 포함 된 Python의 Master Computer Vision ™ OpenCV4에서 참조되었으며, 구독하여 Computer Vision 및 Python에 대해 자세히 알아보십시오.