OpenCV 모션 감지

Salman Mehmood 2023년10월10일
OpenCV 모션 감지

이 기사에서는 OpenCV 및 Python을 사용하여 동작 감지 프로젝트를 만드는 방법을 배웁니다.

OpenCV 및 Python을 사용하여 모션 감지 프로젝트 생성

우선, 이 프로젝트의 요구 사항에 대해 이야기합시다. 첫 번째 요구 사항은 분명히 Python을 설치하는 데 필요하며 opencv라는 외부 패키지도 설치해야 합니다.

이 패키지를 PC에 설치하려면 명령 프롬프트를 열고 이 명령을 실행해야 합니다. 편집기로 이동하여 코드 작성을 시작하겠습니다.

가장 먼저 가져올 것은 필수 라이브러리인 cv2time이고 다음은 OpenCV의 VideoCapture() 메서드를 사용하여 웹캠에서 데이터를 가져오는 것입니다.

Video라는 개체를 만들고 VideoCapture()0을 전달해야 합니다. 웹캠에 0 채널을 사용하고 있기 때문입니다.

import cv2
import time

Video = cv2.VideoCapture(0)
First_Frame = None

이제 우리는 비디오를 추출할 것이기 때문에 while True 루프 또는 무한 루프를 생성할 것입니다. 비디오는 이미지의 슬라이드쇼에서 연속적으로 움직이는 것이기 때문입니다.

이제 while 루프에서 여러 명령을 정의하고 첫 번째 줄에서 Checkframe의 두 변수를 만들고 VideoCapture() 메서드로 추출한 데이터를 읽습니다. 다음 명령에서는 이 추출된 이미지를 회색조로 변환합니다.

그런데 이것을 그레이스케일로 변환하는 이유는 무엇입니까? 특징 감지의 정확도를 높이고 싶기 때문에 이렇게 하는 것입니다.

cvtColor() 메소드를 사용하여 회색조로 변경하고 두 개의 매개변수를 갖습니다. 첫 번째는 frame 또는 회색조로 변환하려는 이미지이고 다음은 COLOR_BGR2GRAY로 이미지를 회색으로 변환합니다.

이제 우리는 이미지를 흐릿하게 만들거나 부드럽게 만들 것입니다. 그래서 물체 감지나 물체의 움직임이 훨씬 쉬워집니다. GaussianBlur() 메서드를 사용하여 스무딩을 적용하고 그레이스케일 이미지, 커널 크기 및 시그마를 전달합니다.

while True:
    Check, frame = Video.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)

프레임이 오고 있는지 여부를 확인하는 if 문을 생성할 것이며 First_Frame을 참조 프레임으로 원하기 때문에 이 작업을 수행합니다.

물리학이 운동에 대해 말하는 것을 살펴봅시다. 모션은 기준점에서 식별되며 이를 예를 들어 설명합니다.

당신이 기차에 앉아 있고 당신을 위해 나무는 움직이지만 움직이지 않는다고 가정해 봅시다. 그들은 여전히 ​​​​있지만 당신은 당신의 기준점에서 움직이고 있습니다. 이 경우 나무는 기준점이지만 프레임은 우리의 경우 기준입니다.

First_Frame을 참조 프레임으로 고정하고 있습니다. 참조 프레임에서 변경 사항이 발생하면 모션이 거기에 있다고 말할 수 있습니다.

이제 First_Frame 변수가 첫 번째 경우 trueNone과 같은 문을 설정하고 First_Frame 변수를 gray 변수인 회색조 이미지와 동일하게 만듭니다.

if First_Frame is None:
    First_Frame = gray
    continue

프레임 간의 차이를 찾기 위해 absdiff() 메서드를 사용합니다. 델타 프레임 변수를 만들고 두 매개변수를 비교를 위해 absdiff() 메서드에 전달해 보겠습니다.

노이즈가 모션으로 감지되는 것을 원하지 않기 때문에 모션이 감지되기를 원하는 임계값 또는 한계를 설정해야 합니다.

이를 위해 threshold() 메서드를 사용하고 몇 가지 매개변수가 있습니다. 첫 번째는 delta_frame, 두 번째는 강도, 세 번째는 이 경우 흰색인 색조, 다음은 몇 가지 매개변수입니다. 다음은 튜플이므로 THRESH_BINARY이므로 첫 번째 요소를 선택해야 합니다.

다음 지침에서 평활화 레이어를 하나 더 적용해야 합니다. 이렇게 하려면 dilate()라는 평활화 함수를 하나 더 사용해야 하며 세 개의 매개변수를 허용합니다. 첫 번째 매개변수는 threshold, 두 번째 매개변수는 None, 세 번째 매개변수는 iterations입니다.

iterations 매개변수는 스무딩이 얼마나 정확한지를 정의합니다. 이 매개변수 값을 늘리면 프로그램도 노이즈를 캡처합니다.

이번에는 등고선을 만들 것입니다. 그렇다면 등고선은 무엇입니까? 윤곽선은 모션이 발생하는 지점입니다.

프레임이 정지하고 손이 움직이면 손의 부분이 윤곽이 됩니다.

findContours() 메서드는 등고선을 찾는 데 도움이 되며 세 개의 매개변수를 허용합니다. 첫 번째는 프레임이고 copy() 메서드를 사용하여 프레임 배열의 복사본을 만듭니다.

delta_frame = cv2.absdiff(First_Frame, gray)
Threshold_frame = cv2.threshold(delta_frame, 50, 255, cv2.THRESH_BINARY)[1]
Threshold_frame = cv2.dilate(Threshold_frame, None, iterations=2)
(cntr, _) = cv2.findContours(
    Threshold_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)

이제 반복을 통해 윤곽을 얻고 대략적인 영역을 모션으로 정의합니다. 영역을 정의하지 않으면 매우 시끄러운 모션 감지가 발생합니다.

먼저 등고선 면적이 천보다 작으면 이것을 모션 영역으로 간주하지 않고 반복을 계속하고 천보다 크면 다음을 그릴 것입니다. 삼각형.

for contour in cntr:
    if cv2.contourArea(contour) < 1000:
        continue

findContours() 메소드는 4개의 값(x, y, 높이, 너비)을 제공하고 직사각형 영역을 바인딩할 boundingRect() 메소드를 사용하여 이 점을 추출합니다. 이제 rectangle() 메서드를 사용하여 사각형을 만듭니다.

첫 번째 매개변수는 프레임 또는 직사각형을 그릴 이미지입니다. 다음은 (x,y) 좌표점, 다음은 높이와 너비, 다음은 프레임 색상, 마지막 매개변수는 사각형을 그리기 위해 선택한 펜의 크기입니다.

(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)

완전한 소스 코드:

import cv2
import time

Video = cv2.VideoCapture(0)
First_Frame = None

while True:
    Check, frame = Video.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)
    if First_Frame is None:
        First_Frame = gray
        continue
    delta_frame = cv2.absdiff(First_Frame, gray)
    Threshold_frame = cv2.threshold(delta_frame, 50, 255, cv2.THRESH_BINARY)[1]
    Threshold_frame = cv2.dilate(Threshold_frame, None, iterations=2)
    (cntr, _) = cv2.findContours(
        Threshold_frame.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
    )
    for contour in cntr:
        if cv2.contourArea(contour) < 1000:
            continue
        (x, y, w, h) = cv2.boundingRect(contour)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
    cv2.imshow("Frame", frame)
    Key = cv2.waitKey(1)
    if Key == ord("q"):
        break

Video.release()
cv2.destroyAllWindows()

이제 우리는 손이 움직일 때 움직임 감지가 일어나는 것을 볼 수 있습니다.

OpenCV 및 Python을 사용하여 모션 감지 프로젝트 생성

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

관련 문장 - OpenCV Video