Parallel SIFT features extraction

14 views
Skip to first unread message

Thomas

unread,
Aug 16, 2015, 3:39:12 PM8/16/15
to Fiji-devel
Dear List,

I get wrong features when running the jython script below (inspired from here, line 470) to extract SIFT features in parallel from several images present on disk. I can see that the features are wrong as with more than 2 threads, some images give erroneously large amounts of features (see logs below, images 37,39 for example).

Does somebody know whether I am doing something wrong ?
Thanks for your help
Thomas

Windows Server 2012, Fiji 64bit

import ij
from ij import IJ

from mpicbg.ij import SIFT
from mpicbg.imagefeatures import FloatArray2DSIFT

from java.util import HashSet
from java.lang import Thread
from java.util.concurrent.atomic import AtomicInteger
from java.lang import Runtime

paths = xxx # list containing the paths of the images
nImages = len(paths)

atomicI = AtomicInteger(0)
threads = []

def getFeatures():
floatSIFT = FloatArray2DSIFT(param)
ijSIFTLowRes = SIFT(floatSIFT)

while atomicI.get() < (nImages - 1):
k = atomicI.getAndIncrement()
if k < nImages:
imp = IJ.openImage(paths[k])
ip = imp.getProcessor()
features = HashSet()
ijSIFTLowRes.extractFeatures(ip, features)
IJ.log( str(k) + ': ' + str(features.size()) + ' features extracted' )
# if features.size() > 3000:
# IJ.log(str(k) + ': ' + '####################################SOMETHING WRONG##################')
imp.close()
del features

# Creating and starting the threads
for p in range(int (Runtime.getRuntime().availableProcessors() * 0.9 )):
# for p in range(1):
thread = Thread(getFeatures)
threads.append(thread)
thread.start()
IJ.log('Thread ' + str(p) + ' started')

# Joining the threads
for thread in threads:
thread.join()
IJ.log('Thread joined')

IJ.log('Computing features done')

Log 1 Thread 
Starting ...
Thread 0 started
0: 924 features extracted
1: 980 features extracted
2: 988 features extracted
3: 873 features extracted
4: 985 features extracted
5: 1059 features extracted
6: 1040 features extracted
7: 1022 features extracted
8: 898 features extracted
9: 1018 features extracted
10: 858 features extracted
11: 844 features extracted
12: 1035 features extracted
13: 950 features extracted
14: 983 features extracted
15: 1026 features extracted
16: 832 features extracted
17: 968 features extracted
18: 1038 features extracted
19: 1012 features extracted
20: 850 features extracted
21: 1089 features extracted
22: 985 features extracted
23: 1074 features extracted
24: 1002 features extracted
25: 1014 features extracted
26: 1083 features extracted
27: 1004 features extracted
28: 910 features extracted
29: 1007 features extracted
30: 966 features extracted
31: 1071 features extracted
32: 961 features extracted
33: 969 features extracted
34: 981 features extracted
35: 895 features extracted
36: 942 features extracted
37: 1041 features extracted
38: 1056 features extracted
39: 991 features extracted
40: 970 features extracted
41: 945 features extracted
42: 1006 features extracted
43: 975 features extracted
44: 948 features extracted
45: 858 features extracted
46: 1006 features extracted
47: 1134 features extracted
48: 1044 features extracted
49: 1013 features extracted
50: 1033 features extracted
51: 974 features extracted
52: 991 features extracted
53: 933 features extracted
54: 1001 features extracted
55: 855 features extracted
56: 1008 features extracted
57: 935 features extracted
58: 992 features extracted
59: 909 features extracted
60: 905 features extracted
61: 996 features extracted
62: 881 features extracted
63: 999 features extracted
64: 754 features extracted
65: 917 features extracted
66: 720 features extracted
67: 1006 features extracted
68: 1003 features extracted
69: 919 features extracted
70: 964 features extracted
71: 957 features extracted
72: 977 features extracted
73: 970 features extracted
74: 944 features extracted
75: 992 features extracted
76: 966 features extracted
77: 866 features extracted
78: 964 features extracted
79: 926 features extracted
80: 959 features extracted
81: 1014 features extracted
82: 990 features extracted
83: 958 features extracted
84: 926 features extracted
85: 974 features extracted
86: 953 features extracted
87: 963 features extracted
88: 987 features extracted
89: 885 features extracted
90: 846 features extracted
91: 943 features extracted
92: 926 features extracted
93: 899 features extracted
94: 883 features extracted
95: 961 features extracted
96: 957 features extracted
97: 861 features extracted
98: 902 features extracted
99: 888 features extracted


Log 2 Threads
Thread 0 started
Thread 1 started
0: 924 features extracted
1: 980 features extracted
2: 988 features extracted
3: 873 features extracted
5: 1059 features extracted
4: 985 features extracted
6: 1040 features extracted
7: 1022 features extracted
8: 898 features extracted
9: 1018 features extracted
11: 844 features extracted
10: 858 features extracted
12: 1035 features extracted
13: 950 features extracted
14: 983 features extracted
16: 832 features extracted
15: 1026 features extracted
17: 968 features extracted
18: 1038 features extracted
19: 1012 features extracted
20: 850 features extracted
21: 1089 features extracted
23: 1074 features extracted
22: 985 features extracted
24: 1002 features extracted
25: 1014 features extracted
26: 1083 features extracted
27: 1004 features extracted
28: 910 features extracted
29: 1007 features extracted
30: 966 features extracted
31: 1071 features extracted
32: 2901 features extracted
33: 969 features extracted
34: 3189 features extracted
36: 2403 features extracted
35: 895 features extracted
37: 3156 features extracted
39: 3437 features extracted
38: 1056 features extracted
40: 3045 features extracted
42: 3054 features extracted
41: 945 features extracted
43: 2716 features extracted
44: 948 features extracted
45: 2393 features extracted
47: 3039 features extracted
46: 1006 features extracted
48: 3105 features extracted
50: 3436 features extracted
49: 1013 features extracted
51: 2830 features extracted
52: 991 features extracted
53: 2945 features extracted
55: 2510 features extracted
54: 1001 features extracted
56: 3122 features extracted
58: 2941 features extracted
57: 935 features extracted
59: 3006 features extracted
60: 905 features extracted
61: 2864 features extracted
63: 3099 features extracted
62: 881 features extracted
64: 2096 features extracted
66: 1941 features extracted
65: 917 features extracted
67: 3050 features extracted
69: 2379 features extracted
68: 1003 features extracted
70: 2972 features extracted
72: 2864 features extracted
71: 957 features extracted
73: 3012 features extracted
75: 3301 features extracted
74: 944 features extracted
76: 2644 features extracted
78: 3054 features extracted
77: 866 features extracted
80: 2519 features extracted
79: 926 features extracted
81: 3177 features extracted
83: 3142 features extracted
82: 990 features extracted
84: 2637 features extracted
86: 2744 features extracted
85: 974 features extracted
87: 2934 features extracted
89: 2590 features extracted
88: 987 features extracted
90: 2962 features extracted
92: 2900 features extracted
91: 943 features extracted
93: 2878 features extracted
94: 883 features extracted
95: 2773 features extracted
97: 2392 features extracted
96: 957 features extracted
98: 2641 features extracted
100: 2738 features extracted
99: 888 features extracted



Thomas

unread,
Sep 27, 2015, 7:47:00 PM9/27/15
to Fiji-devel
I have not found a solution but this might be related to my problem (line 504 in AlignLayersTask)
// Not concurrent safe! So two copies, one per layer and Thread:
final SIFT ijSIFT1 = new SIFT( new FloatArray2DSIFT( p.sift ) );

although in the script above I was creating a new FloatArray2DSIFT(param) for each thread.
I tried also creating the FloatArray2DSIFT(param) inside the loop but the problem remained.

Thomas

Stephan Saalfeld

unread,
Sep 30, 2015, 9:47:02 PM9/30/15
to Thomas, Fiji-devel
Hi Thomas,

please also clone the param object:

floatSIFT = FloatArray2DSIFT(param.clone())

...

depending on the parameters used, the parameters can be non-thread-safe.
Bad design from long time ago.

Sorry,
Stephan
> --
> --
> Please avoid top-posting, and please make sure to reply-to-all!
>
> Mailing list web interface: http://groups.google.com/group/fiji-devel
>
> ---
> You received this message because you are subscribed to the Google
> Groups "Fiji-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to fiji-devel+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


Thomas

unread,
Oct 1, 2015, 7:09:30 AM10/1/15
to Fiji-devel, thomas_...@hotmail.com
Oh yes that was it ! It is working now.
Thank you very much
Best regards
Thomas

Thomas

unread,
Oct 1, 2015, 7:18:08 AM10/1/15
to Fiji-devel, thomas_...@hotmail.com
And for the record, here is the minimalistic python script that computes in parallel the features of images contained in a folder.
Thomas

import ij, os,time
from ij import IJ

from mpicbg.ij import SIFT
from mpicbg.imagefeatures import FloatArray2DSIFT

from java.util import HashSet
from java.lang import Thread
from java.util.concurrent.atomic import AtomicInteger
from java.lang import Runtime

path = os.path.normpath(xxx)

paths = [ os.path.join(path,name) for name  in filter(lambda x: os.path.splitext(x)[1] == '.tif', os.listdir(path))]  # list containing the paths of the images
#print paths

nImages = len(paths)

atomicI = AtomicInteger(0)
threads = []


def getFeatures():
pLowRes = FloatArray2DSIFT.Param().clone()
pLowRes.fdSize = 8
pLowRes.initialSigma = 0.5
while atomicI.get() < (nImages - 1):
k = atomicI.getAndIncrement()
if k < nImages:
floatSIFT = FloatArray2DSIFT(pLowRes)
ijSIFTLowRes = SIFT(floatSIFT)
imp = IJ.openImage(paths[k])
ip = imp.getProcessor()
features = HashSet()
ijSIFTLowRes.extractFeatures(ip, features)
IJ.log( str(k) + ': ' + str(features.size()) + ' features extracted' )
imp.close()
del features

# Creating and starting the threads
for p in range(int (Runtime.getRuntime().availableProcessors() * 0.9 )):
#for p in range(1):
thread = Thread(getFeatures)
threads.append(thread)
thread.start()
#time.sleep(5)
IJ.log('Thread ' + str(p) + ' started')

# Joining the threads
for thread in threads:
thread.join()
IJ.log('Thread joined')

IJ.log('Computing features done')

Reply all
Reply to author
Forward
0 new messages