-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpiinup.m
1433 lines (1317 loc) · 91.3 KB
/
piinup.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Narwhal matching program: uses the location of features of the notchess
% found on the dorsal ridge of the narwhals to identify the individuals.
%
% Author: Marie Auger-Methe & Hal Whitehead
% Date: July 2009
% Please cite: Auger-Methe, M. M. Marcoux, H. Whitehead (2011). Computer-assisted photo-identification of narwhals. Arctic 64:342-352
%
% This program is based on the matching program that Hal Whitehead wrote to
% help the identification of sperm whales. See Whitehead (1990) Computer
% assisted individual identification of sperm whale flukes. Report of the
% International Whaling Commission (Special Issue 12): 71-77
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function piinup
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function piinup is the function to be called in
% the command window omatchf MATLAB to start the matching program. It creates
% 'Figure 1: Main control' which asks the information regarding the location
% of the pictures and databases, and other basic info. Piinup
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
infopl='infopl.txt';% place where info is stored
infoname={'Catalog table','Catalog database','Match table','Match database','New Id #''s greater (Yes/No)?','Areas (separate with commas)','Match area # (which of below?)','Number of potential matches','Location of pictures'}; %Description of the different option. The last description appears on top.
infovar={'cdbtable','cdb','dbtable','dbs','startnum','catname','dcat','noval','picloc'}; % contains the tags/name of these variable
% cdbtable --> catalog table (Catalogtable)
% cdb --> catalog db(Narwhalcatalog)
% dbtable --> match table (KB_2006)
% dbs --> match db (KBnarwhals)
% startnum --> New id numbers greater (Yes)
% catname --> area (Koluktoo Bay)
% dcat --> area # from which the match are (1)
% noval --> number of potential matches (60)
% picloc --> location of picture (C:\Documents and Settings\Marie\My Documents\Narwhals\PhotoId\)
infodef={'Catalogtable','Catalog','KB_2006','Photos','Yes','Koluktoo Bay','1','1','C:\Documents and Settings\Marie\My Documents\NarwhalPhotoId\Catalogue'}; %default values
infotype=[2 1 2 1 2 6 3 3 5];%type of variable: 1 = database; 2 = string; 3 = number; 4 = file; 5 = path; 6 = set of strings
% Deals with the information saved in the infopl.txt file which has the
% info entered last time in figure 1.: Main control was open
fid=fopen(infopl,'r'); %fid = fopen(FILENAME, PERMISSION) opens the file infopl (which has the info peiously stored) for read access. PERMISSION can be: 'r' --> read, 'r+' read and write, ...
if fid>0
for j=1:length(infoname)
infod=fgetl(fid); % tline = fgtel(fid) returns the next line of a file associated with file idetifier fid as a MATLAB string
[uv,uq]=strtok(infod,',');
var=find(strcmp(uv,infovar));
if ~isempty(var)
uq=uq(2:end);
if infotype(var)==3;% Deals with variables that are numbers (i.e.: 'Match area # (which of below?)','Number of potential matches')
uq=str2num(uq);
end
infodef{var}=uq;
end
end
fclose(fid);
end
logintimeout(25);
tfig=0.1;%no info. fig.
umaino=figure; % open the 1st figure
topval=40*length(infoname)+30;
set(umaino,'Position',[200 200 600 topval],'Menubar','none','Name', 'Main control');
umaint=uicontrol(umaino,'Style','text','position',[130 topval-50 360 30],'string','RIDGE MATCHING: MAIN CONTROLS','fontsize',15);
for j=1:length(infoname)
utct(j)=uicontrol(umaino,'Style','text','tag',['t' infovar{j}],'position',[20 20+30*(j-1) 180 20],'string',[infoname{j} ':']);
utc(j)=uicontrol(umaino,'Style','edit','tag',infovar{j},'position',[220 20+30*(j-1) 320 20],'string',infodef{j});
if (infotype(j)==4)|(infotype(j)==5)
ufst(j)=uicontrol(umaino,'Style','pushbutton','tag',['q' infovar{j}],'position',[550 20+30*(j-1) 30 20],'string','...','callback',{@getpl,infotype(j)});
end
end
umaingo=uicontrol(umaino,'Style','pushbutton','position',[500 topval-50 80 30],'string','OK','callback',{@flukeprsetup,infopl,infovar,infotype},'fontsize',15);
umainstop=uicontrol(umaino,'Style','pushbutton','position',[20 topval-50 80 30],'string','Quit','callback','close(gcf);','fontsize',15);
function getpl(obj,eventdata,infot)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function getpl gets the file path using a second window when you
% use the push button '...' It gets called in 'Figure 1: Main control' when
% the user chooses the location for the photographs.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
taggdat=get(obj,'tag');
taggdat=taggdat(2:end);
ufl=findobj('tag',taggdat);
uflt=findobj('tag',['t' taggdat]);
targstr=get(uflt,'string');
if infot==5;pn=[targstr '*.*'];end
[fn,pn]=uigetfile('*.*',targstr,get(ufl,'string'));
if infot==4;pn=[pn fn];end
set(ufl,'string',pn)
function flukeprsetup(obj,eventdata,infopl,infovar,infotype)
global proce vv dd ddu numwig minMPnum noot num sizecat urtt xlt catqual cataside picloc fgc noval startnum fileToBeM qualPicTBM fg dcat connd cdbtable conn dbtable catname compQVal % needs to include all of the variables save in infopl.txt file which will be used in other functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function flukeprsetup gets the information from the catalogue table of
% the MS access db and place it in a matrix called fgc. It also gets the
% info for the individual that will be processed from the matching table of
% the MS access db and place it the matrix fg.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% the following set of lines gets the info from the textfile infopl.txt
fid=fopen(infopl,'w');
for j=1:length(infovar)
uu=get(findobj('tag',infovar{j}),'string');
fprintf(fid,'%s,%s\n',infovar{j},uu);
switch infotype(j)
case 3
eval([infovar{j} '=' uu ';']);
case 6
q=0;
while 1
q=q+1;
[ak{q},uu]=strtok(uu,',');
if isempty(uu);break;end
end
eval([infovar{j} '=strvcat(ak);']);
otherwise
eval([infovar{j} '=''' uu ''';']);
end
end
% Set of variables that have been optimized for the program
vv=[1 0 0; 0 1 0; 0 0 0;]; % the value of two MPs compared: up deep
% In this version you can only compare up with up and deep with
% deep. But you could change this vv=[1 0.5 0; 0.5 1 0; 0 0 0;]; would give
% compare up with deep and give a match between the two half the value than
% for a match between two ups or two deeps MPs. If you want to do such a
% change you need to change also the dd matrix.
ddu=0.04; % size of extra bit added when using the wiggles. This helps to
% account for the misplacement of the ends of the ridge by the user (in the
% version that uses the ends of the ridge) or the possible addition of a
% mark point with time or missing of a point by the user (in the version
% that does not use the ends of the ridge). This value (0.04) should be
% about the average distance between 2 MP for now it's the old optimize ddu
% value from the original piinup (inputridge) program.
dd=[0.003 0 0; 0 0.002 0; 0 0 0;]; % sd of the normal distribution used to
% calculate the probability that two MPs are same. This helps account for
% the errors in the location of the MPS and of the ridge ends.
numwig=1; % number of wiggle used. numwig=1 will result 9 possible
% placements of the ends see fig. 3.3 (Auger-Methe 2008).
minMPnum=9; % minimum number of MPs a photo needs to be adequate for
% matching. This minimum number is based on the minimun 3 deep MPs but is
% now more for the benefit of the program than a limitation for the
% distinctiveness of the ridge. 9 MPs allow the comparison of photographs
% using the matching routine that does not use the ends of the ridge to
% compare two photographs that have visible limits and use the wiggles.
compQVal=[1 1 1]; % value to which lujnddu luknddu is multiply depending on
% the quality of the photos compared for quality [3 4 5]. Since changing
% these values did not significantly increase the matching efficiency, we
% left them as 1. But this is something that could be investigated more.
fclose(fid);
close(gcf);
% Gets the data found in the catalog and place it in a matrix called fgc
% and then form the matrices urtt and xlt which contains the MP information
% of the catalogue.
connd = database(cdb,'','');%input catalog database (Narwhalcatalog)
cursc=exec(connd,['SELECT * from ' cdbtable]); %select all columns from the catalog table (Catalogtable) in connd, the catalog database (Narwhalscatalog)
cursc=fetch(cursc); % fetch data and import data into MATLAB cell array. Import data from the catalog table into an array called cursc
fgc=cursc.Data; % that actually makes a matrix(?) fgc that has the data from the catalog table
sizecat=size(fgc);
sizecat=sizecat(1); % gets the number of rows in the catalogue table
num=zeros(10000,1); %does it put a limit of 10000?
% converts to variables
for i=1:sizecat %For all rows of the catalog table
noot(i)=fgc{i,2};%IDN ()
num(noot(i))=i;
urtt{i}=str2num(fgc{i,3}); % urtt has the Marpoints type information found in the 3rd column of the catalog table (Maktype)
xlt{i}=str2num(fgc{i,4}); % xlt has the Markpoints position information found in the 4th column of the catalog table (Markpos)
catqual{i}=fgc{i,11}; % gets the quality of the photos from the catalogue found in the 11th column of the catalog table (Quality)
cataside{i}=fgc{i,12}; % gets the side of the narwhal in the photograph
end
proce=1; % proceed down the list
% These lines (including the loop) are use to go get the data in the match
% table and place it in a matrix called fg one row at the time. fg only has
% the information found in one of the rows of the match table.
conn = database(dbs,'','');%input match database (KBnarwhals)
%curs=exec(conn,['SELECT * from ' dbtable ]); % Original!! cursor = exec(connect, SQLquerry). It selects all columns from the match table in conn, the match database
curs=exec(conn,['SELECT * from ' dbtable ' ORDER BY ' dbtable '.Encounter']);% Changed so it uses the random numbers I entered, in the final program should change so it with dat time?
while proce
curs=fetch(curs,1); % Fetch data and import data into MATLAB cell array, it returns only 1 row
fg=curs.Data; % Puts the data of one row in fg
while isempty(strmatch(fg{1},'No Data')) && (~strcmp(fg{9},'null') || fg{7}== 0) % if you are not at the end of the table (isempty(strmatch(fg{1},'No Data'))) and the row already has an IDN (~strcmp(fg{9},'null')) or it's not the best photo for that individual (fg{7} == 0), skip the row
curs=fetch(curs,1); % Fetch data and import data into MATLAB cell array, it returns only 1 row
fg=curs.Data; % Puts the data of one row in fg
end
% Display a message box saying 'End of file' if the table is empty or
% if there is no more rows of the match table to go through.
if strmatch(fg{1},'No Data');
uiwait(msgbox('All of the ID have been assigned to this match table. The program only consider ridges for which the BestEncPhoto column contains a 1 and IDN column is empty.','End of file','modal'));
break;
end
fileToBeM=fg{1}; % fileToBeM is the information from the 1st column of match table (e.g.: KC072501.JPG). It's the picture you want to match
qualPicTBM=fg{5}; % quality of the picture to be matched
% to make sure that the location of the picture has a final '\', if not it
% cannot find the picture
if isempty(strmatch(picloc(length(picloc)), '\'));
picloc = [picloc '\'];
end
ifile=[picloc fileToBeM];
if exist(ifile)
umain=figure; % open the 2nd figure: File processed (the one that gives you the name of the file you could process)
qqq=0;
set(umain,'Position',[600 60 400 100],'Menubar','none','tag','umain','Name','File processed');
umaingo=uicontrol(umain,'Style','pushbutton','position',[275 60 100 30],'string','PROCESS','callback',{@processfluke,ifile},'fontsize',15);
umainquit=uicontrol(umain,'Style','pushbutton','position',[160 60 60 30],'string','QUIT','callback',{@quitfig1},'fontsize',15);
umainno=uicontrol(umain,'Style','pushbutton','position',[25 60 70 30],'string','SKIP','callback','close(gcf);','fontsize',15);
ufitt=uicontrol(umain,'Style','text','position',[10 10 380 40],'string',ifile);
uiwait(umain) %wait the figure umain figure is close
else
umain=msgbox(['No image for ' ifile]);
pq=get(umain,'Position');
set(umain,'Position',[520 60 pq(3:4)]);
uiwait(umain);
end
end
close(curs)
close(cursc)
close all
clear all
function quitfig1(obj,event)
global proce
proce=0;
close all;
function processfluke(obj,eventdata,ifile)
global xq numshown ife fg
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function processfluke opens 'Figure 2: Ridge to be matched' which allows
% you to crop the photograph before starting to enter the MPs.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
numshown=1;%number photographs shown
hr=figure; % open 3rd figure which has the ridge you want to match. This figure gives you the option of cropping, ...
set(gcf,'Name','Ridge to be matched','tag','primef');
[dum,ftype]=strtok(ifile,'.');
x=imread(ifile,ftype(2:end));
qq=image(x); % Truecolor image since m-by-n-by-3, changing colormap should not have effect on the colored displayed
axis equal; %sets the aspect ratio so that the data units are the same in every direction; so image not stuck in a square
axis tight;showaxes('off');
set(gcf,'Position',[10 380 1005 360],'Menubar','none');
set(gca,'Position',[0 0 1 1]); %change the position of the picture in the window (gca: get current axes handle)
hs(numshown)=hr;
xq{numshown}=x;
% displays the position of the whale if there is more than 1 individual in
% the photo
if ~strcmp(fg{2},'Null')
uposition=uicontrol(hs(numshown),'Style','text','fontsize',10, ...
'position',[0 343 180 17],'string',...
['Whale position in photo: ' fg{2}]);
end
% push buttons of the first figure with the narwhal photo
umarkin=uicontrol(hs(numshown),'String','GO','tag','ggo','Position',[960 15 40 20],...
'callback',{@markpoints,hs,numshown});
uscrop=uicontrol(hs(numshown),'String','Crop?','tag','ggo','Position',[860 15 40 20],...
'callback','ww=imcrop;qq=image(ww);axis equal;axis tight;showaxes(''off'');set(gcf,''Menubar'',''none'',''tag'',''primef'');');
function markpoints(obj,eventdata,hr,numshown)
global minMPnum sideE sideEntered
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function markpoints allows the input of the markpoints (ridge ends, up,
% down, visible limits) for the photograph from the match table that the
% user is trying to match to the catalogue. The inputed MPs are stored in
% two vectors. urttx is a list of the entered mark type (1 2 3) means: up,
% deep, visible limits. xltx stores the position of the MPs other than the
% ends using the distance from the start of the ridge till its end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
delete(findobj('tag','okn'));
delete(findobj('tag','ggo'));
delete(findobj('tag','sidePopUp'));
sideEntered=[];
% This makes the figure with the information
if isempty(findobj('tag','procinstr'))% only creates a new figure if the figure with the information is not already open
% Describe the MP and diplay the descriptions in figure called
% Instruction. Can add types of MP between R and I but should not play
% with the other types of MP (R, I, O) and don't add MP after O. If you
% add MP types you need to add to the lines below which defines marcode
% and teststring.
tit=strvcat('Put in points from front to back of the narwhal, starting with front of the ridge,',...
'input ends with end of ridge',...
'Precede each point with code',...
' R=Ridge: (front to back), if one part of the ridge is masked place the ridge mark point',...
' where you think the ridge would begin.',...
' U=Up: upper limits of deep notches, it should be the highest point next to a deep notch.',...
' If there is only one high point between 2 deep notches only insert one up mark point',...
' D=Deep: deepest point of deep notch. Deep notches are only the notches that reaches the',...
' bottom of the dorsal ridge. If it is a triangular or narrow rounded notch, place',...
' one deep mark point at the deepest point. If it is a square or wide rouded notch place',...
' two deep mark points at the deepest points of the ends of the notch.',...
' I=Visible limits: if either of the ends of the ridge is masked. Place I where the ridge disapear.',...
' Do not include in the catalogue ridges that would have more than 1 visible limit', ...
' O=Oops, undo the last point');
tfig=figure;
tt=text(0.1,0.1,tit);
axis tight;showaxes('off');
set(tt,'Fontsize',7,'Verticalalignment','bottom');
set(tfig,'Position',[20 60 500 280],'tag','procinstr','Menubar','none','Name','Instructions');%#
set(gca,'Position',[0 0 1 1]);
end
marcode=[0 1 2 3 4];%# Code for the markpoints
figure(hr);
unumt=uicontrol(hr,'Style','text','position',[20 15 330 20],'String','You cannot quit before all of the MPs are entered!'); % writes ID on the left corner
teststring='RUDIO';%# Letters that will be entered in the image when you place a MP on the picture
OK=0;
while ~OK
nummark=zeros(1,length(marcode)-1);% will serve to count the number of mark of each type; should be the length of the number of mark points (-1 since don't count the oops)
p=0;
OK=0;
delete(findobj('tag','points'));% make sure the points entered from previous photographs are deleted
clear tu xx yy typu
while nummark(1)<2 % nummark(1) counts the number of ridge points counted, when two point entered the loop stopped
k=waitforbuttonpress;
if k
cch=upper(get(gcf,'CurrentCharacter')); %get the character entered in the figure (I think)
iss=findstr(cch,teststring);% finds the position of cch (character just entered) in the teststring, so r=0, u=1,...
if ~isempty(iss)% make sure that the letter entered on the key board is from the teststring
figure(hr);
if cch == 'O' %for oops, undo the last point
nummark(typu(p)+1)=nummark(typu(p)+1)-1; % takes out the 1 from the count of each types
typu(p)=[]; % to take out the type just enterd from the list (typu)
xx(p)=[]; % take out the x-position just entered
delete(pu(p)); % delete the red dot just entered
delete(tu(p)); % delete the letter just entered
p=p-1; % reset the p, so the next value has the appropriate index
else
p=p+1;% to give a new point for each point entered
[xx(p),yy(p)]=ginput(1); %Input 1 point using the mouse, the xx is used for the position of the MP
pu(p)=line(xx(p),yy(p),'tag','points','marker','.','markerfacecolor',[1 0 0],'markeredgecolor',[1 0 0],'linestyle','none');% adds the red dot
tu(p)=text(xx(p),yy(p),cch); % sets the letter
set(tu(p),'tag','points','HorizontalAlignment','center','verticalalignment','bottom','color',[0.3 0.3 0.3]);% adds the letter
nummark(iss)=nummark(iss)+1;% this array with the counts the number of mark points of each type
typu(p)=marcode(iss);% typu for: r --> 0, u --> 1, d --> 2, i --> 3
end
end
end
end
OK=1;
if nummark(length(marcode)-1)>1 % verify if you have entered more than 1 visible limit
OK=0;
uiwait(msgbox('You cannot have more than 1 visible limit on a photo. If it is a typo re-enter the mark points. If the two ends of this photo are not visible, quit the program and remove this photo from your matching table.','ERROR','modal')); % error message
elseif sum(nummark(2:end-1))<minMPnum | sum(nummark(3))<3% verify whether you the min number of MP (9 total MPs up or deep) and a minimum of 3 deep MP
OK=0;
uiwait(msgbox(['You have entered less than ' num2str(minMPnum) ' mark points (up or deep) or less than 3 deep mark points, which is the minimum number required. If it is a typo re-enter the mark points. If this photo has not the required number of mark points, quit the program and remove this photo from your matching table.'],'ERROR','modal')); % error message
end
end
urttx=typu(find(typu)); % k = find(X) returns the indices of the array X that point to nonzero elements. If none is found, find returns an empty matrix. In this case returns the indices of the matrix that is not the ridge, since marcode of the ridge (R) is 0.
%so urttx is a list of the entered mark type (1 2 3) means: up, deep,
%visible limit
xltx=(xx(find(typu))-xx(1))/(xx(end)-xx(1)); % Gives position to the MP other than the ends using the distance from the start of the ridge till its end. The ends of the ridge are removed in the function rvalue.
% Entering the side of the narwhal
sideN=uicontrol(hr,'Style','text','tag','sidePopUp','position',[380 15 90 20],'String','Side of narwhal'); % writes ID on the left corner
sideE=uicontrol(hr,'Style', 'popup','tag','sidePopUp','String', 'Enter side|Rigth|Left','Position', [470 15 75 20],'Callback',{@enterside,hr,1});
while isempty(sideEntered) || sideEntered ==1
uiwait(hr)
end
delete(findobj('tag','sidePopUp'));
if sideEntered == 2
sideN=uicontrol(hr,'Style','text','tag','sidePopUp','position',[380 15 90 20],'String','Side of narwhal'); % writes ID on the left corner
sideE=uicontrol(hr,'Style', 'popup','tag','sidePopUp','String', 'Rigth|Left','Position', [470 15 75 20],'Callback',{@enterside,hr,2});
elseif sideEntered == 3
sideN=uicontrol(hr,'Style','text','tag','sidePopUp','position',[380 15 90 20],'String','Side of narwhal'); % writes ID on the left corner
sideE=uicontrol(hr,'Style', 'popup','tag','sidePopUp','String', 'Left|Rigth','Position', [470 15 75 20],'Callback',{@enterside,hr,3});
end
% Are the markpoints ok
okname=uicontrol(hr,'Style','text','tag','okn','position',[580 15 230 20],'String','Are you Ok with the mark points you entered?'); % writes ID on the left corner
oky=uicontrol(hr,'String','OK','tag','okn','Position',[815 15 30 20],'callback',{@startmatchloop,urttx,xltx});
okn=uicontrol(hr,'String','Not OK','tag','okn','Position',[850 15 50 20],'callback',{@markpoints,hr,numshown});
function enterside(obj,event,hr,firstpop)
global sideE sideEntered
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function enterside gets the side from the pop-up menu of 'Figure 2: Ridge
% to be matched'. 1=not entered, 2=rigth, 3=left. The variable firstpop
% allow to make sure that no errors is created by the user (e.g. cannot
% click on 'Enter side' after entering either side.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if firstpop == 1
sideEntered=get(sideE,'Value');
uiresume(hr);
elseif firstpop ==2
sideEntered=get(sideE,'Value')+1;
uiresume(hr);
else
if get(sideE,'Value')==1
sideEntered=get(sideE,'Value')+2;
else
sideEntered=get(sideE,'Value');
end
uiresume(hr);
end
function startmatchloop(obj,event,urttx,xltx,sideEntered) % you need to have obj and event as argument of a callback function
global urtt xlt vv dd ddu numwig minMPnum noval fgc picloc noot catname ptx numdisp catqual qualPicTBM compQVal sideEntered cataside
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function startmatchloop starts the match loop, get the r-values which
% represents the comparision between the ridge being matched and the ridges
% from the catalog. The loop allows the program to compare the ridge to be
% matched to all the photos of the catalogue. This function also open the
% 'Figure 4: List of potential matches' which displays the information of
% different ridges found in the catalogue. The r-value is in the second
% column and it represent the similarity value between the ridge you are
% trying to match and the ridge of the catalague.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if sideEntered==2
sidecat='R';
elseif sideEntered==3
sidecat='L';
end
sideEntered=[];
lurtt = length(urtt); % number of individuals in the catalogue
h = waitbar(0,'Please wait ...');
for k=1:lurtt
[rm(1,k)]=rvaluew(urttx,urtt{k},xltx,xlt{k},vv,dd,ddu,numwig,minMPnum,qualPicTBM,catqual{k},compQVal); %rm is the r value of the match, mmt reporesent whether the match is to a reverse photo
waitbar(k/lurtt)
end
close(h)
[rm,I]=sort(-rm);rm=-rm;% sorts the r-values comparing the photo to the catalog in decreasing order
ispicw=['Pic';' - ']; % picture available on the files of the computer to view
m=noval; % noval is the number of potential match indicated in 'Figure 1: Main control' and represent the maximum number of photograph shown in the list.
if lurtt<noval
m=lurtt;
end
for kkp=1:m % for all individuals of the catalogue (or for the number of potential matches)
ifork{kkp}=[picloc fgc{I(kkp),8}];
ispic(kkp)=exist(ifork{kkp})>0;
datell=fgc{I(kkp),7}(1:(end-2));
if ~strcmp(fgc{I(kkp),10},'Null')
position = fgc{I(kkp),10};
else
position = ' ';
end
selpos{kkp}=sprintf('%2.0f %2.4f %3.0f%1s %1s %12s %19s %12s %5s %3s',kkp,rm(kkp),noot(I(kkp)),fgc{I(kkp),12},position,fgc{I(kkp),8},datell,catname(fgc{I(kkp),6},:),fgc{I(kkp),9},ispicw(2-ispic(kkp),:));
end
ptx=length(urttx); % value of ridge = number of notches
numdisp=m; % number of photos displayed as potential match
usel=figure; % open 4th figure of the program
set(usel,'tag','usel','Position',[25 25 800 360],'Menubar','none','Name','List of potential matches');
uc=uicontrol(usel,'Style','listbox','tag','ulist','string',selpos,'position',[20 50 760 280],'Fontname','courier','callback',...
{@dopic,noot,I,ispic,ifork,I,sidecat}); % writes the list of info of the potential match, if you click on one of the photographs the function dopic which opens the appropriate photo is called
unumt=uicontrol(usel,'Style','text','position',[20 20 40 20],'String','ID='); % writes ID on the left corner
unum=uicontrol(usel,'Style','edit','tag','unum','position',[60 20 60 20],'callback',{@newnum,ispicw,sidecat}); % makes the ID box
umatch=uicontrol(usel,'Style','pushbutton','position',[140 20 60 20],'string','MATCH!','callback',{@matchrun,xltx,urttx,sidecat});
unew=uicontrol(usel,'Style','pushbutton','position',[220 20 90 20],'string','NEW WHALE!','callback',{@newwhale,xltx,urttx,sidecat});
uquit=uicontrol(usel,'Style','pushbutton','position',[330 20 60 20],'string','QUIT!','callback',@uiquit);
disp(' ');
function [r]=rvaluew(ujE,ukE,xjE,xkE,vv,dd,ddu,numwig,minMPnum,qualPicTBM,catqual,compQVal)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function rvaluew compares the photo you just entered with one of the
% photo from the catalogue. This function comes up with highest rvalue
% (similarity value) for this comparison. This function calculates the
% rvalue with both the 'with ends' and 'without ends' version and chooses
% the highest r-value. See Auger-Methe (2008) for details.
% This function is called from startmatchloop. The loop in function
% startmatchloop allows to have a rvalue for the comparison of all of the
% photos from the catalogue.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nn=0; %
ukr=ukE; % uk is urt{k} --> 1 or 2 for up or down mark points of the photo from the catalog
xkr=xkE; % xj is xlt{k} --> the proportional distance of the mark points of the photo from the catalog
mc=length(vv(1,:));%in this case mc=3, represent the value for the visible limit ends
[vvl,dum]=size(vv); %so vv1=3
vv=vv(:);
vals=diag(vv);
for s=1:2 % this allow to also match the flip side of the photograph to be matched
if s==1
xjr=xjE; % xj is xlt{j} --> the proportional distance of the mark points of the photo your are trying to match
ujr=ujE; % uj is urt{j} --> 1 or 2 for up or down mark points of the photo your are trying to match
else
xjr=1-fliplr(xjE); % flip the photograph to be matched
ujr=fliplr(ujE); % flip the photograph to be matched
ukr=ukE; % reset the original values for the photograph of the catalogue
xkr=xkE; % reset the original values for the photograph of the catalogue
end
% this is the basic idea behind the wiggle. It gets complicated when you
% are dealing with visible limit ends.
% For 1st photo of the comparison the 2 loops (i1 and i2) should give 9
% options of wiggle if numwig=1:
% |ddu*-*-*--*-*ddu|--> * represent the MP
% |ddu*-*-*--* --> i1=-1 & i2=-1 proportional length= xjr+ddu-lastMP
% |ddu*-*-*--*-* --> i1=-1 & i2= 0 proportional length= xjr+ddu
% |ddu*-*-*--*-*ddu|--> i1=-1 & i2=+1 proportional length= xjr+ddu+ddu
% *-*-*--* --> i1= 0 & i2=-1 proportional length= xjr-lastMP
% *-*-*--*-* --> i1= 0 & i2= 0 proportional length= xjr
% *-*-*--*-*ddu|--> i1= 0 & i2=+1 proportional length= xjr+ddu
% *-*--* --> i1=+1 & i2=-1 proportional length= xjr-1stMP-lastMP
% *-*--*-* --> i1=+1 & i2= 0 proportional length= xjr-1stMP
% *-*--*-*ddu|--> i1=+1 & i2=+1 proportional length= xjr-1stMP+ddu
p1=1+(ujr(1)==mc); %verifying whether the ridge of 1st photo starts with an visible limit mark point, --> p1 will be 2 if starts with an visible limit (uj(1) should be 4)
p2=1+(ujr(end)==mc); %verifying whether the ridge of 1st photo ends with an visible limit mark point, --> p2 will be 2 if ends with an visible limit (uj(end) should be 4)
p3=1+(ukr(1)==mc); %verifying whether the ridge of 2nd photo starts with an visible limit mark point, --> p3 will be 2 if starts with an visible limit (uk(1) should be 4)
p4=1+(ukr(end)==mc); %verifying whether the ridge of 2nd photo ends with an visible limit mark point, --> p4 will be 2 if endsts with an visible limit (uk(end) should be 4)
%%%%%%%%%%%%%%%%%%
% section with ends
for i1=-numwig:numwig %-1 0 1 --> for the front of the dorsal ridge
for i2=-numwig:numwig %-1 0 1 --> for the back of the dorsal ridge
xj=(xjr-i1*ddu)/(1-(i1*ddu-i2*ddu)); % adjusted proportional distance of the mark points of the photo your are trying to match
uj=ujr;
% for 2nd photo of the comparison pair
for i3=-numwig:numwig %-1 0 1
for i4=-numwig:numwig %-1 0 1
xk=(xkr-i3*ddu)/(1-(i3*ddu-i4*ddu));
uk=ukr;
% so mc=length(vv(1,:))+1;-->mc=3 so uk>=mc will find the visible limit(startI=3, endI=4)
% if reversed the start will become the end so if reversed uk=3 is the end not the start
mvj1=find(uj==mc); %finds the start of an visible limit (uj=3 for startI), 1st photo
missj=[]; % sets a missing section, which is empty be default, so section in k not visible in j
mvk1=find(uk==mc); %finds the start of an visible limit (uk=3 for startI), 2nd photo
missk=[]; % sets a missing section, which is empty be default
for i=1:length(mvj1)%deal with missing values
if p1>1
missk=find(xk<=xj(mvj1)); %finds the area of the ridge in the 2nd photo(xk) that is missing in 1st photo (xj)
else
missk=find(xk>=xj(mvj1));
end
end
for i=1:length(mvk1)
if p3>1
missj=find(xj<=xk(mvk1)); %finds the area of the ridge in the 1st photo(xj) that is missing in 1st photo (xk)
else
missj=find(xj>=xk(mvk1)); %finds the area of the ridge in the 1st photo(xj) that is missing in 1st photo (xk)
end
end
ujj=uj;
ujj(missj)=[]; %gives an null value to all the mark points in the 1st photo that are in an visible limit area in the 2nd photo
xjj=xj;
xjj(missj)=[]; %gives an null value to all the distances of the mark points in the 1st photo that are in an visible limit area in the 2nd photo
ukk=uk;
ukk(missk)=[]; %gives an null value to all the mark points in the 2nd photo that are in an visible limit area in the 1st photo
xkk=xk;
xkk(missk)=[]; %gives an null value to all the distances of the mark points in the 2nd photo that are in an visible limit area in the 1st photo
% removes visible limit ends from the ridge that still have
% them some might have been removed if both ridge had an
% visible limit end
xjj(find(ujj==mc))=[];
ujj(find(ujj==mc))=[];
xkk(find(ukk==mc))=[];
ukk(find(ukk==mc))=[];
luj=length(ujj); %the length has been decreased by the number of missing points (missj)
luk=length(ukk); %the length has been decreased by the number of missing points (missj)
co1=ones(luj,1)*ukk; % makes a matrix with luj numbers of row, each row has the ukk data (markpoint type)
co2=(ones(luk,1)*ujj)'; % makes a matrix with luk number of columns, each column has ujj data (markpoint type)
vvp=vv(co1(:)+vvl*(co2(:)-1)); % so vv is a column with the values of matching two mark points u to u -->1, u to d--> 0, d to s--> 0,5; vv1=3
vvp=reshape(vvp,luj,luk); % makes a matrix with 1 if the mark points in both photos have the same mark point category (up or down)
ddp=dd(co1(:)+vvl*(co2(:)-1));
ddp=reshape(ddp,luj,luk);
rmat=vvp.*exp(-((ones(luj,1)*xkk-(ones(luk,1)*xjj)').^2)./(2*((0.001+ddp).^2))); % for each of the mark points of the same type compares the position and gives a r value that represent whether they error distribution overlap
if luk>luj;rmat=rmat';end
rr=sum(max(rmat))/(((luj*compQVal(catqual-2))+ (luk*compQVal(qualPicTBM-2)))/(compQVal(catqual-2)+compQVal(qualPicTBM-2))); % adds all of the maximum r value for each possible combination and divides it by the greatest number of mark point and divide it so by the number of MP from the the ridge with the highest does count the extra bits as MP
nn=nn+1;
rq(nn)=rr;
end
end
end
end
%%%%%%%%%%%%%%%
% This whole following section of 100s of line is the no ends program!
% this section removes the ends of the ridges compared
xjr=(xjr-xjr(1))/(xjr(end)-xjr(1));% distance from the first point to last point proportional to the distance from the first to last point exclude the ends of ridge
xkr=(xkr-xkr(1))/(xkr(end)-xkr(1));% distance from the first point to last point proportional to the distance from the first to last point exclude the ends of ridge
if (p1+p2+p3+p4)==4 % for no visible limit
for i=1:numwig
xjrt=[(-ddu*i) xjr (1+ddu*i)]; % adding the extra ends (ddu), 1st photo
xkrt=[(-ddu*i) xkr (1+ddu*i)]; % adding the extra ends (ddu), 2nd photo
ujrt=[mc ujr mc]; % adding points for the extra bits they have the same value as visible limit ends, 1st photo
ukrt=[mc ukr mc]; % adding points for the extra bits they have the same value as visible limit ends, 2nd photo
end
for i1=1:numwig*2+1 % for 1st photo of the comparison pair
for i2=1:numwig*2+1
xj=(xjrt(i1:end-i2+1)-xjrt(i1))/(xjrt(end-i2+1)-xjrt(i1));
uj=(ujrt(i1:end-i2+1));
for i3=1:numwig*2+1 % for 2nd photo of the comparison pair
for i4=1:numwig*2+1
xk=(xkrt(i3:end-i4+1)-xkrt(i3))/(xkrt(end-i4+1)-xkrt(i3));
uk=(ukrt(i3:end-i4+1));
luj=length(uj);
luk=length(uk);
lujnddu=length(find(uj<4)); % counts the number of MP used without counting the extra bits
luknddu=length(find(uk<4)); % counts the number of MP used without counting the extra bits
co1=ones(luj,1)*uk; % makes a matrix with luj numbers of row, each row has the ukk data (markpoint type)
co2=(ones(luk,1)*uj)'; % makes a matrix with luk number of columns, each column has ujj data (markpoint type)
vvp=vv(co1(:)+vvl*(co2(:)-1)); % so vv is a column with the values of matching two mark points u to u -->1, u to d--> 0, d to s--> 0.5; vv1=3
vvp=reshape(vvp,luj,luk); % makes a matrix with 1 if the mark points in both photos have the same mark point category (up or down)
ddp=dd(co1(:)+vvl*(co2(:)-1));
ddp=reshape(ddp,luj,luk);
rmat=vvp.*exp(-((ones(luj,1)*xk-(ones(luk,1)*xj)').^2)./(2*((0.001+ddp).^2))); % for each of the mark points of the same type compares the position and gives a r value that represent whether they error distribution overlap
if luk>luj
rmat=rmat';
end
rr=sum(max(rmat))/(((lujnddu*compQVal(catqual-2))+ (luknddu*compQVal(qualPicTBM-2)))/(compQVal(catqual-2)+compQVal(qualPicTBM-2))); % adds all of the maximum r value for each possible combination and divides it by the greatest number of mark point and divide it so by the number of MP from the the ridge with the highest does count the extra bits as MP
nn=nn+1;
rq(nn)=rr;
end
end
end
end
elseif (p1==2 & p2==1 & p3==1 & p4==1) || (p1==1 & p2==2 & p3==1 & p4==1) % if (the 1st ridge starts with an visible limit) OR (the 1st ridge ends with an visible limit)
if (length(ujr)-1)<=(length(ukr)+2*numwig) % only do the comparison if the ridge with the visible limit end (the 1st ridge) has at the maximum the same ammount of MP than the second ridge + 2x the amount of wiggle
numMPxjexI=length(xjr)-1; % number of MP from the original 1st ridge before adding the extra bits(ddu) it does not include the visible limit MP
% this removes the visible limit ends and flip both ridge if the
% visible limit end is at the end of the ridge (p2=2)
if p1==2 % if the 1st ridge start with an visible limit
xjrt=(xjr(2:end)-xjr(2))/(xjr(end)-xjr(2)); % remove the visible limit point
ujrt=ujr(2:end); % remove the visible limit point
xjrt=1-fliplr(xjrt);
ujrt=fliplr(ujrt);
xkrt=1-fliplr(xkr); % for no reverse flip since the xjr is flipped
ukrt=fliplr(ukr);
elseif p2==2 % if the 1st ridge ends with an visible limit
xjrt=(xjr(1:(end-1))-xjr(1))/(xjr(end-1)-xjr(1)); % remove the visible limit point
ujrt=ujr(1:(end-1)); % remove the visible limit point
xkrt=xkr; % for no reverse since xjr in this case in not flipped
ukrt=ukr;
end
% dealing with the wiggles of the ridge WITH the visible limit end
for i=1:numwig % just adding the normal ddu wiggles like for when there is no visible limit for the 1st photo
xjrt=[(-ddu*i) xjrt (1+ddu*i)]; % adding the extra ends (ddu), 1st photo
ujrt=[mc ujrt mc]; % adding points for the extra bits they have the same value as visible limit ends, 1st photo
end
% dealing with wiggles of the ridge WITHOUT the visible limit end
if length(xkrt)>=(numMPxjexI+numwig) % If the 2nd photo has at least the the same amount of MP than the number MP of the photo with visible limit + 2x the amount numwig
xkrt=(xkrt(1:(numMPxjexI+numwig))-xkrt(1))/(xkrt(numMPxjexI+numwig)-xkrt(1)); % using the MPs of the ridge as wiggle for the appropriate side
ukrt=ukrt(1:(numMPxjexI+numwig));
for i=1:numwig
xkrt=[(-ddu*i) xkrt]; %just adding normal wiggle on the other side
ukrt=[mc ukrt];
end
elseif length(xkrt)<=numMPxjexI % If the 2nd photo has at the same number or a bit less (see fisrt if of this section) MP than the photo with the visible limit start
for i=1:numwig
xkrt=[(-ddu*i) xkrt (1+ddu*i)]; % just adding normal wiggle on each side
ukrt=[mc ukrt mc];
end
else % If the 2nd photo an amount of MP in between the amount the photo with the visible limit start has and that amount plus 2*numwig
for i=1:(numMPxjexI+numwig-length(xkrt))
xkrt=[xkrt (1+ddu*i)]; % adding extra wiggles (in addition to the additional MP) on the appropriate side
ukrt=[ukrt mc];
end
for i=1:numwig
xkrt=[(-ddu*i) xkrt]; % adding the normal amount of wiggle on the other side
ukrt=[mc ukrt];
end
end
% removes wiggle or extra MPs as the loop increases
for i1=1:numwig*2+1 % for 1st photo of the comparison pair
for i2=1:numwig*2+1
xj=(xjrt(i1:end-i2+1)-xjrt(i1))/(xjrt(end-i2+1)-xjrt(i1));
uj=(ujrt(i1:end-i2+1));
for i3=1:numwig*2+1% for 2nd photo of the comparison pair
for i4=1:numwig*2+1
xk=(xkrt(i3:end-i4+1)-xkrt(i3))/(xkrt(end-i4+1)-xkrt(i3));
uk=ukrt(i3:end-i4+1);
luj=length(uj); % length for the comparison matrices
luk=length(uk); % length for the comparison matrices
lujnddu=length(find(uj<4)); % counts the number of MP used without counting the extra bits
luknddu=length(find(uk<4)); % counts the number of MP used without counting the extra bits
co1=ones(luj,1)*uk; % makes a matrix with luj numbers of row, each row has the ukk data (markpoint type)
co2=(ones(luk,1)*uj)'; % makes a matrix with luk number of columns, each column has ujj data (markpoint type)
vvp=vv(co1(:)+vvl*(co2(:)-1)); % so vv is a column with the values of matching two mark points u to u -->1, u to d--> 0, d to s--> 0,5; vv1=3
vvp=reshape(vvp,luj,luk); % makes a matrix with 1 if the mark points in both photos have the same mark point category (up or down)
ddp=dd(co1(:)+vvl*(co2(:)-1));
ddp=reshape(ddp,luj,luk);
rmat=vvp.*exp(-((ones(luj,1)*xk-(ones(luk,1)*xj)').^2)./(2*((0.001+ddp).^2))); % for each of the mark points of the same type compares the position and gives a r value that represent whether they error distribution overlap
if luk>luj
rmat=rmat';
end
rr=sum(max(rmat))/(((lujnddu*compQVal(catqual-2))+ (luknddu*compQVal(qualPicTBM-2)))/(compQVal(catqual-2)+compQVal(qualPicTBM-2))); % adds all of the maximum r value for each possible combination and divides it by the greatest number of mark point
nn=nn+1;
rq(nn)=rr;
end
end
end
end
else % if the amount of MP of the ridge with an visible limit is much more than the amount of MP than the ridge without the visible limit
if p1==2 % if the 1st ridge start with an visible limit
xjrt=(xjr(2:end)-xjr(2))/(xjr(end)-xjr(2)); % remove the visible limit point
ujrt=ujr(2:end); % remove the visible limit point
elseif p2==2 % if the 1st ridge ends with an visible limit
xjrt=(xjr(1:(end-1))-xjr(1))/(xjr(end-1)-xjr(1)); % remove the visible limit point
ujrt=ujr(1:(end-1)); % remove the visible limit point
end
for i=1:numwig
xjr=[(-ddu*i) xjr (1+ddu*i)]; % adding the extra ends (ddu), 1st photo
xkr=[(-ddu*i) xkr (1+ddu*i)]; % adding the extra ends (ddu), 2nd photo
ujr=[mc ujr mc]; % adding points for the extra bits they have the same value as visible limit ends, 1st photo
ukr=[mc ukr mc]; % adding points for the extra bits they have the same value as visible limit ends, 2nd photo
end
for i1=1:numwig*2+1 % for 1st photo of the comparison pair
for i2=1:numwig*2+1
xj=(xjr(i1:end-i2+1)-xjr(i1))/(xjr(end-i2+1)-xjr(i1));
uj=(ujr(i1:end-i2+1));
for i3=1:numwig*2+1 % for 2nd photo of the comparison pair
for i4=1:numwig*2+1
xk=(xkr(i3:end-i4+1)-xkr(i3))/(xkr(end-i4+1)-xkr(i3));
uk=(ukr(i3:end-i4+1));
luj=length(uj);
luk=length(uk);
lujnddu=length(find(uj<4)); % counts the number of MP used without counting the extra bits
luknddu=length(find(uk<4)); % counts the number of MP used without counting the extra bits
co1=ones(luj,1)*uk; % makes a matrix with luj numbers of row, each row has the ukk data (markpoint type)
co2=(ones(luk,1)*uj)'; % makes a matrix with luk number of columns, each column has ujj data (markpoint type)
vvp=vv(co1(:)+vvl*(co2(:)-1)); % so vv is a column with the values of matching two mark points u to u -->1, u to d--> 0, d to s--> 0,5; vv1=3
vvp=reshape(vvp,luj,luk); % makes a matrix with 1 if the mark points in both photos have the same mark point category (up or down)
ddp=dd(co1(:)+vvl*(co2(:)-1));
ddp=reshape(ddp,luj,luk);
rmat=vvp.*exp(-((ones(luj,1)*xk-(ones(luk,1)*xj)').^2)./(2*((0.001+ddp).^2))); % for each of the mark points of the same type compares the position and gives a r value that represent whether they error distribution overlap
if luk>luj
rmat=rmat';
end
rr=sum(max(rmat))/(((lujnddu*compQVal(catqual-2))+ (luknddu*compQVal(qualPicTBM-2)))/(compQVal(catqual-2)+compQVal(qualPicTBM-2))); % adds all of the maximum r value for each possible combination and divides it by the greatest number of mark point and divide it so by the number of MP from the the ridge with the highest does count the extra bits as MP
nn=nn+1;
rq(nn)=rr;
end
end
end
end
end
elseif (p1==1 & p2==1 & p3==2 & p4==1) || (p1==1 & p2==1 & p3==1 & p4==2) % if (the 2nd ridge starts with an visible limit) OR (the 2nd ridge ends with an visible limit)
if (length(ukr)-1)<=(length(ujr)+2*numwig) % only do the comparison if the ridge with the visible limit start or end (the second ridge) has at the maximum the same ammount of MP than the 1st ridge plus twice the amount of wiggle
numMPxkexI=length(xkr)-1; % number of MP from the original 2nd ridge before adding the extra bits(ddu) it does not include the visible limit MP
if p3==2 % if the 2nd ridge starts with an visible limit
xkrt=(xkr(2:end)-xkr(2))/(xkr(end)-xkr(2)); % remove the visible limit point
ukrt=ukr(2:end); % remove the visible limit point
xkrt=1-fliplr(xkrt);
ukrt=fliplr(ukrt);
xjrt=1-fliplr(xjr); % for no reverse flip since the xkr is flipped
ujrt=fliplr(ujr);
elseif p4==2 % if the 2nd ridge ends with an visible limit
xkrt=(xkr(1:(end-1))-xkr(1))/(xkr(end-1)-xkr(1)); % remove the visible limit point
ukrt=ukr(1:(end-1)); % remove the visible limit point
xjrt=xjr; % for no reverse not flipped since the xkr is not flipped
ujrt=ujr;
end
for i=1:numwig % just adding the normal ddu wiggles like for when there is no visible limit
xkrt=[(-ddu*i) xkrt (1+ddu*i)]; % adding the extra ends (ddu), 2nd photo
ukrt=[mc ukrt mc]; % adding points for the extra bits they have the same value as visible limit ends, 2nd photo
end
if length(xjrt)>=(numMPxkexI+numwig) % If the 1st photo has at least the the same amount of MP than the number MP of the photo with visible limit + the amount numwig
xjrt=(xjrt(1:(numMPxkexI+numwig))-xjrt(1))/(xjrt(numMPxkexI+numwig)-xjrt(1));
ujrt=ujrt(1:(numMPxkexI+numwig));
for i=1:numwig
xjrt=[(-ddu*i) xjrt];
ujrt=[mc ujrt];
end
elseif length(xjrt)<=numMPxkexI % If the 2nd photo has at the same number or a bit less (see fisrt if of this section) MP than the photo with the visible limit start
for i=1:numwig
xjrt=[(-ddu*i) xjrt (1+ddu*i)];
ujrt=[mc ujrt mc];
end
else % If the 2nd photo an amount of MP in between the amount the photo with the visible limit start has and that amount plus 2*numwig
for i=1:(numMPxkexI+numwig-length(xjrt))
xjrt=[xjrt (1+ddu*i)];
ujrt=[ujrt mc];
end
for i=1:numwig
xjrt=[(-ddu*i) xjrt];
ujrt=[mc ujrt];
end
end
for i1=1:numwig*2+1 % for 1st photo of the comparison pair % might put this part before the for rev=1:2
for i2=1:numwig*2+1
xj=(xjrt(i1:end-i2+1)-xjrt(i1))/(xjrt(end-i2+1)-xjrt(i1));
uj=(ujrt(i1:end-i2+1));
for i3=1:numwig*2+1% for 2nd photo of the comparison pair
for i4=1:numwig*2+1
xk=(xkrt(i3:end-i4+1)-xkrt(i3))/(xkrt(end-i4+1)-xkrt(i3));
uk=ukrt(i3:end-i4+1);
luj=length(uj);
luk=length(uk);
lujnddu=length(find(uj<4)); % counts the number of MP used without counting the extra bits
luknddu=length(find(uk<4)); % counts the number of MP used without counting the extra bits
co1=ones(luj,1)*uk; % makes a matrix with luj numbers of row, each row has the ukk data (markpoint type)
co2=(ones(luk,1)*uj)'; % makes a matrix with luk number of columns, each column has ujj data (markpoint type)
vvp=vv(co1(:)+vvl*(co2(:)-1)); % so vv is a column with the values of matching two mark points u to u -->1, u to d--> 0, d to s--> 0,5; vv1=3
vvp=reshape(vvp,luj,luk); % makes a matrix with 1 if the mark points in both photos have the same mark point category (up or down)
ddp=dd(co1(:)+vvl*(co2(:)-1));
ddp=reshape(ddp,luj,luk);
rmat=vvp.*exp(-((ones(luj,1)*xk-(ones(luk,1)*xj)').^2)./(2*((0.001+ddp).^2))); % for each of the mark points of the same type compares the position and gives a r value that represent whether they error distribution overlap
if luk>luj
rmat=rmat';
end
rr=sum(max(rmat))/(((lujnddu*compQVal(catqual-2))+ (luknddu*compQVal(qualPicTBM-2)))/(compQVal(catqual-2)+compQVal(qualPicTBM-2))); % adds all of the maximum r value for each possible combination and divides it by the greatest number of mark point
nn=nn+1;
rq(nn)=rr;
end
end
end
end
else % if the amount of MP of the ridge with an visible limit is much more than the amount of MP than the ridge without the visible limit the match between these two ridges is unlikely and we give a rvalue of 0
if p3==2 % if the 2nd ridge starts with an visible limit
xkrt=(xkr(2:end)-xkr(2))/(xkr(end)-xkr(2)); % remove the visible limit point
ukrt=ukr(2:end); % remove the visible limit point
elseif p4==2 % if the 2nd ridge ends with an visible limit
xkrt=(xkr(1:(end-1))-xkr(1))/(xkr(end-1)-xkr(1)); % remove the visible limit point
ukrt=ukr(1:(end-1)); % remove the visible limit point
end
for i=1:numwig
xjr=[(-ddu*i) xjr (1+ddu*i)]; % adding the extra ends (ddu), 1st photo
xkr=[(-ddu*i) xkr (1+ddu*i)]; % adding the extra ends (ddu), 2nd photo
ujr=[mc ujr mc]; % adding points for the extra bits they have the same value as visible limit ends, 1st photo
ukr=[mc ukr mc]; % adding points for the extra bits they have the same value as visible limit ends, 2nd photo
end
for i1=1:numwig*2+1 % for 1st photo of the comparison pair
for i2=1:numwig*2+1
xj=(xjr(i1:end-i2+1)-xjr(i1))/(xjr(end-i2+1)-xjr(i1));
uj=(ujr(i1:end-i2+1));
for i3=1:numwig*2+1 % for 2nd photo of the comparison pair
for i4=1:numwig*2+1
xk=(xkr(i3:end-i4+1)-xkr(i3))/(xkr(end-i4+1)-xkr(i3));
uk=(ukr(i3:end-i4+1));
luj=length(uj);
luk=length(uk);
lujnddu=length(find(uj<4)); % counts the number of MP used without counting the extra bits
luknddu=length(find(uk<4)); % counts the number of MP used without counting the extra bits
co1=ones(luj,1)*uk; % makes a matrix with luj numbers of row, each row has the ukk data (markpoint type)
co2=(ones(luk,1)*uj)'; % makes a matrix with luk number of columns, each column has ujj data (markpoint type)
vvp=vv(co1(:)+vvl*(co2(:)-1)); % so vv is a column with the values of matching two mark points u to u -->1, u to d--> 0, d to s--> 0,5; vv1=3
vvp=reshape(vvp,luj,luk); % makes a matrix with 1 if the mark points in both photos have the same mark point category (up or down)
ddp=dd(co1(:)+vvl*(co2(:)-1));
ddp=reshape(ddp,luj,luk);
rmat=vvp.*exp(-((ones(luj,1)*xk-(ones(luk,1)*xj)').^2)./(2*((0.001+ddp).^2))); % for each of the mark points of the same type compares the position and gives a r value that represent whether they error distribution overlap
if luk>luj
rmat=rmat';
end
rr=sum(max(rmat))/(((lujnddu*compQVal(catqual-2))+ (luknddu*compQVal(qualPicTBM-2)))/(compQVal(catqual-2)+compQVal(qualPicTBM-2))); % adds all of the maximum r value for each possible combination and divides it by the greatest number of mark point and divide it so by the number of MP from the the ridge with the highest does count the extra bits as MP
nn=nn+1;
rq(nn)=rr;
end
end
end
end
end
elseif (p1==2 & p2==1 & p3==2 & p4==1) || (p1==1 & p2==2 & p3==1 & p4==2) % if each of the ridges have an visible limit on the same section, remember ridge cannot have two visible limits!
numMPxjexI=length(xjr)-1; % number of MP from the original 1st ridge before adding the extra bits(ddu) it does not include the visible limit MP
numMPxkexI=length(xkr)-1; % number of MP from the original 2nd ridge before adding the extra bits(ddu) it does not include the visible limit MP
compnumMP= [numMPxjexI numMPxkexI]; % to find which ridge has the smallest amount of point visible
[minval posmin]=min(compnumMP); % to find which ridge has the smallest amount of point visible
if p1==2 & p3==2 % if the 1st ridge start with an visible limit
xjrt=(xjr(2:end)-xjr(2))/(xjr(end)-xjr(2)); % remove the visible limit point
ujrt=ujr(2:end); % remove the visible limit point
xjrt=1-fliplr(xjrt);
ujrt=fliplr(ujrt);
xkrt=(xkr(2:end)-xkr(2))/(xkr(end)-xkr(2)); % remove the visible limit point
ukrt=ukr(2:end); % remove the visible limit point
xkrt=1-fliplr(xkrt); % for no reverse flip since the xjr is flipped
ukrt=fliplr(ukrt);
elseif p2==2 & p4==2 % if the 1st ridge ends with an visible limit
xjrt=(xjr(1:(end-1))-xjr(1))/(xjr(end-1)-xjr(1)); % remove the visible limit point
ujrt=ujr(1:(end-1)); % remove the visible limit point
xkrt=(xkr(1:(end-1))-xkr(1))/(xkr(end-1)-xkr(1)); % remove the visible limit point
ukrt=ukr(1:(end-1)); % remove the visible limit point
end
% same number of MPs on the two ridges --> just add normal wiggles on
% both sides
if numMPxjexI == numMPxkexI
for i=1:numwig % just adding the normal ddu wiggles like for when there is no visible limit
xjrt=[(-ddu*i) xjrt (1+ddu*i)]; % adding the extra ends (ddu), 1st photo
ujrt=[mc ujrt mc]; % adding points for the extra bits they have the same value as visible limit ends, 1st photo
xkrt=[(-ddu*i) xkrt (1+ddu*i)]; % adding the extra ends (ddu), 2nd photo
ukrt=[mc ukrt mc]; % adding points for the extra bits they have the same value as visible limit ends, 2nd phototo, reverse
end
elseif posmin==1 % if it's the 1st ridge (xj) that has the smallest amount of MP
for i=1:numwig % just adding the normal ddu wiggles like for when there is no visible limit
xjrt=[(-ddu*i) xjrt (1+ddu*i)]; % adding the extra ends (ddu), 1st photo
ujrt=[mc ujrt mc]; % adding points for the extra bits they have the same value as visible limit ends, 1st photo
end
if length(xkrt)>=(numMPxjexI+numwig) % If the 2nd photo has at least the the same amount of MP than the number MP of the photo with visible limit + two times the amount numwig
xkrt=(xkrt(1:(numMPxjexI+numwig))-xkrt(1))/(xkrt(numMPxjexI+numwig)-xkrt(1));
ukrt=ukrt(1:(numMPxjexI+numwig));
for i=1:numwig
xkrt=[(-ddu*i) xkrt];
ukrt=[mc ukrt];
end
else % If the 2nd photo an amount of MP in between the amount the photo with the visible limit start has and that amount plus 2*numwig
for i=1:(numMPxjexI+numwig-length(xkrt))
xkrt=[xkrt (1+ddu*i)];
ukrt=[ukrt mc];
end
for i=1:numwig
xkrt=[(-ddu*i) xkrt];
ukrt=[mc ukrt];
end
end
elseif posmin==2 % if it's the 2nd ridge that has the smallest amount of MP (if they both have the same amount of MP the 1st ridge comes as default)
for i=1:numwig % just adding the normal ddu wiggles like for when there is no visible limit
xkrt=[(-ddu*i) xkrt (1+ddu*i)]; % adding the extra ends (ddu), 2nd photo
ukrt=[mc ukrt mc]; % adding points for the extra bits they have the same value as visible limit ends, 2nd photo
end
if length(xjrt)>=(numMPxkexI+numwig) % If the 2nd photo has at least the the same amount of MP than the number MP of the photo with visible limit + two times the amount numwig
xjrt=(xjrt(1:(numMPxkexI+numwig))-xjrt(1))/(xjrt(numMPxkexI+numwig)-xjrt(1));
ujrt=ujrt(1:(numMPxkexI+numwig));
for i=1:numwig
xjrt=[(-ddu*i) xjrt];
ujrt=[mc ujrt];
end
else % If the 2nd photo an amount of MP in between the amount the photo with the visible limit start has and that amount plus 2*numwig
for i=1:(numMPxkexI+numwig-length(xjrt))
xjrt=[xjrt (1+ddu*i)];
ujrt=[ujrt mc];
end
for i=1:numwig
xjrt=[(-ddu*i) xjrt];
ujrt=[mc ujrt];
end
end
end
for i1=1:numwig*2+1 % for 1st photo of the comparison pair
for i2=1:numwig*2+1
xj=(xjrt(i1:end-i2+1)-xjrt(i1))/(xjrt(end-i2+1)-xjrt(i1));
uj=(ujrt(i1:end-i2+1));
for i3=1:numwig*2+1 % for 2nd photo of the comparison pair
for i4=1:numwig*2+1
xk=(xkrt(i3:end-i4+1)-xkrt(i3))/(xkrt(end-i4+1)-xkrt(i3));
uk=ukrt(i3:end-i4+1);
luj=length(uj);
luk=length(uk);
lujnddu=length(find(uj<4)); % counts the number of MP used without counting the extra bits
luknddu=length(find(uk<4)); % counts the number of MP used without counting the extra bits
co1=ones(luj,1)*uk; % makes a matrix with luj numbers of row, each row has the ukk data (markpoint type)
co2=(ones(luk,1)*uj)'; % makes a matrix with luk number of columns, each column has ujj data (markpoint type)
vvp=vv(co1(:)+vvl*(co2(:)-1)); % so vv is a column with the values of matching two mark points u to u -->1, u to d--> 0, d to s--> 0,5; vv1=3
vvp=reshape(vvp,luj,luk); % makes a matrix with 1 if the mark points in both photos have the same mark point category (up or down)
ddp=dd(co1(:)+vvl*(co2(:)-1));
ddp=reshape(ddp,luj,luk);
rmat=vvp.*exp(-((ones(luj,1)*xk-(ones(luk,1)*xj)').^2)./(2*((0.001+ddp).^2))); % for each of the mark points of the same type compares the position and gives a r value that represent whether they error distribution overlap
if luk>luj
rmat=rmat';
end
rr=sum(max(rmat))/(((lujnddu*compQVal(catqual-2))+ (luknddu*compQVal(qualPicTBM-2)))/(compQVal(catqual-2)+compQVal(qualPicTBM-2))); % adds all of the maximum r value for each possible combination and divides it by the greatest number of mark point
nn=nn+1;
rq(nn)=rr;
end
end
end
end
elseif (p1==2 & p2==1 & p3==1 & p4==2) || (p1==1 & p2==2 & p3==2 & p4==1)
numMPxjexI=length(xjr)-1; % number of MP from the original 1st ridge before adding the extra bits(ddu) it does not include the visible limit MP
numMPxkexI=length(xkr)-1; % number of MP from the original 2nd ridge before adding the extra bits(ddu) it does not include the visible limit MP
compnumMP= [numMPxjexI numMPxkexI]; % to find which ridge has the smallest amount of point visible
[minval posmin]=min(compnumMP); % to find which ridge has the smallest amount of point visible
if p1==2 & p4==2
xjrt=(xjr(2:end)-xjr(2))/(xjr(end)-xjr(2)); % remove the visible limit point
ujrt=ujr(2:end); % remove the visible limit point
xkrt=(xkr(1:(end-1))-xkr(1))/(xkr(end-1)-xkr(1)); % remove the visible limit point
ukrt=ukr(1:(end-1)); % remove the visible limit point