From 6f92797d55aacfab82658b2f350cea66eb645bfb Mon Sep 17 00:00:00 2001 From: yunzhil Date: Sun, 25 Jul 2021 12:33:15 -0400 Subject: [PATCH 01/10] fix bug --- trackpointer/centroidMulti.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/trackpointer/centroidMulti.py b/trackpointer/centroidMulti.py index d48bb6b..ac67356 100644 --- a/trackpointer/centroidMulti.py +++ b/trackpointer/centroidMulti.py @@ -108,7 +108,10 @@ def measure(self, I): binReg = centroidMulti.regionProposal(Ip) self.tpt = np.array(binReg).T # from N x 2 to 2 x N - self.haveMeas = self.tpt.shape[1] > 0 + if len(self.tpt) == 0: + self.haveMeas = 0 + else: + self.haveMeas = self.tpt.shape[1] > 0 # @todo # Not sure if the translation is correct From 7321c4e36533651b53662c104e6c6dc45afe72df Mon Sep 17 00:00:00 2001 From: yunzhil Date: Mon, 2 Aug 2021 09:28:35 -0400 Subject: [PATCH 02/10] update dataclass & update names --- testing/trackTri01.py | 4 ++-- testing/trackTri02.py | 4 ++-- trackpointer/centroid.py | 26 +++++++++++++------------- trackpointer/centroidMulti.py | 15 ++------------- 4 files changed, 19 insertions(+), 30 deletions(-) diff --git a/testing/trackTri01.py b/testing/trackTri01.py index 58c1529..3c70b0f 100644 --- a/testing/trackTri01.py +++ b/testing/trackTri01.py @@ -105,7 +105,7 @@ dI = binDet.Ip trackptr.process(dI) - tstate = trackptr.getstate() + tstate = trackptr.getState() # @todo # There is no setting in the trackTri01.m to enable the display of the tracker as it uses @@ -113,7 +113,7 @@ # For now, we manully set the state. if ii==0: # Start tracking - trackptr.setstate(tstate.tpt) + trackptr.setState(tstate.tpt) plt.cla() trackptr.displayState(tstate) diff --git a/testing/trackTri02.py b/testing/trackTri02.py index 497186b..8b9df30 100644 --- a/testing/trackTri02.py +++ b/testing/trackTri02.py @@ -122,7 +122,7 @@ dI = binDet.Ip trackptr.process(dI) - tstate = trackptr.getstate() + tstate = trackptr.getState() # @todo # There is no setting in the trackTri01.m to enable the display of the tracker as it uses @@ -130,7 +130,7 @@ # For now, we manully set the state. if ii==0: # Start tracking - trackptr.setstate(tstate.tpt) + trackptr.setState(tstate.tpt) plt.cla() trackptr.displayState(tstate) diff --git a/trackpointer/centroid.py b/trackpointer/centroid.py index 6585516..d2f0fd0 100644 --- a/trackpointer/centroid.py +++ b/trackpointer/centroid.py @@ -35,12 +35,12 @@ import numpy as np import matplotlib.pyplot as plt +from dataclasses import dataclass -class State(object): - - def __init__(self, tpt=None, haveMeas=None): - self.tpt = tpt - self.haveMeas = haveMeas +@dataclass +class State: + tpt: np.ndarray = np.array([]) + haveMeas: bool = False class Params(object): @@ -94,37 +94,37 @@ def get(self, fname): pass - #============================= emptystate ============================ + #============================= emptyState ============================ # # @brief Return an empty state structure. # # - def emptystate(self): + def emptyState(self): estate= State(tpt=[], haveMeas=False) return estate - #============================== setstate ============================= + #============================== setState ============================= # # @brief Set the state vector. # # @param[in] g The desired state. # - def setstate(self, g): + def setState(self, g): self.tpt = g self.haveMeas = True - #============================== getstate ============================= + #============================== getState ============================= # # @brief Return the track-pointer state. # # @param[out] tstate The track point state structure. # - def getstate(self): + def getState(self): tstate = State(tpt=self.tpt, haveMeas=self.haveMeas) @@ -190,9 +190,9 @@ def measure(self, I): # @todo # Not sure if the translation is correct # if (nargout == 1): - # mstate = this.getstate(); + # mstate = this.getState(); # end - mstate = self.getstate() + mstate = self.getState() return mstate diff --git a/trackpointer/centroidMulti.py b/trackpointer/centroidMulti.py index ac67356..4702b7f 100644 --- a/trackpointer/centroidMulti.py +++ b/trackpointer/centroidMulti.py @@ -39,17 +39,6 @@ from skimage.measure import regionprops from trackpointer.centroid import centroid -class State(object): - - def __init__(self, tpt=None, haveMeas=None): - self.tpt = tpt - self.haveMeas = haveMeas - -class Params(object): - - def __init__(self): - pass - class centroidMulti(centroid): # ============================== centroid ============================= @@ -61,7 +50,7 @@ class centroidMulti(centroid): # def __init__(self, iPt=None, params=None): - super(centroidMulti,self).__init__(iPt,params) + super(centroidMulti,self).__init__(iPt, params) #=============================== set =============================== @@ -118,7 +107,7 @@ def measure(self, I): # if (nargout == 1): # mstate = this.getstate(); # end - mstate = self.getstate() + mstate = self.getState() return mstate From edf9255bf915c49a9f9be8e1f05e8d28464b5797 Mon Sep 17 00:00:00 2001 From: yunzhil Date: Mon, 2 Aug 2021 16:56:08 -0400 Subject: [PATCH 03/10] update with OpenCV coordinate system --- testing/trackTri01.py | 4 ++-- testing/trackTri02.py | 4 ++-- trackpointer/centroid.py | 39 ++++++++++++++++----------------- trackpointer/centroidMulti.py | 41 +++++------------------------------ 4 files changed, 28 insertions(+), 60 deletions(-) diff --git a/testing/trackTri01.py b/testing/trackTri01.py index 3c70b0f..4485a1d 100644 --- a/testing/trackTri01.py +++ b/testing/trackTri01.py @@ -113,10 +113,10 @@ # For now, we manully set the state. if ii==0: # Start tracking - trackptr.setState(tstate.tpt) + trackptr.setState(tstate) plt.cla() - trackptr.displayState(tstate) + trackptr.displayState() plt.imshow(I, cmap='Greys') plt.pause(0.001) diff --git a/testing/trackTri02.py b/testing/trackTri02.py index 8b9df30..4ecfbeb 100644 --- a/testing/trackTri02.py +++ b/testing/trackTri02.py @@ -130,10 +130,10 @@ # For now, we manully set the state. if ii==0: # Start tracking - trackptr.setState(tstate.tpt) + trackptr.setState(tstate) plt.cla() - trackptr.displayState(tstate) + trackptr.displayState() plt.imshow(I, cmap='Greys') plt.pause(0.001) diff --git a/trackpointer/centroid.py b/trackpointer/centroid.py index d2f0fd0..fc9e8fd 100644 --- a/trackpointer/centroid.py +++ b/trackpointer/centroid.py @@ -58,15 +58,18 @@ class centroid(object): # def __init__(self, iPt=None, params=None): - if iPt: - self.tpt = iPt - - if params is None: + if not isinstance(params, Params): params = self.setIfMissing(params,'plotStyle','rx') self.tparams = params self.haveMeas = False + if iPt: + self.tpt = iPt + self.haveMeas = True + else: + self.tpt = None + #=============================== set =============================== # # @brief Set parameters for the tracker. @@ -101,7 +104,7 @@ def get(self, fname): # def emptyState(self): - estate= State(tpt=[], haveMeas=False) + estate= State(tpt=np.array([]), haveMeas=False) return estate @@ -109,12 +112,12 @@ def emptyState(self): # # @brief Set the state vector. # - # @param[in] g The desired state. + # @param[in] dPt The desired state. # - def setState(self, g): + def setState(self, dPt): - self.tpt = g - self.haveMeas = True + self.tpt = dPt.tpt + self.haveMeas = dPt.haveMeas @@ -177,21 +180,14 @@ def measure(self, I): else: Ip = I - + # y,x in OpenCV ibin, jbin = np.nonzero(Ip) + # x,y in OpenCV self.tpt = np.array([np.mean(jbin), np.mean(ibin)]).reshape(-1,1) self.haveMeas = self.tpt.shape[1] > 0 - # center = transpose(size(image)*[0 1;1 0]+1)/2; - # trackpoint = trackpoint - center; - - # @todo - # Not sure if the translation is correct - # if (nargout == 1): - # mstate = this.getState(); - # end mstate = self.getState() return mstate @@ -217,14 +213,17 @@ def process(self, I): # def displayState(self, dstate = None): - if dstate: + if isinstance(dstate, State): if dstate.haveMeas: + # Change to OpenCV style plt.plot(dstate.tpt[0,:], dstate.tpt[1,:], self.tparams.plotStyle) else: if self.haveMeas: + # Change to OpenCV style plt.plot(self.tpt[0,:], self.tpt[1,:], self.tparams.plotStyle) + #========================= displayDebugState ========================= # # @brief Displays internally stored intermediate process output. @@ -249,7 +248,7 @@ def setIfMissing(self, params, pname, pval): # @todo # Need double check on this translation - if params is None or not isinstance(params): + if not isinstance(params, Params): params = Params() setattr(params, pname, pval) return params diff --git a/trackpointer/centroidMulti.py b/trackpointer/centroidMulti.py index 4702b7f..d50deea 100644 --- a/trackpointer/centroidMulti.py +++ b/trackpointer/centroidMulti.py @@ -37,7 +37,7 @@ import cv2 from skimage.measure import regionprops -from trackpointer.centroid import centroid +from trackpointer.centroid import centroid, State class centroidMulti(centroid): @@ -95,18 +95,13 @@ def measure(self, I): Ip = I binReg = centroidMulti.regionProposal(Ip) - self.tpt = np.array(binReg).T # from N x 2 to 2 x N + self.tpt = np.array(binReg).T # from N x 2 to 2 x N if len(self.tpt) == 0: - self.haveMeas = 0 + self.haveMeas = False else: self.haveMeas = self.tpt.shape[1] > 0 - # @todo - # Not sure if the translation is correct - # if (nargout == 1): - # mstate = this.getstate(); - # end mstate = self.getState() return mstate @@ -121,34 +116,6 @@ def process(self, I): self.measure(I) - #============================ displayState =========================== - # - # @brief Displays the current track pointer measurement. - # - # Assumes that the current figure to plot to is activate. If the plot has - # existing elements that should remain, then hold should be enabled prior to - # invoking this function. - # - def displayState(self, dstate = None): - - if dstate: - if dstate.haveMeas: - plt.plot(dstate.tpt[0,:], dstate.tpt[1,:], self.tparams.plotStyle) - else: - if self.haveMeas: - plt.plot(self.tpt[0,:], self.tpt[1,:], self.tparams.plotStyle) - - - #========================= displayDebugState ========================= - # - # @brief Displays internally stored intermediate process output. - # - # Currently, there is no intermediate output, though that might change - # in the future. - # - def displayDebugState(self, dbstate=None): - pass - #========================= regionProposal ========================= # # @brief Find out the centroid for multiple objects @@ -168,6 +135,8 @@ def regionProposal(I): # Note that regionprops assumes different areas are with different labels # See https://stackoverflow.com/a/61591279/5269146 + + # Have been transferred to the OpenCV style as regionprops is from skimage binReg = [[i.centroid[1], i.centroid[0]] for i in regionprops(mask)] return binReg From d3b4fced566a87510ced9df8f34f66c46c23df9c Mon Sep 17 00:00:00 2001 From: yiyeChen Date: Wed, 29 Sep 2021 12:49:04 -0400 Subject: [PATCH 04/10] Update the parameter to the dataclass style --- trackpointer/centroid.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/trackpointer/centroid.py b/trackpointer/centroid.py index 6585516..101dbc9 100644 --- a/trackpointer/centroid.py +++ b/trackpointer/centroid.py @@ -33,19 +33,31 @@ # #================================ centroid =============================== +from dataclasses import dataclass +from cv2 import data import numpy as np import matplotlib.pyplot as plt class State(object): + """[summary] + + Args: + object ([type]): [description] + """ def __init__(self, tpt=None, haveMeas=None): self.tpt = tpt self.haveMeas = haveMeas +@dataclass class Params(object): + """The parameters for the centroid tracker - def __init__(self): - pass + Args: + plotStyle (str): The plot style from the matplotlib for the centroid. Defaults to "rx". \ + Detailed choices see: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html + """ + plotStyle:str = "rx" class centroid(object): @@ -56,14 +68,11 @@ class centroid(object): # @param[in] iPt The initial track point coordinates. # params The parameter structure. # - def __init__(self, iPt=None, params=None): + def __init__(self, iPt=None, params=Params()): if iPt: self.tpt = iPt - if params is None: - params = self.setIfMissing(params,'plotStyle','rx') - self.tparams = params self.haveMeas = False From e87ef48e0671592043e79aa380e5e927fd2e31bf Mon Sep 17 00:00:00 2001 From: yiyeChen Date: Wed, 29 Sep 2021 15:54:29 -0400 Subject: [PATCH 05/10] update the params for the centroidMulti --- trackpointer/centroidMulti.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/trackpointer/centroidMulti.py b/trackpointer/centroidMulti.py index ac67356..71ed414 100644 --- a/trackpointer/centroidMulti.py +++ b/trackpointer/centroidMulti.py @@ -32,12 +32,14 @@ # #================================ centroid =============================== +from dataclasses import dataclass import numpy as np import matplotlib.pyplot as plt import cv2 from skimage.measure import regionprops from trackpointer.centroid import centroid +from trackpointer.centroid import Params as cParams class State(object): @@ -45,10 +47,10 @@ def __init__(self, tpt=None, haveMeas=None): self.tpt = tpt self.haveMeas = haveMeas -class Params(object): +@dataclass +class Params(cParams): + improcessor: any = None - def __init__(self): - pass class centroidMulti(centroid): @@ -59,7 +61,7 @@ class centroidMulti(centroid): # @param[in] iPt The initial track point coordinates. # params The parameter structure. # - def __init__(self, iPt=None, params=None): + def __init__(self, iPt=None, params=Params()): super(centroidMulti,self).__init__(iPt,params) From 643709bd433f4d1c91d749db7f8457b062235639 Mon Sep 17 00:00:00 2001 From: yiyeChen Date: Wed, 29 Sep 2021 16:34:37 -0400 Subject: [PATCH 06/10] Update multiCentroid for binary input & update display with customized axis --- trackpointer/centroid.py | 9 ++++++--- trackpointer/centroidMulti.py | 5 +++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/trackpointer/centroid.py b/trackpointer/centroid.py index 3e465ac..f9f9bc7 100644 --- a/trackpointer/centroid.py +++ b/trackpointer/centroid.py @@ -218,16 +218,19 @@ def process(self, I): # existing elements that should remain, then hold should be enabled prior to # invoking this function. # - def displayState(self, dstate = None): + def displayState(self, dstate = None, ax=None): + + if ax is None: + ax = plt.gca() if isinstance(dstate, State): if dstate.haveMeas: # Change to OpenCV style - plt.plot(dstate.tpt[0,:], dstate.tpt[1,:], self.tparams.plotStyle) + ax.plot(dstate.tpt[0,:], dstate.tpt[1,:], self.tparams.plotStyle) else: if self.haveMeas: # Change to OpenCV style - plt.plot(self.tpt[0,:], self.tpt[1,:], self.tparams.plotStyle) + ax.plot(self.tpt[0,:], self.tpt[1,:], self.tparams.plotStyle) diff --git a/trackpointer/centroidMulti.py b/trackpointer/centroidMulti.py index 1b646ea..84e545a 100644 --- a/trackpointer/centroidMulti.py +++ b/trackpointer/centroidMulti.py @@ -125,8 +125,9 @@ def process(self, I): # @ staticmethod def regionProposal(I): - mask = np.zeros_like(I) - cnts = cv2.findContours(I, cv2.RETR_EXTERNAL, + Ip = I.astype(np.uint8) + mask = np.zeros_like(Ip) + cnts = cv2.findContours(Ip, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # For OpenCV 4+ cnts = cnts[0] From 4225795977724df550af0a7a49ee85fd05be9458 Mon Sep 17 00:00:00 2001 From: Yiye Chen Date: Thu, 28 Oct 2021 18:44:22 -0400 Subject: [PATCH 07/10] Fix the bug of centroid when no target is presented --- trackpointer/centroid.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/trackpointer/centroid.py b/trackpointer/centroid.py index f9f9bc7..1d72588 100644 --- a/trackpointer/centroid.py +++ b/trackpointer/centroid.py @@ -190,10 +190,13 @@ def measure(self, I): # y,x in OpenCV ibin, jbin = np.nonzero(Ip) - # x,y in OpenCV - self.tpt = np.array([np.mean(jbin), np.mean(ibin)]).reshape(-1,1) - - self.haveMeas = self.tpt.shape[1] > 0 + if ibin.size == 0: + self.tpt = None + self.haveMeas = False + else: + # x,y in OpenCV + self.tpt = np.array([np.mean(jbin), np.mean(ibin)]).reshape(-1,1) + self.haveMeas = True mstate = self.getState() From 63cc79f51ae43882c15b8c2f1b9d75a07c33b029 Mon Sep 17 00:00:00 2001 From: Yiye Chen Date: Fri, 11 Feb 2022 16:54:52 -0500 Subject: [PATCH 08/10] Update readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index d2c27ff..418e6aa 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ Implementations of trackpointer methods. Track object by giving track point or t ## installation instruction +First install the dependencies following its instruction: [Lie](https://github.com/ivapylibs/Lie). + +The install this repository: + ``` git clone git@github.com:ivapylibs/trackpointer.git pip3 install -e trackpointer/ From 296a1d050e2e05b35ca660f75a0facfeb02f81c8 Mon Sep 17 00:00:00 2001 From: yunzhil Date: Sat, 12 Feb 2022 17:37:10 -0500 Subject: [PATCH 09/10] re-organize --- testing/fakeTri02.py | 4 ++-- trackpointer/utils/__init__.py | 0 {testing => trackpointer/utils}/fakeTriangle.py | 0 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 trackpointer/utils/__init__.py rename {testing => trackpointer/utils}/fakeTriangle.py (100%) diff --git a/testing/fakeTri02.py b/testing/fakeTri02.py index afe7561..54a8013 100644 --- a/testing/fakeTri02.py +++ b/testing/fakeTri02.py @@ -33,7 +33,7 @@ import numpy as np import matplotlib.pyplot as plt -from fakeTriangle import fakeTriangle +from trackpointer.utils.fakeTriangle import fakeTriangle import Lie.group.SE2.Homog #==[1] Specify the marker geometry on the rigid body, and other related # parameters. Instantiate the simulated image generator. @@ -83,4 +83,4 @@ plt.draw() # -#=============================== fakeTri02 =============================== \ No newline at end of file +#=============================== fakeTri02 =============================== diff --git a/trackpointer/utils/__init__.py b/trackpointer/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/testing/fakeTriangle.py b/trackpointer/utils/fakeTriangle.py similarity index 100% rename from testing/fakeTriangle.py rename to trackpointer/utils/fakeTriangle.py From 9458f866b537771453263e26907fbcbf811ca0e8 Mon Sep 17 00:00:00 2001 From: yunzhil Date: Thu, 3 Mar 2022 11:32:43 -0500 Subject: [PATCH 10/10] minor update --- README.md | 10 ++++++---- testing/fakeTri02.py | 1 + testing/trackTri01.py | 2 +- testing/trackTri02.py | 2 +- trackpointer/centroid.py | 2 -- trackpointer/centroidMulti.py | 2 -- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 418e6aa..30a754c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ # trackpointers Implementations of trackpointer methods. Track object by giving track point or track coordinate frame. -## installation instruction +## Install -First install the dependencies following its instruction: [Lie](https://github.com/ivapylibs/Lie). +Install the following repositories from the source: -The install this repository: +- [improcessor](https://github.com/ivapylibs/improcessor) +- [detector](https://github.com/ivapylibs/detector.git) +- [Lie](https://github.com/ivapylibs/Lie) ``` git clone git@github.com:ivapylibs/trackpointer.git @@ -15,5 +17,5 @@ pip3 install -e trackpointer/ The test files are shell command line executable and should work when invoked, presuming that pip installation has been performed. If no modifications to the source code will be performed then the ``-e`` flag -is not neessary (e.g., use the flag if the underlying code will be +is not necessary (e.g., use the flag if the underlying code will be modified). diff --git a/testing/fakeTri02.py b/testing/fakeTri02.py index 54a8013..8431906 100644 --- a/testing/fakeTri02.py +++ b/testing/fakeTri02.py @@ -35,6 +35,7 @@ from trackpointer.utils.fakeTriangle import fakeTriangle import Lie.group.SE2.Homog + #==[1] Specify the marker geometry on the rigid body, and other related # parameters. Instantiate the simulated image generator. # diff --git a/testing/trackTri01.py b/testing/trackTri01.py index 4485a1d..6f78a0b 100644 --- a/testing/trackTri01.py +++ b/testing/trackTri01.py @@ -36,7 +36,7 @@ import numpy as np import matplotlib.pyplot as plt -from fakeTriangle import fakeTriangle +from trackpointer.utils.fakeTriangle import fakeTriangle import Lie.group.SE2.Homog import improcessor.basic as improcessor import detector.inImage as detector diff --git a/testing/trackTri02.py b/testing/trackTri02.py index 4ecfbeb..e3dc11d 100644 --- a/testing/trackTri02.py +++ b/testing/trackTri02.py @@ -35,7 +35,7 @@ import numpy as np import matplotlib.pyplot as plt -from fakeTriangle import fakeTriangle +from trackpointer.utils.fakeTriangle import fakeTriangle import Lie.group.SE2.Homog import improcessor.basic as improcessor import detector.inImage as detector diff --git a/trackpointer/centroid.py b/trackpointer/centroid.py index 1d72588..ed746c3 100644 --- a/trackpointer/centroid.py +++ b/trackpointer/centroid.py @@ -33,8 +33,6 @@ # #================================ centroid =============================== -from dataclasses import dataclass -from cv2 import data import numpy as np import matplotlib.pyplot as plt from dataclasses import dataclass diff --git a/trackpointer/centroidMulti.py b/trackpointer/centroidMulti.py index 84e545a..6a159e6 100644 --- a/trackpointer/centroidMulti.py +++ b/trackpointer/centroidMulti.py @@ -32,9 +32,7 @@ # #================================ centroid =============================== -from dataclasses import dataclass import numpy as np -import matplotlib.pyplot as plt import cv2 from skimage.measure import regionprops