Skip to content

Commit

Permalink
Merge pull request #1 from jgraving/master
Browse files Browse the repository at this point in the history
update from upstream
  • Loading branch information
Selmaan committed Apr 18, 2020
2 parents 06af00d + 94b8390 commit 52b997b
Show file tree
Hide file tree
Showing 21 changed files with 415 additions and 77 deletions.
15 changes: 1 addition & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ Localization (without tracking) can also be achieved with deep learning software

[Check out our paper](https://doi.org/10.7554/eLife.47994) to find out more.

**NOTE:** This software is still in early-release development. *Expect some adventures.*

<p align="center">
<img src="https://github.com/jgraving/jgraving.github.io/blob/master/files/images/zebra.gif" height="256px">
<img src="https://github.com/jgraving/jgraving.github.io/blob/master/files/images/locust.gif" height="256px">
Expand Down Expand Up @@ -144,17 +142,7 @@ If you use DeepPoseKit for your research please cite [our open-access paper](htt
url={https://doi.org/10.7554/eLife.47994},
}

You can also read [our open-access preprint](http://preprint.deepposekit.org):

@article{graving2019preprint,
title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},
author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},
journal={bioRxiv},
pages={620245},
year={2019},
publisher={Cold Spring Harbor Laboratory}
url={https://doi.org/10.1101/620245}
}
You can also read [our open-access preprint](http://preprint.deepposekit.org).

If you use the [imgaug package](https://github.com/aleju/imgaug) for data augmentation, please also consider [citing it](https://github.com/aleju/imgaug/blob/master/README.md#citation).

Expand All @@ -163,7 +151,6 @@ If you [use data](https://github.com/jgraving/DeepPoseKit#i-already-have-annotat
Please also consider citing the relevant references for the pose estimation model(s) used in your research, which can be found in the documentation (i.e., [`StackedDenseNet`](http://jakegraving.com/DeepPoseKit/html/deepposekit/models/StackedDenseNet.html#references), [`StackedHourglass`](http://jakegraving.com/DeepPoseKit/html/deepposekit/models/StackedHourglass.html#references), [`DeepLabCut`](http://jakegraving.com/DeepPoseKit/html/deepposekit/models/DeepLabCut.html#references), [`LEAP`](http://jakegraving.com/DeepPoseKit/html/deepposekit/models/LEAP.html#references)).

# News

- **October 2019:** Our paper describing DeepPoseKit is published at eLife! (http://paper.deepposekit.org)
- **September 2019**:
- Nature News covers DeepPoseKit: [Deep learning powers a motion-tracking revolution](http://doi.org/10.1038/d41586-019-02942-5)
Expand Down
2 changes: 1 addition & 1 deletion deepposekit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@


__doc__ = """ """ # open('README.md').read()
__version__ = "0.3.5"
__version__ = "0.3.9"
5 changes: 5 additions & 0 deletions deepposekit/annotate/gui/Annotator.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,11 @@ def _data(self):
self.skeleton["annotated"] = False
elif self.key is keys.F:
self.skeleton["annotated"] = True
elif self.key is keys.V:
if self.skeleton.loc[self.idx, ["x", "y"]].isnull()[0]:
self.skeleton.loc[self.idx, ["x", "y"]] = -1
else:
self.skeleton.loc[self.idx, ["x", "y"]] = np.nan
elif self.key in [keys.Q, keys.ESC]:
self._save()
print("Saved")
Expand Down
58 changes: 34 additions & 24 deletions deepposekit/annotate/gui/GUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,9 @@ def _draw_text(self):
else:
color = self.colors[self.idx] # (34, 87, 255)
border_color = np.bitwise_not(color)
if self.skeleton.loc[self.idx, ["x", "y"]].isnull()[0]:
color = (127, 127, 127)

# color = (3, 255, 118)
thickness = 8

Expand All @@ -332,8 +335,11 @@ def _draw_text(self):
color = (254, 79, 48)
else:
color = self.colors[idx] # (34, 87, 255)
if self.skeleton.loc[text_idx, ["x", "y"]].isnull()[0]:
color = (127, 127, 127)
thickness = 2
border_color = (0, 0, 0)


text = self.skeleton.loc[text_idx, "name"]
loc = self.text_locs[(idx + len(self.text_locs) // 4) % len(self.text_locs)]
Expand Down Expand Up @@ -447,29 +453,31 @@ def _draw_points(self):
"""
for idx in self.keypoint_index:
if idx != self.idx:
if np.all(self.skeleton.loc[:, "annotated"]):
color = self.colors[idx]
inv_color = (254, 79, 48)
# inv_color = None
else:
# color = (34, 87, 255)
color = self.colors[idx]
inv_color = self.inv_colors[idx]
center = self._get_scaled_coords(idx)
radius = 5
if inv_color is not None:
self._draw_point(center, radius, inv_color, 2)
self._draw_point(center, radius, color)

center = self._get_scaled_coords(self.idx)
radius = 8
# color = (3, 255, 118)
color = self.colors[self.idx]
inv_color = self.inv_colors[self.idx]
self._draw_point(center, radius, inv_color, 2)
self._draw_crosshairs(center, radius + 3, inv_color, 2)
self._draw_point(center, radius, color)
self._draw_crosshairs(center, radius + 3, color, 1)
if not self.skeleton.loc[idx, ["x", "y"]].isnull()[0]:
if np.all(self.skeleton.loc[:, "annotated"]):
color = self.colors[idx]
inv_color = (254, 79, 48)
# inv_color = None
else:
# color = (34, 87, 255)
color = self.colors[idx]
inv_color = self.inv_colors[idx]
center = self._get_scaled_coords(idx)
radius = 5
if inv_color is not None:
self._draw_point(center, radius, inv_color, 2)
self._draw_point(center, radius, color)

if not self.skeleton.loc[self.idx, ["x", "y"]].isnull()[0]:
center = self._get_scaled_coords(self.idx)
radius = 8
# color = (3, 255, 118)
color = self.colors[self.idx]
inv_color = self.inv_colors[self.idx]
self._draw_point(center, radius, inv_color, 2)
self._draw_crosshairs(center, radius + 3, inv_color, 2)
self._draw_point(center, radius, color)
self._draw_crosshairs(center, radius + 3, color, 1)

def _draw_lines(self):
""" Draw lines
Expand All @@ -483,7 +491,9 @@ def _draw_lines(self):
color = (34, 87, 255)
for idx in self.keypoint_index:
tree = self.skeleton.loc[idx, "tree"]
if tree >= 0:
if (tree >= 0 and
not self.skeleton.loc[tree, ["x", "y"]].isnull()[0] and
not self.skeleton.loc[idx, ["x", "y"]].isnull()[0]):
pt1 = self._get_scaled_coords(idx)
pt2 = self._get_scaled_coords(tree)
cv2.line(
Expand Down
2 changes: 2 additions & 0 deletions deepposekit/annotate/utils/hotkeys.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
A = ord("a")
S = ord("s")
D = ord("d")
V = ord("v")

SPACE = ord(" ")


Expand Down
4 changes: 2 additions & 2 deletions deepposekit/io/BaseGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def get_images(self, indexes):
Takes a list or array of indexes corresponding
to image-keypoint pairs in the dataset.
Returns a numpy array of images with the shape:
(1, height, width, n_channels)
(n_samples, height, width, n_channels)
"""
raise NotImplementedError()

Expand All @@ -83,7 +83,7 @@ def get_keypoints(self, indexes):
Takes a list or array of indexes corresponding to
image-keypoint pairs in the dataset.
Returns a numpy array of keypoints with the shape:
(1, n_keypoints, 2), where 2 is the x,y coordinates
(n_samples, n_keypoints, 2), where 2 is the x,y coordinates
"""
raise NotImplementedError()

Expand Down
6 changes: 3 additions & 3 deletions deepposekit/io/TrainingGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def __call__(self, n_outputs=1, batch_size=32, validation=False, confidence=True
self.confidence = confidence
self.on_epoch_end()
self_copy = copy.deepcopy(self)
if self.augmenter:
if self.augmenter is not None:
self_copy.augmenter.reseed()
return self_copy

Expand Down Expand Up @@ -289,7 +289,7 @@ def augment(self, images, keypoints):
def generate_batch(self, indexes):
"""Generates data containing batch_size samples"""
X, y = self.load_batch(indexes)
if self.augmenter and not self.validation:
if self.augmenter is not None and not self.validation:
X, y = self.augment(X, y)
if self.confidence:
y = draw_confidence_maps(
Expand All @@ -309,7 +309,7 @@ def generate_batch(self, indexes):
return X, y

def get_config(self):
if self.augmenter:
if self.augmenter is not None:
augmenter = True
else:
augmenter = False
Expand Down
2 changes: 1 addition & 1 deletion deepposekit/io/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from tensorflow.python.keras.utils import Sequence
from tensorflow.keras.utils import Sequence
import cv2
import numpy as np
import os
Expand Down
2 changes: 1 addition & 1 deletion deepposekit/models/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def save(self, path, overwrite=True):

def get_config(self):
config = {}
if self.train_generator:
if self.train_generator is not None:
base_config = self.train_generator.get_config()
return dict(list(base_config.items()) + list(config.items()))
else:
Expand Down
3 changes: 1 addition & 2 deletions deepposekit/models/layers/convolutional.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from tensorflow.python.keras.engine import Layer
from tensorflow.python.keras.engine import InputSpec
from tensorflow.keras.layers import Layer, InputSpec

from tensorflow.keras.layers import UpSampling2D

Expand Down
7 changes: 3 additions & 4 deletions deepposekit/models/layers/imagenet_densenet.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@
import numpy as np
import tensorflow.keras as keras

from tensorflow.python.keras.applications import imagenet_utils
from tensorflow.python.keras.applications.imagenet_utils import decode_predictions
from deepposekit.models.layers import imagenet_utils
from deepposekit.models.layers.imagenet_utils import decode_predictions
from tensorflow.keras.layers import Layer
from tensorflow.python.keras.applications import keras_applications

_obtain_input_shape = imagenet_utils.imagenet_utils._obtain_input_shape
_obtain_input_shape = imagenet_utils._obtain_input_shape

backend = keras.backend
layers = keras.layers
Expand Down
11 changes: 5 additions & 6 deletions deepposekit/models/layers/imagenet_mobile.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,13 @@
import numpy as np
import tensorflow.keras as keras

from tensorflow.python.keras.applications import imagenet_utils
from tensorflow.python.keras.applications.imagenet_utils import decode_predictions
from deepposekit.models.layers import imagenet_utils
from deepposekit.models.layers.imagenet_utils import decode_predictions
from tensorflow.keras.layers import Layer
from tensorflow.python.keras.applications import keras_applications
from tensorflow.python.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input

correct_pad = keras_applications.correct_pad
_obtain_input_shape = imagenet_utils.imagenet_utils._obtain_input_shape
correct_pad = imagenet_utils.correct_pad
_obtain_input_shape = imagenet_utils._obtain_input_shape


# TODO Change path to v1.1
Expand Down
4 changes: 2 additions & 2 deletions deepposekit/models/layers/imagenet_resnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
import tensorflow.keras as keras
from tensorflow.keras.layers import Layer

from tensorflow.python.keras.applications import imagenet_utils
from deepposekit.models.layers import imagenet_utils

_obtain_input_shape = imagenet_utils.imagenet_utils._obtain_input_shape
_obtain_input_shape = imagenet_utils._obtain_input_shape

backend = keras.backend
layers = keras.layers
Expand Down
Loading

0 comments on commit 52b997b

Please sign in to comment.