📄 readme.txt
字号:
-wCA
Comment: the file name is in the form <image name>"T"<trace functional>CA<diametrical functional>".sm"
-wCP
Comment: the file name is in the form <image name>"T"<trace functional>CP<diametrical functional>".sm"
Comment for these four options: output files: *.sm; overall LtrList* LdiList files per image are created.
-iwC
Comment: the file name is in the form <image name>"C.sc"
-iwCA
Comment: the file name is in the form <image name>"CA.sc"
-iwCP
Comment: the file name is in the form <image name>"CP.sc"
Comment for these three options: output files: *.sc, one file per image.
TRIPLE FEATURES
The program offers one file of triple features for each image; therefore, the first letter of option is "i". This file can be of three kinds:
triple features for plain (ie initial) circuses; the option to get such a file is
-iwFtxt
Comment: the file name is in the form <image name>"F.txt"
triple features computed for normalised associated circuses; the option is
-iwFAtxt
Comment: the file name is in the form <image name>"FA.txt"
and features computed for normalised plain circus; the option is
-iwFPtxt
Comment: the file name is in the form <image name>"FP.txt"
As it is seen from the extension, the files are text files. Triple features are arranged in lexicographical order of the triplets (this explains why the term "triple features" are used):
(<trace_functional>, <diametrical_functional>,<circus_functional>).
Therefore, all the computed triple features for a given trace matrix follow each other, then triple features for the next trace matrix follow, etc. Overall one file per image is produced, in it the number of triple features is equal to the product LtrList*LdiList*LcirList.
PART 2. OTHER PROGRAMS
LIST OF ALL FUNCTIONALS: PROGRAM "functional.cpp"
This can be compiled, for example, as
g++ functional.cpp -o functional -O3
Without arguments, this program types the list of currently available functionals. With argument it computes a single functional, and it can be used to check the properties of that functional. The latter can be done by using the matlab program "testTr.m", described below.
Read about the program functional.cpp in the first commented lines of its code.
MATLAB
The matlab session should start with "start.m". Matlab can be used for the following purposes:
1. To view a trace transform *.txt file, use line
M=textread(trace_transform_file_name)'; imagesc(M);colorbar;pixval
For example,
T33=textread('Outinfo/TrMatrs/image1T033.txt')';imagesc(T33)
(if the file exists)
2. To view all circuses for a given image, use the command
show_iwc_txt(text_file_containing_all_circuses,<Dir>)
Example:
show_iwc_txt('a0CA.txt')
(if <Dir>="Outinfo/"). For further information type
help show_iwc_txt
3. Function "computeFunctional.m" computes a functional "fnlNo" for a given trace f(t)=array "AA". It does this via "functional.cpp". Call this function as
fnlvalue=computeFunctional(fnlNo,typ,AA,Lbeg)
where "typ" can be one of the following two options:
0 - if the array "AA" consist of integer numbers in the range [0,255],
2 - if the elements of "AA" are interpreted as double.
This argument appears because a functional may be programmed in either of these two ways.
The integer argument Lbeg is equal to the first value t in trace f(t)=array "AA". Then the values of t are
Lbeg, Lbeg+1, Lbeg+2, ..., Lbeg+length(AA).
Output is
fnlvalue(1) - value of the functional for f(t)
fnlvalue(2) - value of the functional for f(-t)
fnlvalue(3) - value of the functional for -f(-t)
This kind of output is due to the fact that a functional for f(-t) and -f(-t) may be computed by different algorithms. This fact in the program is associated with attributes "attBack" and "attSack", and it is explained later.
4. In order to check the properties of a functional, one may investigate the behaviour of the functional to scaling, shrinking and shifting the trace f(t). Behaviour with respect to inverting the trace, in the sense of using f(-t) and -f(-t), is also needed since this should be described in program tt.cpp. The "testTr.m" performs this analysis using function "computeFunctional.m". As a result, an estimation of kappa, lambda and the invariance of the functional are given.
For further information use
help testTr
PART 3. WRITING A CODE FOR A NEW FUNCTIONAL
The number of objects and modi operandi is limited by constant
int const Amount=100;
in file "objects0.h". You can change this constant if larger indices are needed.
A new object should be first described in "objects0.h". Coding of a new object is demonstrated in an example of object 46.
ATTRIBUTES
Object no. 46 is described by its 12 attributes in "objects0.h":
k=46;
attIsfnl[k]=1;//0=non-scalar; 1=scalar
attName[k]="integral of |f'| circular";
attKind[k]=1;//0 = no info;1 = invariant; 2 = sensitive
attGray[k]=2;//0=for binary trace only,1=for integer trace, 2=for double trace
attBack[k]=0;//0=same,1=sign,k>1 in object k
attSack[k]=0;//0=same,1=sign,k>1 in object k
attHasKappa[k]=1; attKappa[k]=0;
attHasLambda[k]=1;attLambda[k]=1;
attBlank[k]=0;
attIsInteger[k]=1;//0=double output,1=integer output
This object uses another object, no. 45, which is called <integral of |f'|>. Object 45 is a summation of |f'(t)|, t=0,1,2,...,L-1. Object 46 is an object 45 plus
|f(L-1)-f(0)|. In turn, object 45 uses object 44. Its description is
k=44;
attIsfnl[k]=0;//0=non-scalar; 1=scalar
attName[k]="differences 1";
From this, one may notice that objects 46 and 45 are scalar objects, and therefore they may be treated as functionals. Object 44 is a helping array, and it is not a functional. For helping objects one needs only 2 attributes, and for scalar objects 12 attributes are needed. Attributes have the following meaning:
attIsfnl[k] explains whether the object no. k is a scalar one
attName[k] is its description or its formula
attKind[k] shows whether it is invariant, sensitive, or neither
attGray[k] explains whether it can be computed only for binary image, only for integer image, or for any real-valued image.
attBack[k] describes that functional T no. k has one of the properties:
T(f(-t))=T(f(t)) (attBack[k]=0),
T(f(-t))=-T(f(t)) (attBack[k]=1), or
T(f(-t)) can be found in object no. attBack[k] (if attBack[k]>1). In the latter case you have to create object k1= attBack[k]. For object k1 no attributes are necessary.
attSack[k] is similar to the previous one, but this time for T(-f(-t))
attHasKappa[k] answers the question whether the functional has a kappa.
Briefly, kappa is a number with property
(a^kappa)T(f(t))= T(f(at)) for all a>0.
attKappa[k] is kappa itself
attHasLambda[k] indicates whether the functional possesses a lambda, that is
(c^lambda)T(f(t))= T(cf(t)) for all c>0.
attLambda[k] is lambda, (if it exists)
attBlank[k] is the value of T(f(t)) if f is equal to the zero function
attIsInteger[k] indicates that T(f(t)) is an integer if f(t) is an integer valued function defined for integer variable t
No mistakes in the attributes are tolerable. This is why program "testTr.m", testing attributes, is present in the package. However, in the present version of the package some attributes may be out of use.
MODUS OPERANDI
"Modus operandi" is a function which computes an object. Object 46 is computed by modus operandi 57, found in file "modioperandi.h":
//*******************ANOTHER MODUS OPERANDI
out sumAbsDiff1c;// circular
void U57(void){u[0]=45;u[1]=0;}//uses objects, line should end with zero
void f57(void)//object 46 "integral of |tr'| circular"
{ sumAbsDiff1c=sumAbsDiff1+adiff1[L-1];
o[46]=sumAbsDiff1c;
}//END.
void V57(void)
{v[0]=46;v[1]=0;v[2]=0;v[3]=0;}//computed objects, line should end with zero
//*******************ANOTHER MODUS OPERANDI
here
out sumAbsDiff1c
is an output, that is functional 46, and this value can be used later in other modi operandi with indices >57. The word "out" is defined as "unsigned char" for computing trace functionals and "double" for other types of functional, i.e. diametrical and circus. However, one can see that functional 46 is also written to o[46]. This is the case for all functionals: they should be compulsorily written into the double array "o".
The other two functions U57 and V57 indicate which objects are used by this modi operandi f57 and which objects are computed by f57.
ASSIGNING U57, f57 and V57 TO AN ARRAY OF FUNCTIONS
The second place where modi operandi 57 should appear, is the line
M=57;U[M]=&U57;f[M]=&f57;V[M]=&V57;//computes object 45 "integral of |tr'| circular"
in function
void UfVArrAssign(void) //PLACE2
This is rather a mechanical addition.
MEMORY ALLOCATION
An object may need memory for performing the computation or for its result. For example, if the object is FFT, it certainly needs allocation of memory. This is done in function
void objectsMemoryConstructor(void) //PLACE3
Consider object 44, which is a pair of arrays of derivatives f'(t) and |f'(t)|. It is presented here by two lines
if (oneeded[44]){delete[]diff1;diff1=new TYPEsr[ML];
delete[]adiff1;adiff1=new TYPEsr[ML];}//"differences 1"
in this function. Initially these arrays are introduced as
TYPEsr *diff1=NULL,*adiff1=NULL,
at the beginning of "modioperani.h", (Please notice, that "=NULL" is compulsory due to "delete[]"). Word "TYPEsr" is identical to "out".
For object 46 no allocation of memory is necessary, and then "46" is not mentioned in "objectsMemoryConstructor"
ORDER
For a given stage, ie "TRACE" for trace transform, "DIAM" for computing circuses and "TRIPLE" for computing triple features, the user's list of functionals is transformed to a minimal list of modi operandi which are computed in ascending order. This means that one should bear in mind that the objects should be computed in such a way, that an object is computed before it is used. Briefly, the current object should first appear computed in the program in the previous lines in the "modioperandi.h".
The same object may be computed by several modi operandi. So then what is the rule of choosing modi operandi for computing a certain object? We shall consider the process of how modi operandi are chosen. The algorithm is as follows:
Start with the user's list of objects.
Step 1. First add to the list those modi that are unambiguously necessary.
Step 2 These will compute more objects than the user asked for, but also some extra objects may be needed to compute these modi operandi. These newly added objects should be computed and then we go back the Step 1 again.
Step 3. Eventually, we get only non-resolved objects computed by a few (>1) modi each. For each such object consider computing its modus operandi with the largest index. Then take the first modus (with the smallest index) from these modi operandi and go to Step 2.
At the end we shall get such modi operandi that do not need any more objects.
Then we can derive an ordering rule:
1. A modus operandi must use objects computed by previous modi operandi.
2. If an object N is computed by modi M1 and M2, M1<M2, then M2 is supposed to be faster, but M1 produces more objects, so N is a by-product of M1.
The following rule is not essential, however useful to make a program readable:
3. An object N for its computations should use objects with numbers less than N
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -