|
|
|
@@ -14,9 +14,7 @@ |
|
|
|
|
|
|
|
"""Optical Flow Algorithms""" |
|
|
|
import abc |
|
|
|
|
|
|
|
import numpy |
|
|
|
import cv2 |
|
|
|
from sedna.common.class_factory import ClassFactory, ClassType |
|
|
|
from sedna.common.log import LOGGER |
|
|
|
|
|
|
|
@@ -40,6 +38,8 @@ class BaseFilter(metaclass=abc.ABCMeta): |
|
|
|
|
|
|
|
@ClassFactory.register(ClassType.OF, alias="LukasKanadeOF") |
|
|
|
class LukasKanade(BaseFilter, abc.ABC): |
|
|
|
import cv2 |
|
|
|
|
|
|
|
""" |
|
|
|
Class to detect movement between two consecutive images. |
|
|
|
""" |
|
|
|
@@ -49,7 +49,7 @@ class LukasKanade(BaseFilter, abc.ABC): |
|
|
|
dict(maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7) |
|
|
|
|
|
|
|
# Parameters for Lucas Kanade optical flow |
|
|
|
_criteria = cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT |
|
|
|
_criteria = self.cv2.TERM_CRITERIA_EPS | self.cv2.TERM_CRITERIA_COUNT |
|
|
|
|
|
|
|
self.lk_params = dict( |
|
|
|
winSize=(15, 15), |
|
|
|
@@ -67,14 +67,15 @@ class LukasKanade(BaseFilter, abc.ABC): |
|
|
|
|
|
|
|
movement = False |
|
|
|
try: |
|
|
|
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY) |
|
|
|
p0 = cv2.goodFeaturesToTrack( |
|
|
|
old_gray = self.cv2.cvtColor(old_frame, self.cv2.COLOR_BGR2GRAY) |
|
|
|
p0 = self.cv2.goodFeaturesToTrack( |
|
|
|
old_gray, mask=None, **self.feature_params) |
|
|
|
|
|
|
|
current_gray = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY) |
|
|
|
current_gray = \ |
|
|
|
self.cv2.cvtColor(current_frame, self.cv2.COLOR_BGR2GRAY) |
|
|
|
|
|
|
|
# Calculate Optical Flow |
|
|
|
p1, st, err = cv2.calcOpticalFlowPyrLK( |
|
|
|
p1, st, err = self.cv2.calcOpticalFlowPyrLK( |
|
|
|
old_gray, current_gray, p0, None, **self.lk_params |
|
|
|
) |
|
|
|
|
|
|
|
@@ -88,7 +89,10 @@ class LukasKanade(BaseFilter, abc.ABC): |
|
|
|
# Allclose is used instead of array_equal to support |
|
|
|
# array of floats (if we remove rounding). |
|
|
|
movement = \ |
|
|
|
not numpy.allclose(numpy.rint(good_new), numpy.rint(good_old)) |
|
|
|
not numpy.allclose( |
|
|
|
numpy.rint(good_new), |
|
|
|
numpy.rint(good_old) |
|
|
|
) |
|
|
|
except Exception as ex: |
|
|
|
LOGGER.error( |
|
|
|
f"Error during the execution of\ |
|
|
|
@@ -99,6 +103,9 @@ class LukasKanade(BaseFilter, abc.ABC): |
|
|
|
|
|
|
|
@ClassFactory.register(ClassType.OF, alias="LukasKanadeOF_CUDA") |
|
|
|
class LukasKanadeCUDA(BaseFilter, abc.ABC): |
|
|
|
import cv2 |
|
|
|
import numpy |
|
|
|
|
|
|
|
""" |
|
|
|
Class to detect movement between |
|
|
|
two consecutive images (GPU implementation). |
|
|
|
@@ -107,7 +114,7 @@ class LukasKanadeCUDA(BaseFilter, abc.ABC): |
|
|
|
# Parameters for ShiTomasi corner detection |
|
|
|
self.feature_params = \ |
|
|
|
dict( |
|
|
|
srcType=cv2.CV_8UC1, |
|
|
|
srcType=self.cv2.CV_8UC1, |
|
|
|
maxCorners=100, |
|
|
|
qualityLevel=0.3, |
|
|
|
minDistance=7, |
|
|
|
@@ -120,8 +127,11 @@ class LukasKanadeCUDA(BaseFilter, abc.ABC): |
|
|
|
) |
|
|
|
|
|
|
|
self.corner_detector = \ |
|
|
|
cv2.cuda.createGoodFeaturesToTrackDetector(**self.feature_params) |
|
|
|
self.of = cv2.cuda.SparsePyrLKOpticalFlow_create(**self.lk_params) |
|
|
|
self.cv2.cuda.createGoodFeaturesToTrackDetector( |
|
|
|
**self.feature_params |
|
|
|
) |
|
|
|
self.of = \ |
|
|
|
self.cv2.cuda.SparsePyrLKOpticalFlow_create(**self.lk_params) |
|
|
|
|
|
|
|
def __call__(self, old_frame=None, current_frame=None): |
|
|
|
""" |
|
|
|
@@ -131,16 +141,17 @@ class LukasKanadeCUDA(BaseFilter, abc.ABC): |
|
|
|
`False` means that there is no movement. |
|
|
|
""" |
|
|
|
|
|
|
|
old_frame = cv2.cuda_GpuMat(old_frame) |
|
|
|
current_frame = cv2.cuda_GpuMat(current_frame) |
|
|
|
old_frame = self.cv2.cuda_GpuMat(old_frame) |
|
|
|
current_frame = self.cv2.cuda_GpuMat(current_frame) |
|
|
|
|
|
|
|
movement = False |
|
|
|
try: |
|
|
|
old_gray = cv2.cuda.cvtColor(old_frame, cv2.COLOR_BGR2GRAY) |
|
|
|
old_gray = \ |
|
|
|
self.cv2.cuda.cvtColor(old_frame, self.cv2.COLOR_BGR2GRAY) |
|
|
|
p0 = self.corner_detector.detect(old_gray) |
|
|
|
|
|
|
|
current_gray = \ |
|
|
|
cv2.cuda.cvtColor(current_frame, cv2.COLOR_BGR2GRAY) |
|
|
|
self.cv2.cuda.cvtColor(current_frame, self.cv2.COLOR_BGR2GRAY) |
|
|
|
|
|
|
|
# Calculate Optical Flow |
|
|
|
p1, st, err = self.of.calc( |
|
|
|
@@ -161,7 +172,10 @@ class LukasKanadeCUDA(BaseFilter, abc.ABC): |
|
|
|
# Allclose is used instead of array_equal to |
|
|
|
# support array of floats (if we remove rounding). |
|
|
|
movement = \ |
|
|
|
not numpy.allclose(numpy.rint(good_new), numpy.rint(good_old)) |
|
|
|
not numpy.allclose( |
|
|
|
numpy.rint(good_new), |
|
|
|
numpy.rint(good_old) |
|
|
|
) |
|
|
|
except Exception as ex: |
|
|
|
LOGGER.error( |
|
|
|
f"Error during the execution of\ |
|
|
|
|