Username Remember Me?
Password   forgot password?
   
 
1 of 2
1
Spectral Angle Mapper (SAM) using hypertools
Posted: 13 June 2009 12:52 PM   [ Ignore ]  
Novice
Rank
Total Posts:  9
Joined  2009-06-13

Hello everyone. I am currently trying to classify an hyperspectral Image (HYMAP) using a spectral angle mapper classifier. Im having trouble on this and need urgent help.

I have an Hymap image called: HYMAP_SCENE

>> size(HYMAP_SCENE)

ans =

200 200 126

In this image, I define training sites for ten classes (1 to 10). I take the training pixels (100 per class) out of (HYMAP_SCENE) and put them into a training data matrix hym_t:

>> size(hym_t)

ans =
1000 126

furthermore I have a training label vectot train_l (size 1000,1) with the class labels.

from this, Im building a dataset, to train the spectral angle mapper:

>> hym_dv = dataset(hym_t,train_l)
>> A = samc(hym_dv)

First question: is this the right way to do it? And furthermore: What do I have to to, to get a spectral angle classification of the whole scene (that means of: HYMAP_SCENE)? I need a classification result of the size (200x200x1) which contains the class labels (1 to ten).

Please help me, I need this classification for my diploma thesis and I have got one week left :-)

[ Edited: 09 May 2010 11:10 AM by pavel]
Profile
 
 
Posted: 13 June 2009 02:37 PM   [ Ignore ]   [ # 1 ]  
Administrator
Avatar
RankRankRankRank
Total Posts:  355
Joined  2008-04-26

Hi Andy,

yes you set up the database and trained classifier in the right way :-)

You can use im2feat PRTools function to create a dataset from your entire image. Here example on a small hyperspectral image:

>> size(I) % image cube 33x40 pixels with 240 spectral bands
ans 
=
    
33    40   240

>> a=im2feat(I)
1320 by 240 dataset with 0 classes[]

the dataset preserves the original image size:
>> 
a.objsize
ans 
=
    
33    40

lets train a SAM classifier:
>> 
proto set of manually-labeled prototype spectra
30 by 240 dataset with 5 classes
[7  9  8  3  3]
>> w=samc(proto)
Spectral Angle Mapper classifier240 to 5 trained  mapping   --> samc

execute the SAM classifier on the complete image a:
>> 
out=a*w
1320 by 5 dataset with 0 classes
[]

five output features representes our five classes

lets get decisions at default operating point using nlabeld:
>> 
dec=out*nlabeld;

decisions are numerical indices in the dataset lablist
>> class(dec)
ans =
double
>> size(dec)
ans =
        
1320           1

visualize the decisions as image:
>> 
figureimagesc(reshape(dec,a.objsize))

Hope it helps,

Pavel

P.S.: Good luck with your thesis :-)

Image Attachments
Picture 2.png
Profile
 
 
Posted: 13 June 2009 02:43 PM   [ Ignore ]   [ # 2 ]  
Novice
Rank
Total Posts:  9
Joined  2009-06-13

Hi Pavel, thanks a lot, yes it helped :-) in the meanwhile I found out another solution which would be:

hym=im2feat(hym);
sam_train=samc(ds1);
result=classim(hym,sam_train);

Is this also valid? And could I use the same way to get a minimum distance result? I mean using:

hym=im2feat(hym);
sam_train=mindistc(ds1);
result=classim(hym,sam_train);

Cheers ;-)

Profile
 
 
Posted: 13 June 2009 02:58 PM   [ Ignore ]   [ # 3 ]  
Administrator
Avatar
RankRankRankRank
Total Posts:  355
Joined  2008-04-26

yes. This should work as well.

If, using mindistc, you encounter an error complaining about “Cell elements must be character arrays.” you’ll need to replace
w.lablist on line 94 in mindistc.m by getlablist(w).

Pavel

Profile
 
 
Posted: 13 June 2009 04:09 PM   [ Ignore ]   [ # 4 ]  
Novice
Rank
Total Posts:  9
Joined  2009-06-13

Hi Pavel,

unfortunately, it doesn’t work: Im receiving the error message:

??? Error using ==> isfeatim at 28

---- Dataset with feature images expected -----

Error in ==> classim at 56
isfeatim(a);

Error in ==> fastsam at 49
result=classim(hym,sam_train)

(fastsam is a small m-file I wrote which simply helps me to select the image).

hym ist a dataset made from the image AA

hym=im2feat(AA);

Its kind of strange. When calling it with

sam_train=samc(ds1);

it perfectly works, when calling it with

sam_train=mindistc(ds1);

it doesn’t. Do you have any ideas?

Cheers

Profile
 
 
Posted: 13 June 2009 04:16 PM   [ Ignore ]   [ # 5 ]  
Administrator
Avatar
RankRankRankRank
Total Posts:  355
Joined  2008-04-26

Hi Andy,

looks like mindistc does not properly set the image size in the resulting dataset. Try to set it manually by typing out.objsize=hym.objsize
where out is the dataset returned when applying sam_train to your image dataset.

You can also patch mindistc.m routine by adding

w.objsize=a.objsize;

on line 97, just before the end

Does it help?

Pavel

Profile
 
 
Posted: 13 June 2009 04:34 PM   [ Ignore ]   [ # 6 ]  
Novice
Rank
Total Posts:  9
Joined  2009-06-13

Hello Pavel,

well, it does. But unfortunatly, result only contains labels for class 1:

>> unique(result)

ans =

1

meaning that the entire image is of the same color. I tried so on a RGB image, defining seven classes which a quite easy to distinguish.

Am I still doing anything wrong?

Profile
 
 
Posted: 13 June 2009 04:55 PM   [ Ignore ]   [ # 7 ]  
Administrator
Avatar
RankRankRankRank
Total Posts:  355
Joined  2008-04-26

Can you run getlab(sam_train) to validate that you really have multiple classes in the classifier?

Are samc and mindistc both returning only decision 1?

Pavel

Profile
 
 
Posted: 13 June 2009 05:05 PM   [ Ignore ]   [ # 8 ]  
Novice
Rank
Total Posts:  9
Joined  2009-06-13

Hello Pavel,

No matter whether I use samc or mindistc, getlab returns:
>> getlab(sam_train)

ans =

1
2
3
4
5
6
7
so it seems to be defined correctly. Do you have any other idea what could be the problem?

Thank you so much for helping

Profile
 
 
Posted: 13 June 2009 05:12 PM   [ Ignore ]   [ # 9 ]  
Administrator
Avatar
RankRankRankRank
Total Posts:  355
Joined  2008-04-26

Then I’d look at classifier outputs. The decision is just an index of column with maximum per-class output. Check-out what comes out of the classifier:

>> w2=samc(proto)
Spectral Angle Mapper classifier240 to 5 trained  mapping   --> samc
>> out2=a*w2
1320 by 5 dataset with 0 classes
[]
>> +out2(1:10,:)
ans =
    
1.4286    1.5177    1.3748    1.4297    1.3994
    1.4163    1.5304    1.3617    1.4222    1.3953
    1.4110    1.5366    1.3552    1.4181    1.3927
    1.4052    1.5411    1.3484    1.4148    1.3907
    1.4018    1.5435    1.3439    1.4130    1.3895
    1.3993    1.5446    1.3414    1.4105    1.3879

Profile
 
 
Posted: 13 June 2009 05:31 PM   [ Ignore ]   [ # 10 ]  
Novice
Rank
Total Posts:  9
Joined  2009-06-13

Hi Pavel, hhhm, doing the same thing like you proposed returns:
>> out2=hym*sam_train
53109 by 7 dataset with 0 classes: []
>> out2(1:10,:)
10 by 7 dataset with 0 classes: []

in my case. Im sure theres got to be something wrong with that, but I have no idea what it could be. Do you ? :-)

Profile
 
 
Posted: 13 June 2009 05:37 PM   [ Ignore ]   [ # 11 ]  
Administrator
Avatar
RankRankRankRank
Total Posts:  355
Joined  2008-04-26

you should include the unary plus operator before the out dataset to get the numbers out:

>> +out(1:10,:)

The same can be made using:

>> double(out(1:10,:))

Profile
 
 
Posted: 13 June 2009 05:44 PM   [ Ignore ]   [ # 12 ]  
Novice
Rank
Total Posts:  9
Joined  2009-06-13

Yes, of course, I forgot. samc returns
>> +out2(1:10,:)

ans =

1.2368 1.2263 1.3103 0.4405 1.3887 1.2110 1.2285
1.3169 1.4146 1.5165 0.6636 1.4220 1.2174 1.3357
1.3057 1.4335 1.5167 0.6951 1.3982 1.1992 1.3394
1.3016 1.4375 1.5209 0.6924 1.4015 1.1955 1.3438
1.2930 1.4422 1.4988 0.7214 1.3745 1.1822 1.3373
1.2917 1.4345 1.5391 0.6487 1.4431 1.1940 1.3611
1.1769 1.1676 1.2445 0.3698 1.3375 1.1667 1.1857
0.9195 0.6431 0.7430 0.1524 0.7910 1.0253 0.6298
0.9544 0.6978 0.7961 0.1636 0.8494 1.0541 0.6889
1.3164 1.0484 1.1522 0.4795 1.1697 1.3815 1.0103

while mindistc returns:
>> +out2(1:10,:)

ans =

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

does that say anything to you? I cant see a reason why this yould happen.

Profile
 
 
Posted: 13 June 2009 06:15 PM   [ Ignore ]   [ # 13 ]  
Administrator
Avatar
RankRankRankRank
Total Posts:  355
Joined  2008-04-26

I don’t see any reason why *all* mindistc output would be zero (if you have different prototypes).
However, in your code above, I can see you’re training both samc and mindistc on the same dataset called ds1. This could suggest a problem because samc is trained in the spectral feature-space but mindistc on the dissimilarity representation.
Here is an example:

>> a1 original dataset with 5 classes
1320 by 240 dataset with 5 classes
[372  360  258  161  169]

>> b=gendat(a1,[4 4 4 4 4]) % subset we use
20 by 240 dataset with 5 classes[4  4  4  4  4]

first training and executing SAM:
>> 
w2=samc(b)
Spectral Angle Mapper classifier240 to 5 trained  mapping   --> samc
>> out2=b*w2
20 by 5 dataset with 5 classes
[4  4  4  4  4]
>> +out
ans 
=
         
0   -0.1389   -0.1079   -0.0853   -0.1266
         0   
-0.1410   -0.1204   -0.0828   -0.1272
         0   
-0.1168   -0.0874   -0.0850   -0.1188
         0   
-0.1415   -0.0285   -0.1501   -0.1681
   
-0.1188         0   -0.1569   -0.1187   -0.1322
   
-0.1371         0   -0.1810   -0.1265   -0.1418
   
-0.1262         0   -0.1610   -0.1302   -0.1406
...

I first train a dissimilarity mapping (using distance measure defined in dsam.m)
we train it using all samples in b as prototypes:
>> 
w=b*dissimm('dsam')
Dissimilarity mapping 'dsam'240 to 20 trained  mapping   --> dissimm

now we compute distances to all samples in b:
>> 
D=b*w
20 by 20 dataset with 5 classes
[4  4  4  4  4]

part of the distance matrixnote zeros where we compare prototype to itself
>> +D(1:7,1:7)
ans =
         
0    0.0260    0.0399    0.1102    0.1429    0.1554    0.1508
    0.0260         0    0.0495    0.1215    0.1461    0.1564    0.1542
    0.0399    0.0495         0    0.0840    0.1188    0.1371    0.1262
    0.1102    0.1215    0.0840         0    0.1415    0.1681    0.1450
    0.1429    0.1461    0.1188    0.1415         0    0.0589    0.0235
    0.1554    0.1564    0.1371    0.1681    0.0589         0    0.0611
    0.1508    0.1542    0.1262    0.1450    0.0235    0.0611         0

only on this dissimilarity representationwe train mindistc classifier:
not it mapps distances from 20D input (dissimilarity representationto 5 class outputs:
>> 
wd=mindistc(D)
Minimum distance classifier20 to 5 trained  mapping   --> mindistc

output of the minimum distance classifier:
>> 
out=D*wd
20 by 5 dataset with 5 classes
[4  4  4  4  4]

now the columns represent classes:
>> +
out(1:7,:)
ans =
         
0   -0.1389   -0.1079   -0.0853   -0.1266
         0   
-0.1410   -0.1204   -0.0828   -0.1272
         0   
-0.1168   -0.0874   -0.0850   -0.1188
         0   
-0.1415   -0.0285   -0.1501   -0.1681
   
-0.1188         0   -0.1569   -0.1187   -0.1322
   
-0.1371         0   -0.1810   -0.1265   -0.1418
   
-0.1262         0   -0.1610   -0.1302   -0.1406

Hope it helps,

Pavel

Profile
 
 
Posted: 14 June 2009 09:18 AM   [ Ignore ]   [ # 14 ]  
Novice
Rank
Total Posts:  9
Joined  2009-06-13

Hi Pavel, so far, it worked thanks a lot! What I did was:

a1=dataset(tdv,tlv);

tdv ist a matirx with the training instances, tlv contains the labels for seven classes

b=gendat(a1,[4 4 4 4 4 4 4]); Do I have to subset the data,or can I train on the entire set?

w=b*dissimm(’dsam’);
D=b*w;

wd=mindistc(D);
out=D*wd;

What I am still unable to achieve ist to classify the entire image. tdv are the training instances. The entire image is:

IMG=imread(’entire_image.png’);

I get the following error messages:

result=classim(IMG,wd);
??? Error using ==> map at 325
Data type not supported

Error in ==> C:\Users\Andy@Work\Downloads\prtools\@mapping\mtimes.p>mtimes at 15

Error in ==> classim at 52
a = a*w;

I also tried:

BB=im2feat(IMG);
>> result=classim(BB,wd);
??? Error using ==> setfeatsize at 35

The total feature size does not fit with the real number of features.
This might be caused when mappings are applied to datafiles with objects of different
size.

Error in ==> map at 265
a = setfeatsize(a,fsize); % needed to set object images, sometimes

Error in ==> C:\Users\Andy@Work\Downloads\prtools\@mapping\mtimes.p>mtimes at 15

Error in ==> classim at 52
a = a*w;

I must be doing anything wrong!

Profile
 
 
Posted: 14 June 2009 09:46 AM   [ Ignore ]   [ # 15 ]  
Administrator
Avatar
RankRankRankRank
Total Posts:  355
Joined  2008-04-26

yes. I think that the key step missing for the entire image is to move from the spectral feature representation (dataset BB) to the dissimilarity representation and only then apply the mindistc classifier wd:

>> D=BB*w
>> out=D*wd
>> dec=nout*labeld;

Pavel

Profile
 
 
   
1 of 2
1