Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RARE2012, add RARE2007 #80

Merged
merged 3 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
* In general, naming convention for attriutes has been changed to use the plural form if the attribute is a list of values for each
element (i.e., `Scanpaths.xs`) and the singular form if the attribute is a single value (i.e., `Scanpaths.length`, `Fixations.x`). This resulted in
renaming `Fixations.subjects` to `Fixations.subject`. The old name is now a deprecated alias.
* Bugfix: Compatibility with torch 2.2 and numpy 2.0
* Bugfix!: The download location of the RARE2012 model changed. The new source code results in slightly different predictions.
* Feature: The RARE2007 model is now available as `pysaliency.external_models.RARE2007`. It's execution requires MATLAB.


* 0.2.22:
* Enhancement: New [Tutorial](notebooks/Tutorial.ipynb).
Expand Down
21 changes: 10 additions & 11 deletions pysaliency/external_models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
from .deepgaze import (
DeepGazeI,
DeepGazeIIE,
)
from .matlab_models import (
AIM,
SUN,
ContextAwareSaliency,
BMS,
GBVS,
GBVSIttiKoch,
Judd,
IttiKoch,
RARE2007,
RARE2012,
SUN,
ContextAwareSaliency,
CovSal,
GBVSIttiKoch,
IttiKoch,
Judd,
)

from .deepgaze import (
DeepGazeI,
DeepGazeIIE,
)

from .utils import ExternalModelMixin
71 changes: 54 additions & 17 deletions pysaliency/external_models/matlab_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,18 +454,61 @@ def _setup(self, saliency_toolbox_archive):
f.write(resource_string(__name__, 'scripts/IttiKoch_wrapper.m'))


class RARE2007(ExternalModelMixin, MatlabSaliencyMapModel):
"""
RARE2007 by Mancas.
The original matlab code is used.

.. note::
The source code published by the authors is used without modifications.

.. seealso::
Matei Mancas. Relative influence of bottom-up and top-down attention.
[International Workshop on Attention in Cognitive Systems 2008]

https://numediart.github.io/VisualAttention-RareFamily/
https://github.com/numediart/VisualAttention-Rare2007
"""
__modelname__ = 'RARE2007'

def __init__(self, location=None, **kwargs):
self.setup(location)
super(RARE2007, self).__init__(os.path.join(self.location, 'RARE2007_wrapper.m'), only_color_stimuli=True, **kwargs)

def _setup(self):
source_location = os.path.join(self.location, 'source')
directory = 'VisualAttention-Rare2007-ee7ef25c9b6cc7e96837091e868d03bd97b4b131'
print('Downloading RARE2007 Model...')
url = 'https://github.com/numediart/VisualAttention-Rare2007/archive/ee7ef25c9b6cc7e96837091e868d03bd97b4b131.zip'
download_extract_patch(url,
'7ee05ae059dac10478b5cabc8ee066dc',
os.path.join(source_location, directory),
location_in_archive=True,
patches=None)

with open(os.path.join(self.location, 'RARE2007_wrapper.m'), 'wb') as f:
f.write(resource_string(__name__, 'scripts/RARE2007_wrapper.m'))


class RARE2012(ExternalModelMixin, MatlabSaliencyMapModel):
"""
RARE2012 by Margolin et al.
The original matlab code is used.

.. note::
The original code is patched to work from other directories.

The model makes use of the [SaliencyToolbox](http://www.saliencytoolbox.net/). Due
to licence restrictions the Toolbox cannot be downloaded automatically. You have to
download it yourself and provide the location of the zipfile via the
`saliency_toolbox_archive`-keyword to the constructor.

This page is not available anymore, the RARE models are now hosted
at https://numediart.github.io/VisualAttention-RareFamily/, the RARE2012
model is published at https://github.com/numediart/VisualAttention-Rare2012.
This model is a wrapper around the published (compiled) matlab code.

The model used to be hosted at
http://www.tcts.fpms.ac.be/attention/?categorie16/what-and-why.
This page is not available anymore, the RARE models are now hosted
at https://numediart.github.io/VisualAttention-RareFamily/ and GitHub.
With this change, the behaviour of RARE2012 changed slightly
compared to the earlier version (e.g., saliency maps look a bit smoother).

This model does not work with octave due to incompabilities
of octave with matlab (RARE2012 comes as precompiled matlab file).
Expand All @@ -477,7 +520,7 @@ class RARE2012(ExternalModelMixin, MatlabSaliencyMapModel):
saliency detection with its comparative statistical analysis
[Signal Processing: Image Communication, 2013]

http://www.tcts.fpms.ac.be/attention/?categorie16/what-and-why
https://numediart.github.io/VisualAttention-RareFamily/
"""
__modelname__ = 'RARE2012'

Expand All @@ -487,18 +530,12 @@ def __init__(self, location=None, **kwargs):

def _setup(self):
source_location = os.path.join(self.location, 'source')
directory = 'VisualAttention-Rare2012-55ba7414b971429e5e899ddfa574e4235fc806e6'
print('Downloading RARE2012 Model...')
#download_extract_patch('http://www.tcts.fpms.ac.be/attention/data/documents/data/rare2012.zip',
download_extract_patch('http://tcts.fpms.ac.be/attention/data/medias/documents/models/rare2012.zip',
'5a0a0de83e82b46fa70cea8b0a6bae55',
os.path.join(source_location, 'Rare2012'),
location_in_archive=True,
patches=None)

print('Downloading simplegabortb-v1.0.0')
download_extract_patch('http://www2.it.lut.fi/project/simplegabor/downloads/src/simplegabortb/simplegabortb-v1.0.0.tar.gz',
'92bc6ae7178a7b1301fad52489f5d677',
os.path.join(source_location, 'simplegabortb-v1.0.0'),
url = 'https://github.com/numediart/VisualAttention-Rare2012/archive/55ba7414b971429e5e899ddfa574e4235fc806e6.zip'
download_extract_patch(url,
'a5bbd8a42c231530834659acfd0d2b64.',
os.path.join(source_location, directory),
location_in_archive=True,
patches=None)

Expand Down
7 changes: 3 additions & 4 deletions pysaliency/external_models/scripts/RARE2012_wrapper.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
function [ ] = RARE2012(filename, outname)

addpath('source/simplegabortb-v1.0.0')
addpath('source/Rare2012')
addpath('source/VisualAttention-Rare2012-55ba7414b971429e5e899ddfa574e4235fc806e6')

I = im2double(imread(filename));
saliency_map = RARE2012(I);
saliency_map = rare2012(I);
save(outname, 'saliency_map');

12 changes: 3 additions & 9 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,14 @@ def matlab(request, pytestconfig):
pysaliency.utils.MatlabOptions.octave_names = []
elif request.param == 'octave':
if pytestconfig.getoption("--nooctave"):
pytest.skip("skipped octave")
pytest.skip("skipped octave due to command line option")
elif any([marker.name == 'skip_octave' for marker in request.node.own_markers]):
pytest.skip("skipped octave due to test marker")
pysaliency.utils.MatlabOptions.matlab_names = []
pysaliency.utils.MatlabOptions.octave_names = ['octave', 'octave.exe']

return request.param


@pytest.fixture()
def skip_by_matlab(request, matlab):
if request.node.get_marker('skip_octave'):
if matlab == 'octave':
pytest.skip('skipped octave')


#@pytest.fixture(params=["no_location", "with_location"])
#def location(tmpdir, request):
# if request.param == 'no_location':
Expand Down
Binary file not shown.
Binary file not shown.
Binary file modified tests/external_models/RARE2012_color_stimulus.npy
Binary file not shown.
Binary file modified tests/external_models/RARE2012_grayscale_stimulus.npy
Binary file not shown.
14 changes: 14 additions & 0 deletions tests/test_external_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ def test_IttiKoch(tmpdir, matlab, color_stimulus, grayscale_stimulus):
np.load(os.path.join('tests', 'external_models', '{}_grayscale_stimulus.npy'.format(model.__modelname__))))


@pytest.mark.skip_octave
@pytest.mark.matlab
def test_RARE2007(tmpdir, matlab, color_stimulus, grayscale_stimulus):
model = pysaliency.external_models.RARE2007(location=str(tmpdir))
print('Testing color')
saliency_map = model.saliency_map(color_stimulus)
np.testing.assert_allclose(saliency_map,
np.load(os.path.join('tests', 'external_models', '{}_color_stimulus.npy'.format(model.__modelname__))))
print('Testing Grayscale')
saliency_map = model.saliency_map(grayscale_stimulus)
np.testing.assert_allclose(saliency_map,
np.load(os.path.join('tests', 'external_models', '{}_grayscale_stimulus.npy'.format(model.__modelname__))))


@pytest.mark.skip_octave
@pytest.mark.matlab
def test_RARE2012(tmpdir, matlab, color_stimulus, grayscale_stimulus):
Expand Down
Loading