첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170
import cv2
import numpy as np

terminationTuple = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)
featureParameterDictionary = dict(maxCorners = 200, qualityLevel = 0.01, minDistance = 7, blockSize = 7)
lkParameterDictionary = dict(winSize = (15, 15), maxLevel = 2, criteria = terminationTuple)

class Application:
    def __init__(self, sourceVideo):
        self.trackLength     = 10
        self.detectInterval  = 5
        self.trackList       = []
        self.videoCapture    = cv2.VideoCapture(sourceVideo)
        self.frameIndex      = 0
        self.ShowBlackScreen = False
        self.videoWidth      = int(self.videoCapture.get(3))
        self.videoHeight     = int(self.videoCapture.get(4))

    def run(self):
        while True:
            result, frameNDArray = self.videoCapture.read()
            if not result:
                break
            grayscaleFrameNDArray = cv2.cvtColor(frameNDArray, cv2.COLOR_BGR2GRAY)
            if self.ShowBlackScreen:
                frameNDArray = np.zeros((self.videoHeight, self.videoWidth, 3), np.uint8)
            if len(self.trackList) > 0:
                previousFeatureNDArray = np.float32([track[-1] for track in self.trackList]).reshape(-1, 1, 2)
                featureNDArray, statusNDArray, errorNDArray = cv2.calcOpticalFlowPyrLK(self.previousGrayscaleFrameNDArray, grayscaleFrameNDArray, previousFeatureNDArray, None, **lkParameterDictionary)
                reverseFeatureNDArray, statusNDArray, errorNDArray = cv2.calcOpticalFlowPyrLK(grayscaleFrameNDArray, self.previousGrayscaleFrameNDArray, featureNDArray, None, **lkParameterDictionary)
                differenceNDArray = abs(previousFeatureNDArray - reverseFeatureNDArray).reshape(-1, 2).max(-1)
                goodNDArray = differenceNDArray < 1
                newTrackList = []
                for track, (x, y), good in zip(self.trackList, featureNDArray.reshape(-1, 2), goodNDArray):
                    if not good:
                        continue
                    track.append((x, y))
                    if len(track) > self.trackLength:
                        del track[0]
                    newTrackList.append(track)
                    cv2.circle(frameNDArray, (x, y), 2, (0, 255, 0), -1)
                self.trackList = newTrackList
                cv2.polylines(frameNDArray, [np.int32(track) for track in self.trackList], False, (0, 0, 255))
            if self.frameIndex % self.detectInterval == 0:
                maskNDArray = np.zeros_like(grayscaleFrameNDArray)
                maskNDArray[:] = 255
                for x, y in [np.int32(track[-1]) for track in self.trackList]:
                    cv2.circle(maskNDArray, (x, y), 5, 0, -1)
                featureNDArray = cv2.goodFeaturesToTrack(grayscaleFrameNDArray, mask = maskNDArray, **featureParameterDictionary)
                if featureNDArray is not None:
                    for x, y in np.float32(featureNDArray).reshape(-1, 2):
                        self.trackList.append([(x, y)])
            self.frameIndex += 1
            self.previousGrayscaleFrameNDArray = grayscaleFrameNDArray
            cv2.imshow("video", frameNDArray)
            key = cv2.waitKey(30) & 0xFF
            if key == 27:
                break
            if key == ord('b'):
                self.ShowBlackScreen = not self.ShowBlackScreen
        self.videoCapture.release()

Application(0).run()

cv2.destroyAllWindows()
728x90
반응형
그리드형
Posted by 사용자 icodebroker

댓글을 달아 주세요