若若's profile芳草天涯PhotosBlogListsMore Tools Help

Blog


    October 11

    C++批量修改文件名

    从驴子上拖cd,最恼火就是乱七八糟的文件名和专门存放文件名的文本文件闹分裂。
    索性写个程序,从txt读取文件名列表,然后修改文件夹下所有文件的文件名。
    小程序仅限mp3文件。
     
     1 #include "stdafx.h"
     2 #include <afx.h>
     3 #include <iostream>
     4 #include <fstream> 
     5 #include <string>
     6 using namespace std;
     7 
     8 int RenameFromTXT(string InputFolderPath, string InputTXTName)
     9 {    
    10     int result=-1;
    11     CString cstr, CNewName;
    12     string str, OldName, NewName;
    13     CFileFind finder;   
    14     CString FolderPath = InputFolderPath.c_str();
    15     bool ifFind = finder.FindFile(FolderPath + "*.mp3"); 
    16 
    17     if(ifFind == false){
    18         cout<<"Folder not found!"<<endl;
    19         return -1;
    20     }
    21 
    22     ifstream inputNewName(InputTXTName.c_str());
    23     if(!inputNewName){
    24         cout<<"TXT-file not found!"<<endl;
    25         return -1;
    26     }
    27 
    28     while(ifFind)   
    29     {   
    30         ifFind = finder.FindNextFile();  
    31         cstr = finder.GetFilePath();
    32         USES_CONVERSION;
    33         OldName = W2A(cstr);
    34         cout<<"old path: "<<OldName.c_str()<<endl;
    35         getline(inputNewName, str);
    36         cout<<"new name: "<<str.c_str()<<endl;
    37         cstr = FolderPath + str.c_str();       
    38         CNewName = cstr + ".mp3";
    39         NewName = W2A(CNewName);
    40         cout<<"new path: "<<NewName<<endl;
    41         result = rename(OldName.c_str(), NewName.c_str());
    42         if( result == 0)
    43             cout<<"File successfully renamed!"<<endl;
    44         else{
    45             cout<<"Error renaming file: Permission denied"<<endl;
    46             cout<<"The new filename may contain \ / : ? \" < > |"<<endl;
    47             return -1;
    48         }
    49         cout<<endl;
    50         result=-1;
    51     }
    52     finder.Close();
    53     inputNewName.close();
    54     return 0;
    55 }
    56 
    57 int main(int argc, char **argv)
    58 {    
    59     string input1 = "D:\\Musik\\V.A.-.[Eurovision.Song.Contest.Moscow.2009.(2CD).(2009)].专辑.(MP3)\\";
    60     string input2 = "D:\\Musik\\NewNameList.txt";
    61     RenameFromTXT(input1, input2);
    62 
    63     system("pause");
    64     return 0;
    65 }

    main中调用时,只要输入待改文件名的文件夹路径,和存放新名字的文本文件路径和名字就行。 

    其中NewNameList.txt内容格式如下:

    101. Susanna Georgi — Le Teva Decisio (Get A Life) [Andorra]
    102. Kejsi Tola — Carry Me In Your Dreams [Albania]
    103. Inga & Anush — Jan Jan [Armenia]
    104. AySel & Arash — Always [Azerbaijan]
    105. Regina — Bistra Voda [Bosnia & Herzagovina]
    106. Copycat — Copycat [Belgium]
    107. Krasimir Avramov — Illusion [Bulgaria]
    108. Petr Elfimov — Eyes That Never Lie [Belarus]
    109. Lovebugs — Highest Heights, The [Switzerland]
    110. Christina Metaxa — Firefly [Cyprus]
    111. Gipsy.cz — Aven Romale [Czech Republic]
    112. Alex Swings Oscar Sings! — Miss Kiss Kiss Bang [Germany]
    113. Brinck — Believe Again [Denmark]
    114. Urban Symphony — Randajad [Estonia]
    115. Soraya — La Noche Es Para Mi (The Night Is For Me) [Spain]
    116. Waldo's People — Lose Control [Finland]
    117. Patricia Kaas — Et S'il Falliat Le Faire [France]
    118. Jade Ewen — It's My Time [United Kingdom]
    119. Sakis Rouvas — This Is Our Night [Greece]
    120. Igor Cukrov feat. Andrea — Lijepa Tena (Beautiful Tena) [Croatia]
    121. Zoli Adok — Dance With Me [Hungary]
    201. Sinead Mulvey & Black Daisy — Et Cetera [Ireland]
    202. Noa & Mira Awad — There Must Be Another Way [Israel]
    203. Yohanna — Is It True [Iceland]
    204. Sasha Son — Love [Lithuania]
    205. Intars Busulis — Probka [Latvia]
    206. Nelly Ciobanu — Hora Din Moldova (Dancing Moldova) [Moldova]
    207. Andrea Demirovic — Just Get Out Of My Life[Montenegro]
    208. Next Time — Neshto Shto Ke Ostane [FYR Macedonia]
    209. Chiara — What If We [Malta]
    210. Toppers — Shine [Netherlandsnew wave Eurovision 2009 mix]
    211. Alexander Rybak — Fairytale [Norway]
    212. Lidia Kopania — I Don't Wanna Leave [Poland]
    213. Flor-De-Lis — Todas As Ruas Do Amor [Portugal]
    214. Elena — Balkan Girls, The [Romania]
    215. Marko Kon & Milaan — Cipela [Serbia]
    216. Anastasia Prikhodko — Mamo [Russia]
    217. Malena Ernman — La Voix [Sweden]
    218. Nela Pociskova & Kamil Mikulcik — Let' Tmou [Slovakia]
    219. Quartissimo — Love Symphony [Slovenia]
    220. Hadise — Dum Tek Tek [Turkey]
    221. Svetlana Loboda — Be My Valentine! (Anti-crisis Girl) [Ukraine]

     

    一秒钟全改了,很爽Smiley mit geöffnetem Mund

    October 03

    C++编程思想(2nd卷一):函数重载与默认参数

    在C++中,struct和class唯一的不同之处就在于,struct默认为public,而class默认为private。


    在使用默认参数时必须记住两条规则:
    1.只有参数列表的后部参数才是可默认的,也就是说,不可以在一个默认参数后面又跟一个非默认的参数。
    2.一旦在一个参数调用中开始使用默认参数,那么这个参数后面的所有参数都必须是默认的。
    默认参数只能放在函数声明中,通常在一个头文件中。编译器必须在使用该函数之前知道默认值。


    占位符参数:
    函数声明时,参数可以没有标识符。其目的在于以后可以修改函数定义而不需要修改所有的函数调用。

    September 30

    不会创新因循守旧的神经网

    现在最大的问题就是神经网络不会创新,只会在原有的类的基础上进行分类。
    想要教他创新,结果却很不理想。。。
      1 //////////////////////////////////////////////////////////////////////////
      2 // File Name: pnn.cpp
      3 // Author:    Ruoruo(du#in.tum.de)
      4 //////////////////////////////////////////////////////////////////////////
      5 #include "stdafx.h"
      6 #include "cv.h"
      7 #include "highgui.h"
      8 #include <ml.h>
      9 #include <time.h>
     10 #include <ctype.h>
     11 #include <vector>
     12 #include <math.h> 
     13 #include <iostream>
     14 using namespace std;
     15 
     16 static CvScalar colors[] = 
     17     {
     18         {{0,0,255}},
     19         {{0,128,255}},
     20         {{0,255,255}},
     21         {{0,255,0}},
     22         {{255,128,0}},
     23         {{255,255,0}},
     24         {{255,0,0}},
     25         {{255,0,255}}
     26     };
     27 
     28 int main( int argc, char** argv )
     29 {
     30     vector<float> point;
     31     vector<float> result;
     32 
     33     float p[10= { 1.32.7,
     34                     1.53.0,
     35                     1.72.8,
     36                     1.62.6,
     37                     1.22.9 };
     38     float res[5= { 0,0,0,0,0 };
     39     int i;
     40     for(i=0; i<10; i++)
     41     {
     42         point.push_back(p[i]);
     43         if(i<5) result.push_back(res[i]);
     44     }
     45 
     46     CvMat* input = cvCreateMat( 52, CV_32FC1 );
     47     cvInitMatHeader( input, 52, CV_32FC1, p );
     48     CvMat* output = cvCreateMat( 51, CV_32FC1 );
     49     cvInitMatHeader( output, 51, CV_32FC1, res );
     50     IplImage* img = cvCreateImage(cvSize(450450), IPL_DEPTH_8U, 3);
     51     img->origin = 1;
     52     for(i= 0; i<5; i++)
     53     {
     54         cvCircle(img, cvPoint((int)(p[i*2]*100), (int)(p[i*2+1]* 100)), 5, colors[(int)res[i]%8], 1, CV_AA, 0);
     55     }
     56     
     57     int layer_num[3= { 241 };
     58     CvMat* layer_size = cvCreateMatHeader( 13, CV_32S );
     59     cvInitMatHeader( layer_size, 13, CV_32S, layer_num );
     60     CvANN_MLP pnn;
     61     pnn.create( layer_size, CvANN_MLP::SIGMOID_SYM, 11 );
     62     CvANN_MLP_TrainParams params;
     63     params.term_crit = cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, \
     64         3000.0000001 );
     65     params.train_method = 0;
     66     params.bp_dw_scale = 0.1;
     67     params.bp_moment_scale = 0.1;
     68     cout<<"begin training"<<endl;
     69     pnn.train( input, output, 00params );
     70     cout<<"end training"<<endl;
     71     pnn.save( "pNN_DATA.xml" );
     72 
     73     //begin to test
     74     float testp[24= { 1.42.75,
     75                         4.30.2
     76                         4.24.3,
     77                         1.452.85,
     78                         4.20.4,
     79                         4.14.0,
     80                         4.30.5,
     81                         4.04.2,
     82                         1.52.7
     83                         4.14.2
     84                         1.62.7,
     85                         4.00.3 };
     86     /*float testp[24] = { 1.4, 2.75,
     87                         4.3, 0.2, 
     88                         4.2, 4.3,
     89                         1.45, 2.85,
     90                         4.25, 0.3,
     91                         4.25, 4.25,
     92                         3.5, 1.2,
     93                         3.0, 3.7,
     94                         4.0, 2.7, 
     95                         0.2, 0.2, 
     96                         2.8, 2.7,
     97                         2.7, 2.8 };*/
     98     CvMat* test_point = cvCreateMat( 12, CV_32FC1 );    
     99     CvMat* test_result = cvCreateMat( 11, CV_32FC1 );
    100     CvFont font;
    101     double hScale=0.5;
    102     double vScale=0.5;
    103     int lineWidth=1;
    104     cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);
    105 
    106     for(i= 0; i<12; i++)
    107     {
    108         cvSetReal2D( test_point, 00, testp[2*i] );
    109         cvSetReal2D( test_point, 01, testp[2*i+1] );
    110         pnn.predict(test_point, test_result);
    111         cout<<cvmGet(test_result,0,0)<<endl;
    112 
    113         float delta = 1;
    114         int best_class = 0;
    115         int max_class = 0;
    116         for(int ii=0; ii<result.size(); ii++){
    117             if(fabs(cvmGet(test_result,0,0- (float)result[ii])<delta){
    118                 delta = fabs(cvmGet(test_result,0,0- (float)result[ii]);
    119                 best_class = result[ii];
    120             }
    121             if(result[ii]>=max_class)
    122                 max_class = result[ii];
    123         }
    124 
    125         point.push_back(testp[2*i]);
    126         point.push_back(testp[2*i+1]);
    127 
    128         if( delta>0.06 ){
    129             int new_result = max_class+1;
    130             cvmSet( test_result,0,0,new_result );
    131             result.push_back((float)new_result );
    132         }
    133         else{
    134             cvmSet( test_result,0,0,best_class );
    135             result.push_back((float)best_class );
    136         }
    137 
    138         int new_point_size = point.size();
    139         int new_result_size = result.size();
    140             
    141         CvMat* input = cvCreateMat( new_result_size, 2, CV_32FC1 );
    142         CvMat* output = cvCreateMat( new_result_size, 1, CV_32FC1 );
    143 
    144         for(int ii=0; ii<new_result_size; ii++)
    145         {
    146             cvmSet( input, ii, 0, point[2*ii]);
    147             cvmSet( input, ii, 1, point[2*ii+1]);
    148             cvmSet( output, ii, 0, result[ii]);
    149         }
    150         //cout<<"begin training again"<<endl;
    151         pnn.train( input, output, 00params );
    152         //cout<<"end training"<<endl;
    153 
    154         cvCircle( img, cvPoint((int)(testp[i*2]*100), (int)(testp[i*2+1]* 100)), 0, colors[(int)cvmGet(test_result,0,0)%8], 10, CV_AA, 0 );
    155 
    156         char buffer[10];
    157         _itoa(i,buffer,10);
    158         string point_id(buffer);
    159         cvPutText(img, point_id.c_str(), cvPoint(testp[2*i]*100,testp[2*i+1]*100), &font, cvScalar(255,255,255));
    160 
    161         cout<<i<<""<<"("<<testp[i*2]<<""<<testp[i*2+1]<<")"<<"\t"<<cvmGet(test_result,0,0)<<endl;
    162     }
    163 
    164     cvNamedWindow( "Coordinates" , 1 ); 
    165     cvShowImage( "Coordinates" ,img);
    166 
    167     cvWaitKey( 0 );
    168 
    169     cvDestroyWindow("Coordinates");
    170     cvReleaseImage(&img);
    171 
    172     return 0;
    173 }

    明明右下角四个点是一类,应该同色。显然点6和11分类错误了,6变成了第3个新类而11变成了第4个新类。或许类的名字对内部计算有很大影响,但目前还没有更好的办法,总之我这个循循善诱谆谆教诲的算法很垃圾就对了。。。

    最近压力好大 = =

    September 27

    C++的文件读写操作练习

    捡基础捡基础 = =|||
     
    #include <iostream>
    #include <fstream>
    #include <string> 
     
    #define WordByWord 1
    #define LineByLine 2
     
    void ReadAndShow( string fname, int flag )
    {
     ifstream fin( fname.c_str() );
     int i = 1;
     string s;
     
     if( !fin )
     {
      cout<<"File dose not exist!"<<endl;
      exit(-1);
     }
     if( flag == WordByWord)
     {
      while( fin>>s ){
       cout<<i<<". word: "<<s<<endl;
       i++;
      }
     }
     else if( flag == LineByLine )
     {
      while( getline(fin, s) ){
       cout<<i<<". line: "<<s<<endl;
       i++;
      }
     }
     else
     {
      cout<<"Error: The second argument should be 1 or 2."<<endl;
      exit(-1);
     }
     cout<<endl;
     fin.close();
    }
     
    int main()
    {
     string filename = "data.txt";
     ofstream fout( filename.c_str() );
     fout<<"Ich schreibe irgendwas hier,"<<endl;
     fout<<"um zu testen."<<endl;
     fout.close();
     ReadAndShow( filename, WordByWord );
     ReadAndShow( filename, LineByLine );
     
     return 0 ;
    }
     
    输出结果:
    Photobucket
    August 02

    翻译有关OpenCV海尔训练——(四)训练样本

    1.海尔训练
    现在,我们使用haartraining.exe来训练我们自己的分类器。训练语句如下:

    Usage: ./haartraining
      -data <dir_name>
      -vec <vec_file_name>
      -bg <background_file_name>
      [-npos <number_of_positive_samples = 2000>]
      [-nneg <number_of_negative_samples = 2000>]
      [-nstages <number_of_stages = 14>]
      [-nsplits <number_of_splits = 1>]
      [-mem <memory_in_MB = 200>]
      [-sym (default)] [-nonsym]
      [-minhitrate <min_hit_rate = 0.995000>]
      [-maxfalsealarm <max_false_alarm_rate = 0.500000>]
      [-weighttrimming <weight_trimming = 0.950000>]
      [-eqw]
      [-mode <BASIC (default) | CORE | ALL>]
      [-w <sample_width = 24>]
      [-h <sample_height = 24>]
      [-bt <DAB | RAB | LB | GAB (default)>]
      [-err <misclass (default) | gini | entropy>]
      [-maxtreesplits <max_number_of_splits_in_tree_cascade = 0>]
      [-minpos <min_number_of_positive_samples_per_cluster = 500>]


    Kuranov et. al. 指出,20*20的样本识别的正确率最高。另外,对于18*18的尺寸,四分裂节点表现最好。而对于20*20的样本,两节点显然更好。分裂节点数分别是2、3或4的弱树分类器间的差小于它们的中间节点。
    此外,关于20阶训练有个说法。假设我的测试集合代表了学习任务,我可以期望一个报错率是0.5^20≈9.6e-07,识对率是0.999^20≈0.98。
    所以,使用20*20的样本大小,并且Nsplit=2, Nstages=20, MINhitrate=0.9999(default: 0.995), MAXfalsealarm=0.5(default: 0.5), weighttrimming=0.95(default: 0.95)是比较优的组合。

    $ haartraining -data haarcascade -vec samples.vec -bg negatives.dat -nstages 20 -nsplits 2 -minhitrate 0.999 -maxfalsealarm 0.5 -npos 7000 -nneg 3019 -w 20 -h 20 -nonsym -mem 512 -mode ALL


    "-nonsym"选项用于没有垂直(左-右)对称的对象类。如果对象类是垂直对称的,例如正脸,则用"-sym (default)"。这样会增大运算速度,因为类海尔特征只有一半投入使用。
    "-mode ALL"使用了类海尔特征的扩展集。默认只使用竖直特征,ALL除了能使用竖直特征,还能使用转角为45°的特征集合。
    "-mem 512"是以MB为单位的预计算可使用的内存大小。默认是200MB。
    另外还有一些选项没有用到:

    [-bt <DAB | RAB | LB | GAB (default)>]
    [-err <misclass (default) | gini | entropy>]
    [-maxtreesplits <max_number_of_splits_in_tree_cascade = 0>]
    [-minpos <min_number_of_positive_samples_per_cluster = 500>]


    #你可以使用OpenMP(multi-processing).
    #一次训练持续三天。

    2.生成XML文件
    当海尔训练过程完全结束,它将会生成一个xml文件。
    如果你想要将一个中级海尔训练输出目录树转化为一个xml文件,在目录OpenCV/samples/c/convert_cascade.c下有个程序可供使用。
    输入的格式为:

    $ convert_cascade --size="<sample_width>x<sampe_height>" <haartraining_ouput_dir> <ouput_file>


    举例:

    $ convert_cascade --size="20x20" haarcascade haarcascade.xml

    翻译有关OpenCV海尔训练——(三)创建样本

    1.创建训练样本
    Kuranov et. al.指出,他们用了5000个含有正脸模板的正样本和3000个负样本进行训练,其中的5000个正样本是由1000张带脸的图像生成的。
    然而,你可能已经注意到了,以上四个方法都无法实现一下子由1000张图生成5000张图。我们必须先使用方法1使每张原图生成5张或者更多的正样本图,然后将这个过程重复1000次或更多次,最后合并所有生成的样本输出至vec文件中。
    我写了一个mergevec.cpp用来合并vec文件,还有一个叫createtrainsamples.pl的脚本用以重复该过程1000遍甚至更多遍。 我生成了7000个样本而不是5000,因为教程上说7000是最适当的数字。请将路径改为createsamples的位置。

    createtrainsamples.pl的输入格式为:

    $ perl createtrainsamples.pl <positives.dat> <negatives.dat> <vec_output_dir> [<totalnum = 7000>] [<createsample_command_options = "./createsamples -w 20 -h 20...">]


    mergevec的输入格式为:

    $ mergevec <collection_file_of_vecs> <output_vec_file_name>


    一个收集文件(一个含有文件名列表的文件)可以由下法生成:

    $ find [dir_name] -name '*.[ext]' > [collection_file_name]


    举例:

    $ cd HaarTraining/bin
    $ find ../../data/negatives/ -name '*.jpg' > negatives.dat
    $ find ../../data/umist_cropped/ -name '*.pgm' > positives.dat

    $ perl createtrainsamples.pl positives.dat negatives.dat samples 7000 "./createsamples  -bgcolor 0 -bgthresh 0 -maxxangle 1.1 -maxyangle 1.1 maxzangle 0.5 -maxidev 40 -w 20 -h 20"
    $ find samples/ -name '*.vec' > samples.dat # to create a collection file for vec files
    $ mergevec samples.dat samples.vec
    $ # createsamples -vec samples.vec -show -w 20 -h 20 # Extra: If you want to see inside


    20*20的样本大小检测正确率最高。


    2.创建测试样本
    测试样本是正样本镶嵌在负样本中并且正样本定位已知的样本图像。手动创建这样的图像是完全可行的。我们也能使用前面所说的第三种方法去综合这些图像。但是,我们只能一次加工一张图,如此,编写一个脚本(svn:createtestsamples.pl)可以帮助我们重复这种过程。

    createtestsamples.pl的输入格式为:

    $ perl createtestsamples.pl <positives.dat> <negatives.dat> <output_dir> [<totalnum = 1000>] [<createsample_command_options = "./createsamples -w 20 -h 20...">]


    这样就能生成许多jpg文件,并在<output_dir>中生成info.dat。jpg文件名格式是<number>_<x>_<y>_<width>_<height>.jpg,这里的x, y, width和height是嵌入对象的边缘矩形的坐标。

    举例:

    $ # cd HaarTraining/bin
    $ # find ../../data/negatives/ -name '*.jpg' > negatives.dat
    $ # find ../../data/umist_cropped/ -name '*.pgm' > positives.dat
    $ perl createtestsamples.pl positives.dat negatives.dat tests 1000 "./createsamples -bgcolor 0 -bgthresh 0 -maxxangle 1.1 -maxyangle 1.1 -maxzangle 0.5 maxidev 40"
    $ find tests/ -name 'info.dat' -exec cat \{\} \; > tests.dat # merge info files

    翻译有关OpenCV海尔训练——(二)创建样本(参考)

    我们可以使用createsamples utility(\bin\createsamples.exe)创建训练样本,并且测试它们。以下是选项列表:

    Usage: ./createsamples
      [-info <description_file_name>]例(C:\Temp2\positives\train.txt)
      [-img <image_file_name>]
      [-vec <vec_file_name>]例(data\positives.vec)
      [-bg <background_file_name>]
      [-num <number_of_samples = 1000>]例(-num 500)
      [-bgcolor <background_color = 0>]
      [-inv] [-randinv] [-bgthresh <background_color_threshold = 80>]
      [-maxidev <max_intensity_deviation = 40>]
      [-maxxangle <max_x_rotation_angle = 1.100000>]
      [-maxyangle <max_y_rotation_angle = 1.100000>]
      [-maxzangle <max_z_rotation_angle = 0.500000>]
      [-show [<scale = 4.000000>]]
      [-w <sample_width = 24>]
      [-h <sample_height = 24>]例(-w 20 -h 20)

     

    1. 由一个样本创建多个样本
    当选项-img, -bg和-vec被初始化时,这个函数(cvhaartraining.cpp#cvCreateTrainingSamples)会被启用。

    -img <one_positive_image>
    -bg <collection_file_of_negatives>
    -vec <name_of_the_output_file_containing_the_generated_samples>

    例如:

    $ createsamples -img face.png -num 10 -bg negatives.dat -vec samples.vec -maxxangle 0.6 -maxyangle 0 -maxzangle 0.3 -maxidev 100 -bgcolor 0 -bgthresh 0 -w 20 -h 20

     

    这个例子由一个正样本生成数量为<num>的多个样本。值得注意的是,只有前<num>个在<collection_file_of_negatives>中负样本会被采用。
    收集文件的格式(<collection_file_of_negatives>)为:

    img/img1.jpg
    img/img2.jpg

    它可以通过find命令来创建:

    $ cd [your working directory]
    $ find [image dir] -name '*.[image ext]' > [description file]

    比如:

    $ find ../../data/negatives/ -name '*.jpg' > negatives.dat

    2. 由多个样本创建训练样本
    当选项-img和-vec被初始化时,这个函数(cvhaartraining.cpp#cvCreateTestSamples)将会被启用。

    -info <description_file_of_samples>
    -vec <name_of_the_output_file_containing_the_generated_samples>

    例如:

    $ createsamples -info samples.dat -vec samples.vec -w 20 -h 20



    如此,就生成了未经变形的样本,你可以将其想象为一个文件格式转换函数。
    <description_file_of_samples>的格式为:

    [filename] [# of objects] [[x y width height] [... 2nd object] ...]
    [filename] [# of objects] [[x y width height] [... 2nd object] ...]
    [filename] [# of objects] [[x y width height] [... 2nd object] ...]


    其中,(x, y)是对象的左上角坐标,而整个样本图像的左上角为原点(0, 0)。例如:
    img/img1.jpg 1 140 100 45 45
    img/img2.jpg 2 100 200 50 50 50 30 25 25
    img/img3.jpg 1 0 0 20 20
    姑且称其为描述文件格式。
    这个方法获得了样本区域、重定大小并且将它们转化为.vec格式。但是它不能从一个样本生成多个样本。所以,在你已经有了大量的样本(5000到7000左右)时,才好使用这个方法。
    利用find命令和identify命令可以创建一个描述文件:

    $ cd <your working directory>
    $ find <dir> -name '*.<ext>' -exec identify -format '%i 1 0 0 %w %h' \{\} \; > <description_file>


    例如:

    $ find ../../data/umist_cropped -name '*.pgm' -exec identify -format '%i 1 0 0 %w %h' \{\} \; > samplesdescription.dat


    如果所有的样本图像都有着相同的大小尺寸,则命令写起来可以更加容易快捷:

    $ find <dir> -name '*.<ext>' -exec echo \{\} 1 0 0 <width> <height> \; > <description_file>


    例如:

    $ find ../../data/umist_cropped -name '*.pgm' -exec echo \{\} 1 0 0 20 20 \; > samplesdescription.dat


    好了,现在已经有了一个对象检测器了。

    3.创建测试样本
    这个方法(cvsamples.cpp#cvCreateTrainingSamplesFromInfo)是创建测试样本和它们的从单个样本变换而来的基本信息。

    开启条件:选项-img, -bg和-info被初始化。

    -img <one_positive_image>
    -bg <collection_file_of_negatives>
    -info <generated_description_file_for_the_generated_test_images>

    这里-w和-h被用作确定嵌入在测试样本中的正样本的最小尺寸。

    $ createsamples -img face.png -num 10 -bg negatives.dat -info test.dat -maxxangle 0.6 -maxyangle 0 -maxzangle 0.3 -maxidev 100 -bgcolor 0 -bgthresh 0



    输出样本的文件名格式是<number>_<x>_<y>_<width>_<height>.jpg,其中x, y, width和height说明了植入对象的边界矩形的坐标。
    <description_file_for_test_samples>格式与2.中描述文件格式格式相同。

    4.显示样本
    这个方法(cvsamples.cpp#cvShowVecSamples)是用一个vec文件显示样本图像。

    开启条件:选项-vec被初始化。例如:

    $ createsamples -vec samples.vec -w 20 -h 20
    July 31

    翻译有关OpenCV海尔训练——(一)数据准备

    作者:Naotoshi Seo

    OpenCV给我们提供了很多训练分类器的方法和程序。对于人脸检测的分类器训练叫做海尔训练,我们可以用这些方法创建我们自己的分类器。

    (一)数据准备:

    • 正样本(人脸)
              我们需要收集只含有脸部的图像。The UMIST Face Database 有着类似Video般的连续脸部图像,不论是正脸的还是侧脸的。我以为训练这些图像能生成一个面部表情鲁棒性很好的脸部检测器。然而我想得太过美好了,事实上效果一般。后来我又用了基于CMU PIE Database的正面脸部数据库,它包含了许多不同光照条件的图像,可是效果与前面类似,都不理想。MIT CBCL Face Data是另一种选择,它囊括了2429张正脸图像,其中也有一些不同的表情与光强。原本是很适合海尔训练的,然而该库的图像原始大小只有19*19,这样,我们就无法进行检测更好尺寸的人脸的实验。
              OpenCV的开发者有可能使用了FERET数据库。
    • 负样本(背景)
              我们同样需要收集一些我们不感兴趣的对象(也就是不含有人脸的图像)来生成海尔练级分类器。
    • 测试自然状态的图像(人脸在背景中)
              我们可以利用createsamples utility来综合测试图像集,不过有个专门的测试自然状态的图像集合就更好了。
              OpenCV的开发者使用了CMU-MIT Frontal Face Test Set去进行他们关于这类图像的实验。这个集合有个有关范围的描述,涵盖了眼睛、鼻子和嘴唇的中心及两端的方位信息,然而并没有由矩形区域来表示的人脸定位。
              但是,比如人脸区域的矩形可以由以下方法计算得出:
              以鼻子的高度作为矩形的上沿,以嘴巴的高度作为矩形的下沿,以嘴巴的左端作为矩形的左边缘,以嘴巴的右端作为矩形的右边缘。
              虽然此法不够完美,不过看起来还算可行。
    • 如何手动快速生成图像
              我使用的软件是imageclipper,这个软件不仅对海尔训练有帮助,而且也可应用于计算机视觉和机器学习研究等领域。它有如下特点:
              自动打开同一目录下的图像序列;以帧为单位打开视频文件;通过某快捷键方便剪切图像并跳至下一幅图像;直接用鼠标左键选定并剪切图像中的区域;通过鼠标右键移动或重置图像区域;所选定的区域也可显示在下一幅图中。
    May 06

    念想之间 尘埃落定

            我把钥匙卡在门旁一照,“滴——”一响,推门进屋。直映入眼的是实验室的凌乱。电脑拥挤地排列着,桌上摊着纸笔鼠标垫和乱七八糟的线甚至是刀叉,小机器人安静地站在电脑之间,一抬头便是窗外死角处又细又高尚未长成努力撑着叶子随风摇动的树苗……这样的不华丽不整洁却能突然间令我兴奋不已。就好像一下子回到了几年前,老爸的电子楼实验室,那散着横七竖八的板子元件电烙铁以及电线的拼接起来的桌子,一两本或熟悉或新鲜的教材书籍,老旧而反应迟钝的电脑,落着尘埃的键盘和其上用得油光的按键,窗外月色下的瘦削的没有叶子的细长花枝,还有那花枝顶上安静站立着的洁白的玉兰花……输入用户名和密码登陆,同样的一层薄灰的键盘,同样的干净发白的按键,同样的原始朴实的Windows界面。很好,这就是我想要的,并不枝繁叶茂但载满回忆的角落。

    April 22

    摘录:详解费米能级

    IC1第一堂课上得晕乎乎的,居然还冒出一个完全陌生的名词——费米能级。

    找篇详解,还是很晕@_@

    举个例子,一小学由一班学生,学生人数为50人,班上所提供的座位
    有60个.老师以学生的身高进行座位的分配.经分配后,班上身高较
    高的学生将配往后座,而且经分配后,班上将留下10个空位.这是一
    般我们小时候常经历的生活经验.电子在原子内分布的情形与分布
    的规则,与上面这个例子十分的相似.电子的能级,好比是例子里的
    座位;而电子的能量,则好比是例子里学生身高.能量较高的电子,
    就好像是身高较高的学生一般,将占往高位的能级(即例子里的后
    座),并使低位能的能级留下空缺(即空位).因为材料的导电性与位
    于导带的导电电子密度(或数量)有关,为了了解这一点,我们势必
    要先了解电子的量子状态分布(如例子里的座位分配),及电子的能
    量分布(即学生的身高分布)后,才能让我们掌握有多少自由电子位
    于导带内(即有多少身高较高的学生能坐在后座).在材料科学上,
    我们通常称前者(即电子的量子状态分布)为状态密度(Density 
    of Status),以N(E)表示;后者(即电子的能量分布)称为费米
    在绝对温度零度(0 k)时,原子内电子所能占住的最高能级的能
    量". 也就是说,在0 k时,所有低于Ef的能级将完全为电子所占满,
    而高于Ef的能级则完全空着,当物体所在的环境温度高于0 k后,虽
    然大多数的电子依然处于低能级上,但是一小部分的电子将因环境
    所提供的能量,而开始转往较高的能级,使电子的分布不再局限于
    Ef的下方,至于费米函数,则可以定义为:" 当物体所在的环境温度
    高于绝对零度时,在能量为Ef的能级上,发现电子的几率为50%", 

    发表用户:电子狂客 发表时间:2006-7-3 10:18:55

    December 03

    金木月·JSP

    10976656_20032164算是第一次正式写HTML吧,虽然以前也做过博客模板什么的,不过跟这次jsp比太小儿科了。东西确实太烦躁了,时间也不够,只能将就这样了,能运行出来了还是很满足的。下午四点多在地铁上看到天边的云很奇怪,很低很黑,而天被西沉的太阳染成橘色到深蓝的渐变,整个景观画面却因为解决了程序报错问题而变得好看起来,Orz我自己。。。据说国内这几天晚上能看到星星眼和月亮笑弯的嘴。金星木星和月球,擦肩而过没什么想法,在地球看来却是一场幸福的相遇。客观事物本无美丑,看客的心情决定一切。

    只有这学期才有效的网址:http://dbpra.in.tum.de:8080/dbpra01/aufgabe61.html

     

                                   10975115_5720141

    November 27

    Trouble Is A Friend

    目光呆滞地在图书馆等下节课,大脑罢工,只好写点儿中文缓解缓解。

    两天熬夜,编程编到三点,洋洋洒洒十多页,先后改版九次。在要交最终版本的时候,一直不吭声的Tobi自说自话要交自己的版本。三个组都是按照我的设计做的,你最后一刻要我们都用你的?要用你的你也早点儿弄好。四点钟一封邮件给我,要我们推翻重做五个小时内搞定算啥?就算你弄不好也把想法给我们说一下或者怎么都行。我吐血弄好了你又看不上。玛丽的邻居。不理他。自己给奥胖又交了一份。奥胖表示理解。看来分队历年都有矛盾。不过我看今年至少二队比我们高效得多。

    我们一队,越南人很沉默,突尼斯人啥都不做,德国人拖,中国人蚂蚁热锅……

    一个混乱无序的组织,合起来毫无意义。

    今天小测验,SQL轻松搞定,而且觉得题目很二极管里通电流——iDio(de)t。JDBC由于寄望于可以看书,没背。奥胖提示了十分钟,脑子始终是一片空白,本来就没啥在里头,结果无奈打回下周重测。苍天大地,明天还要交JSP大作业……

    在地铁里啃面包,悲伤一阵,烦躁一阵,最终还是平静了。痛苦的情绪,源于太计较自己的付出,而忽略了潜在的所得。如果不是写了这十几页的程序,SQL查询语句怎会信手拈来?

    让交作业期限来得更猛烈些吧!Trouble is a friend.

     

    Lenka - Trouble Is A Friend

    Trouble will find you no mater where you go, oh oh.
    No Matter if you're fast no matter if you're slow, oh oh.
    The eye of the storm and the cry in the morn, oh oh.
    Your fine for a while but then start to loose control.
    He's there in the dark,
    he's there in my heart,
    he waits in the winds
    he's gotta play a part.
    Trouble is a friend,
    yeah trouble is a friend of mine. oh oh!

    Trouble is a friend but trouble is a foe, oh oh.
    And no matter what I feed him he always seems to grow, oh oh.
    He sees what I see and he knows what I know, oh oh.
    So don't forget as you ease on down the road.
    He's there in the dark,
    he's there in my heart,
    he waits in the winds
    he's gotta play a part.
    Trouble is a friend,
    yeah trouble is a friend of mine. oh oh!

    So don't be alarmed if he takes you by the arm.
    I won't let him win, but im a sucker for his charm.
    Trouble is a friend,
    yeah trouble is a friend of mine. Oh oh!
    Oh how I hate the way he makes me feel.
    And how I try to make him leave; I try.
    Oh Oh I try!

    He's there in the dark,
    he's there in my heart,
    he waits in the winds
    he's gotta play a part.
    Trouble is a friend,
    yeah trouble is a friend of mine. oh oh!
    So don't be alarmed if he takes you by the arm.
    I won't let him win, but im a sucker for his charm.
    Trouble is a friend,
    yeah trouble is a friend of mine. Oh oh!

    September 19

    LV初学笔记

          不要误会。LV是LabVIEW,虚拟仪器。我用的是8.5,Demo版,试用30天,到处找不到注册机,说起来勉强也算个奢侈品?

          话说回来,用图片来编程还真是第一次见,编起程来像画画,或者拼图,或者搭积木?总而言之,很好玩。其实一开始就被迷住了,谁曾想一个for循环能用一个框框来表达?编一个子程序还要为这个子程序配一幅画?简直是天方夜谭!只不过,讲这个故事的是个土耳其人,将就将就了。于是我想,就算才疏学浅不能跟着他干,学学这个东西也是好的。

          趁新鲜写点记录,以备后用。没装中文版的,专业词语只好乱用了。

    • 总而言之,就两块板:一块是操作板,两个用途即操作和显示,通俗讲就是用来放一些LED、按钮、调值器、操作杆、示波器等等,而且是运行的地方;另一块是编程板,就是写程序的地方,就好像黑箱子里面,要连好多线,其实就是花哨版的电路图。
    • 因为是绘图编程,所以鼠标右键特别有用。一开始不知道,傻乎乎地不厌其烦用左键点开元件表选元件,后来知道相关元件都可以在元件的端口右键选择,比如Timer旁边右键Erstellen选Konstant定时间,矩阵Max&Min旁边右键选Erstellen选Anzeigeelement,Signale右键Erstellen选Graph-Anzeige等等,都是绝配。还有就是导线连得太乱可以右键自动整理。导线连接元件时可用右键查看元件的接口分布图。导线与循环框框或者什么别的框框的交点上右键Indizierung (de)aktivieren是个很重要的功能。I/O控制的元件上右键属性选择存储或者读取的路径,若是表格还要选分隔符。操作板上图太乱了可以用右键然后Datenoperationen把历史图像删掉。子程序的设定方面,在右上角的图标上右键的子菜单也必不可少。
    • 快捷键:Ctrl+B是清除所有错误导线;Ctrl+E是操作板和编程板窗口之间的转换;Ctrl+H是显示帮助文字,另外,帮助窗口很有用,一般都开着。
    • 不同类型的数据用不同颜色来表示,导线只有和元件接口同色,才能正确连接,否则显示错误。DBL是双精度浮点数,色橘黄。正蓝是整型数,深蓝粗虚线表示信号,草绿为布尔,桃红是Kommentar或者Beschreibung之类的Text……
    • 子程序不但要起好名字,还必须要定义一个图标,图标可以自己画,也可以插图进去。总之对应于一般编程语言为函数起名字,在绘图编程语言上自然就是做图标了。做好图标后还要定义接口在图标上的分布。再调用时就从存储的路径下把这个子程序选出来,贴到程序里就是自己定义的图标式样了。
    • 程序运行的顺序是件比较好玩的事情。没有从左至右或者从上至下的规矩,而是依照数据流过各个元件的顺序,比如从数据的输入开始,终止于数据的输出。后来发现了一个比较好玩的东东,就是时间控制序列的框框,被框起来的元件可以设定开始运行的时间,于是“面向过程的语言”就可以轻松实现。
    • I/O控制方面,文件的写入和读出都需要时间,不是刚写完文件就马上可以读的,中间要留一定的时间给电脑读写。
    • for控制需要一定次数的循环,比如对矩阵赋值;while控制任意次数的循环,会在操作板上出现一个stop按钮人为控制循环结束,或者将stop元件与时间元件相连到时即止。

          基本先这样。做了个不伦不类的东东:把10秒声音换成华氏或者摄氏度,显示图像并显示最大最小值,算出均值,存档,再读档,以图像显示,对照检验。没办法没有温度传感器。冷。哆嗦一下。

    LV初学笔记

    July 11

    Java

    其实时间过得一点儿也不快,想起去年初春的程序考试,那时身边的人留下的浮光掠影,忽然有种恍若隔世的错觉…… 

    拼了老命,如果不出意外,能拿下了GRV的Bonus了。70%,也算是一个记录。Tutor Guenther很nett,很负责,也很牛,计算机电子双硕士,腾不出时间加给我们。下周除了上TÜ的时间空,其他时间全有考试。听他说了一堆日期后,我们眩晕地选择放弃,只好委屈THEO考试了。Guenther出的Zusatzaufgaben,相当好,比Leitung的好很多,很满足地做了3个小时,有爽的感觉。。。估计如果Guenther带Netz的Praktikum,我就追随了。。。汗。可惜双硕士还未毕业,资历不够,但牛人终归是牛人,假以时日,能秒杀Leitung。

    房子下来了,去看了看我的前房东,一位很nett的德国MM,朝东的窗口远望能及郁郁森森的英国花园和若隐若现的阿尔卑斯,不禁又想起Michi同学糟糕的厨艺和馋嘴的肚皮。一年而已,物是人非,沧海桑田。

    曾经看见一个刻苦的人写道:“那些岁月,我每天用17个小时读书。”这究竟是什么概念啊!尽了我最大的努力,每天十个小时已经是极限!今晚回家的路上一路眩晕,似乎木木刚做了三三三个腹部绕杠。当然我这儿可能是低血糖。。。

    下午吃了一支很有意思的Ice——MI楼里卖的和路雪,名字叫Java,牛奶巧克力夹着浓浓香草……如今的我不会去想那遥远的印度尼西亚爪哇岛上的可可,而是做梦着吃了Java能变得聪明一点。毕竟考试之际,内心深处需要一点自我解嘲。

    February 19

    终于又灭了一门 咔咔~

    趁着新鲜回忆题目下下,有同学要考~

    这门课叫MMK1,Mensch-Maschine-Kommunikation 1。

    75分钟,总共4个Aufgabe。

    1,给出一套公寓的平面图,有A~I个房间,互相连通。消防员救火需要将房间遍历。画出Suchbaum;每个房间都有Kosten,就是它在格子图上的大小,要用heuristische Suche找出Kosten最小的遍历顺序;有个小孩在E房间,妈妈在F房间,消防员找到他们的最段路径用什么算法。

    2,共有75个魔法咒语,用HMM区分,需要多少HMMs;给出一句咒语,四个T的o,以及A-Matrix、B-Matrix、e和v,根据A判断该HMM的类型;画Trellis图;用Vorwaerts算法算p(o|拉姆达);Viterbi。。。几个老套不说了,昨天和HMM熬夜大战三百回合,见到此题,分外亲切。

    3,已知一Aussage=T,求T的否定,KNF,证明其Gueltigkeit,填写真值表;仨人讨论谁吃了蛋糕,每个人说一句话,写成Praedikatenlogik,从而得出谁吃了蛋糕。。。除了弱智的真值表我给弄错了,其他都简单死,没有任何技术含量,怨念的真值表啊,看来我不适合当体力劳动者。。。

    4,弄了半天也没搞清题目啥意思(心里在想怎么老师还没报剩15分钟,教室又没钟,我那个急啊乱啊。其实前面做得确实快得出乎我意料了),就看到要算Luminanznormierung,于是就算,算好了在Farbtafel里标注一下;还问了另外有个Farbe的坐标,是不是很重要等;要画出Staebchen和Zapfen的分布图和Hoerflaeche图,前者幸好带的纸上有,对于后者我只有囧了,谁没事儿干研究这破图啊,于是开始愤恨让带纸进考场的bt制度,向将所有讲义和练习答案挤着打印在两张纸上的人致敬,囧rz。。。

    还有些啥边边角角的问题,记不周全了。反正就75分钟,埋头抓狂似地写,很猛很暴力。。。除了真的无能为力的,其他都涂鸦满了。其实已经比以前进步些了,不然说不定还没找到感觉就收卷了。。嗯,满意ing。。

     

    吃了两天的百服宁,勉强维持鼻子还能出气进气,坚持熬了两夜,昨天甚至都没吃米,导致考完路过某餐馆么忍住进去fb了一把。为啥老把自己弄得这么惨啊,好像考不出会死人一样。。赖到补考,或者递病假条,绝望的时候都想过,也只不过想想,没有理由找借口的。于是憋着一口气,拼命织啊拼命织,在临刑前把十一件荨麻外衣扔给十一天鹅,就不用死啦~(为我的抱佛脚找到一件童话般的美丽外衣= =|||)

    February 06

    with SQL给大家拜个早年~

    create view 鼠年大吉 as

    select 2008.新年运势

    from 俺滴祝福 2008

    where 2008.财经状况='涨停不断' and 2008.身体状况='吃嘛嘛香' and

              2008.友情<>'投名状' and 2008.爱情<>'云水谣' and 2008.学业事业<>'无间道'

    February 05

    扔点东西自己看(二)——操作系统中文资料大杂烩

    • linux/unix中soft link和hard link的区别

    硬链接文件和原文件指向同样的数据,两者就像科隆一样,inode号也相同,当删除原文件时,硬链接文件仍然存在有效。但硬链接文件不同于文件的复制。应该说硬链接文件的产生只是原文件所在目录文件的内容发生改变,原文件的数据并没有得到复制,而复制文件,磁盘上有两份数据。简单说,硬链接就是一个类似于别名的概念。当原来的名字没有了,别名照样可以使用。

    软连接也叫符号连接,他只是对源文件在新的位置建立一个“快捷(借用一下wondows常用词)”,所以,当源文件删除时,符号连接的文件将成为无源之水->仅仅剩下个文件名了,当然删除这个连接,也不会影响到源文件,但对连接文件的使用、引用都是直接调用源文件的。
     
    • 时间片随机到达的轮转调度算法分析
        Shortage of Analysis of Instances Scheduled by the Quantum Round Robin Algorithm

    在早期的时间片轮转法中,系统将所有的就绪进程按先来先服务的原则,排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片.时间片的大小从几ms到几百ms.当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片.这样就可以保证就绪队列中的所有进程,在一给定的时间内,均能获得一时间片的处理机执行时间.

     

    • MFT

    NTFS 中包含一个称为主文件表 (MFT) 的文件。MFT 是一个映射磁盘中储存的所有对象的索引文件。在 MFT 中,NTFS 磁盘上的每个文件(包括 MFT 自身)至少有一映射项。MFT 中的各项包含如下数据: 大小、时间及时间戳、安全属性和数据位置。一但 MFT 产生碎片,磁盘碎片整理程序无法对其进行碎片整理。但是,由于可以持续使用 MFT 来存取磁盘上所有的其它文件,因此它也会逐渐形成碎片,从而导致磁盘存取时间加长,降低磁盘性能。NTFS 通过保留 1/8 的磁盘空间留作 MFT 专用而将此影响降至最低。磁盘的此区域(称为 MFT 区域)尽可能在 MFT 增加时保持其连续性。
    • i-node

    i-node你可以理解成一个大楼。
    i-node用光了,不能增加,除非format的时候制定。。 i-node你可以理解成一个大楼。 如果这个楼房建筑的时候,就是100户,只能卖100套房子,住100户人家,没家4室二厅,200平米。。当来了101户人的时候,虽然没家人家200平米,但是也只是人家自己住。不能让其他人住了。。 如果你建立楼房的时候,都是小户型,同样建筑面积200×100平米,但是你每个户型都是100平米的小房间,就可以住200户人家了。。 这个东西,是你盖房子的时候决定的。以后不允许你在顶楼上再加盖了。。 系统的i-noode也是这个意思。。 创建文件系统的时候,就定义了i-noode的个数。计算机是通过i-noode来管理文件系统的。。
     
    When a file system is created, data structures that contain information about files are created. Each file has an inode and is identified by an inode number (often "i-number" or even shorter, "ino") in the file system where it resides. Inodes store information on files such as user and group ownership, access mode (read, write, execute permissions) and type of file. There is a fixed number of inodes, which indicates the maximum number of files each filesystem can hold.
     
    • POSIX标准

    POSIX,准确的说,是POS,是一套标准,是由IEEE(Institute of Electrical and Electronic Engineering)开发的,并由ANSI(American National Standards Institute)和ISO(International Standards Organisation)标准化。
    因为UNIX API 几乎可以作为编写真正可移植软件的硬件无关标准,所以最初的IEEE所标称的“可移植操作系统标准”(Portable Operation System Standard)的POS很快被大家加了后缀变成了“POSIX”,缩写为POSIX是为了读音更像Unix。
    POSIX标准定义了操作系统应该为应用程序提供的接口:系统调用集。
    • gcc

    Linux系统下的gcc(GNU C Compiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。
    gcc编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件。在Linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。而gcc则通过后缀来区别输入文件的类别,下面我们来介绍gcc所遵循的部分约定规则。
    .c为后缀的文件,C语言源代码文件;
    .a为后缀的文件,是由目标文件构成的档案库文件;
    .C,.cc或.cxx 为后缀的文件,是C++源代码文件;
    .h为后缀的文件,是程序所包含的头文件;
    .i 为后缀的文件,是已经预处理过的C源代码文件;
    .ii为后缀的文件,是已经预处理过的C++源代码文件;
    .m为后缀的文件,是Objective-C源代码文件;
    .o为后缀的文件,是编译后的目标文件;
    .s为后缀的文件,是汇编语言源代码文件;
    .S为后缀的文件,是经过预编译的汇编语言源代码文件。
    gcc的执行过程
    虽然我们称gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。
    命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。
    gcc的基本用法和选项
    在使用gcc编译器的时候,我们必须给出一系列必要的调用参数和文件名称。gcc编译器的调用参数大约有100多个,其中多数参数我们可能根本就用不到,这里只介绍其中最基本、最常用的参数。
    gcc最基本的用法是∶gcc [options] [filenames]
    其中options就是编译器所需要的参数,filenames给出相关的文件名称。
    -c,只编译,不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
    -o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。
    -g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。
    -O,对程序进行优化编译、连接,采用这个选项,整个源代码会在编译、连接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。
    -O2,比-O更好的优化编译、连接,当然整个编译、连接过程会更慢。
    -Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。C程序中的头文件包含两种情况∶
    A)#include
    B)#include “myinc.h”
    其中,A类使用尖括号(< >),B类使用双引号(“ ”)。对于A类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而对于B类,cpp在当前目录中搜寻头文件,这个选项的作用是告诉cpp,如果在当前目录中没有找到需要的文件,就到指定的dirname目录中去寻找。在程序设计中,如果我们需要的这种包含文件分别分布在不同的目录中,就需要逐个使用-I选项给出搜索路径。
    -Ldirname,将dirname所指出的目录加入到程序函数档案库文件的目录列表中,是在连接过程中使用的参数。在预设状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的档案库文件,这个选项告诉连接程序,首先到-L指定的目录中去寻找,然后到系统预设路径中寻找,如果函数库存放在多个目录下,就需要依次使用这个选项,给出相应的存放目录。
    -lname,在连接时,装载名字为“libname.a”的函数库,该函数库位于系统预设的目录或者由-L选项确定的目录下。例如,-lm表示连接名为“libm.a”的数学函数库。
    上面我们简要介绍了gcc编译器最常用的功能和主要参数选项,更为详尽的资料可以参看Linux系统的联机帮助。
    假定我们有一个程序名为test.c的C语言源代码文件,要生成一个可执行文件,最简单的办法就是∶
    gcc test.c
    这时,预编译、编译连接一次完成,生成一个系统预设的名为a.out的可执行文件,对于稍为复杂的情况,比如有多个源代码文件、需要连接档案库或者有其他比较特别的要求,就要给定适当的调用选项参数。再看一个简单的例子。
    整个源代码程序由两个文件testmain.c 和testsub.c组成,程序中使用了系统提供的数学库,同时希望给出的可执行文件为test,这时的编译命令可以是∶
    gcc testmain.c testsub.c □lm □o test
    其中,-lm表示连接系统的数学库libm.a,这个过程可以用图12-1框图描述。
    gcc的错误类型及对策
    gcc编译器如果发现源程序中有错误,就无法继续进行,也无法生成最终的可执行文件。为了便于修改,gcc给出错误资讯,我们必须对这些错误资讯逐个进行分析、处理,并修改相应的语言,才能保证源代码的正确编译连接。gcc给出的错误资讯一般可以分为四大类,下面我们分别讨论其产生的原因和对策。
    第一类∶C语法错误
    错误资讯∶文件source.c中第n行有语法错误(syntex errror)。这种类型的错误,一般都是C语言的语法错误,应该仔细检查源代码文件中第n行及该行之前的程序,有时也需要对该文件所包含的头文件进行检查。有些情况下,一个很简单的语法错误,gcc会给出一大堆错误,我们最主要的是要保持清醒的头脑,不要被其吓倒,必要的时候再参考一下C语言的基本教材。
    第二类∶头文件错误
    错误资讯∶找不到头文件head.h(Can not find include file head.h)。这类错误是源代码文件中的包含头文件有问题,可能的原因有头文件名错误、指定的头文件所在目录名错误等,也可能是错误地使用了双引号和尖括号。
    第三类∶档案库错误
    错误资讯∶连接程序找不到所需的函数库,例如∶
    ld: -lm: No such file or directory
    这类错误是与目标文件相连接的函数库有错误,可能的原因是函数库名错误、指定的函数库所在目录名称错误等,检查的方法是使用find命令在可能的目录中寻找相应的函数库名,确定档案库及目录的名称并修改程序中及编译选项中的名称。
    第四类∶未定义符号
    错误资讯∶有未定义的符号(Undefined symbol)。这类错误是在连接过程中出现的,可能有两种原因∶一是使用者自己定义的函数或者全局变量所在源代码文件,没有被编译、连接,或者干脆还没有定义,这需要使用者根据实际情况修改源程序,给出全局变量或者函数的定义体;二是未定义的符号是一个标准的库函数,在源程序中使用了该库函数,而连接过程中还没有给定相应的函数库的名称,或者是该档案库的目录名称有问题,这时需要使用档案库维护命令ar检查我们需要的库函数到底位于哪一个函数库中,确定之后,修改gcc连接选项中的-l和-L项。
    排除编译、连接过程中的错误,应该说这只是程序设计中最简单、最基本的一个步骤,可以说只是开了个头。这个过程中的错误,只是我们在使用C语言描述一个算法中所产生的错误,是比较容易排除的。我们写一个程序,到编译、连接通过为止,应该说刚刚开始,程序在运行过程中所出现的问题,是算法设计有问题,说得更玄点是对问题的认识和理解不够,还需要更加深入地测试、调试和修改。一个程序,稍为复杂的程序,往往要经过多次的编译、连接和测试、修改。下面我们学习的程序维护、调试工具和版本维护就是在程序调试、测试过程中使用的,用来解决调测阶段所出现的问题。

    摘自:大学生网络联盟

    • Petrinetze

    计算元素同步元素(T元),用方框表示;存储元素异步元素(S元),用圆形表示。

    关系只有边(T,S)和(S,T),没有(T,T)和(S,S)边。即同步元素周围是异步元素,而异步元素周围一定是同步元素;边有方向;边里流动着的是消息,消息即数据。

    同步元素T是无状态元素,其内部实现就是一个用函数表示的加工。元素有n条输入边和m条输出边,且n、m >= 1,即至少有一条输入边和一条输出边。虽然元素内部的函数有确定的终生不变的输入参数和输出参数,但元素边的数量以及边中的消息却是可以随外界而变化的,但是一定保持输入边和输出边里的消息里含有的数据符合函数要求、且总质量不变。

    同步元素T的同步是指同步元素周围的所有n+m条消息,要么同时发生,要么同时不发生,并且称这n+m条消息的同步为“一次执行”。即保证一次执行的原子性。

    异步元素P也有n条输入边和m条输出边,且n+m >= 1,即至少有一条输入边或者一条输出边。异步元素总是被动地为同步元素提供或接受消息,一次一条。

    元素的邻居、及其间的消息,都是由系统定义,与元素自身无关。但要求元素能够接收和发出这些消息。元素的邻居数量、及其重要性不是一成不变的,在不同的应用环境里,可以有很大差别,如同人类的朋友关系。

    同步元素是一个消息加工系统,即现实世界里的加工厂或者计算机里的函数,叫“变迁”。异步元素就是一个消息存储系统,即现实世界里的仓库或者计算机里的数据存储系统,叫“库所”。

    Petri网是一个“自分解(解构、析构)”和“自组合(重组、重构)”的系统模型,即同步元素和异步元素都可以是另外一个Petri网系统。但其原子元素必须是计算机里的函数或者数据存储系统,即软件构件系统(software components system)或者软件存储系统(software storages system)。

    补充:Petri网就是把一个个封闭的图灵机系统用消息传递联系成为一个整体的“虚拟社会”的。Petri网把所有的软件系统统统分成两类:1类是计算元素的软件构件,如dll文件,是函数集合,负责消息处理和转换。因为计算元素不存储任何中间状态,所以必需立即把处理结果再用消息传递出去,因而叫又同步元素。另1类是存储元素的软件应用系统,用于加工并保存消息中的有用数据。存储元素可以按照应用逻辑的要求保存或者提供(而不是同时既保存又提供)消息里的用户数据,因而又叫异步元素。所有软件系统要么属于计算元素,要么属于存储元素,没有第3类,不可能有既是计算元素同时又是存储元素的软件系统。

    Petri网模型没有全局状态,也没有任何的中央控制,可以无限扩展。系统的每一个元素只与其周围邻居发生着关系,Petri网就是一个完全分布的P2P网络,如同Gnutella协议。

      

    出自:http://www.cnblogs.com/luohuarenduli/archive/2007/04/28/731160.aspx 

     

     

    ps. 谢谢筒子们关心,某就素考前焦虑综合症,从小学期末大考开始到现在都介样,么虾米出息 = =

    pps. 收到杰小妹滴片片,稍待日后闲暇之时再叙音乐及松鼠等有关事宜,钦此。

    December 17

    很白痴的发现

    对于电视里出现颤抖的横条纹的电脑显示器,豁然有了后知后觉的理论认识。。。

    出现颤抖横条纹的显示器,一定是显像管式而非液晶,而前者的工作原理就是奇偶行交错半屏半屏地刷新,由于速率太快,人的肉眼无法察觉。而摄像头帧数的刷新率又远远小于显像管显示器的刷新率。。。

    火星人就是火星人,俺承认俺的天线很壮硕。。。。。。。

    December 15

    看图说话·生活之不完全手册

    贴点照片,给老爸老妈和国内的朋友们看下~

    Foto0374

    早上从学生城的地铁站出发,去Garching上课。

    Foto0375

    从Garching的地铁站出来。

    070511 (17)

    上完课又去Garching地铁站赶地铁,去本部。

    Foto0397

    本部的阶教里听电子课,信号与系统,老师用的是Matlab。

    Foto0390

    上完课去食堂,穿越本部校区。

    Foto0393

    有鸡腿有土豆有蔬菜还有汤,有史以来最合算的一顿:2,35欧~

    Foto0409

    绕道去图书馆,Lidl超市那里,马路对面的小狗期待主人快点购物归来。

    Foto0410

    图书馆里的自动售货机,还卖热饮咖啡,困了就会过来烧钱。。。

    Foto0411

    高峰时期箱子都上锁了,认真的人挺多。

    Foto0412

    图书馆的Reading Room,置身其中仿佛有种归属感。

    Foto0395

    回家已是入夜,看见白天安静的电子楼在开Party……

    Foto0396

     

    (照片不是一天之内照的,有组合,以后有机会还会添加……)

    December 11

    执着

          现在是凌晨一点了。好容易把明天演讲的东西都弄完,呆坐着看着时间一分一秒在流逝。

          下午跟Betreuer见了演讲前最后一面,我告诉他,我发现发给我的参考资料上有个大错误,直接会影响结果。他看了也很无奈。但是要算出正确答案,看起来还真不是几个小时能搞定的。我问他教授有没有看过这个算法?他说没。我说那就把式子写对,结果还是照抄原来的就好了。正当我自鸣得意的时候,Betreuer却大揺其头。他说不行不行,发现错误是件好事,实在不行就说时间不够了来不及算出正确答案,但是那篇论文中的错误一定要说出来。

          突然觉得好惭愧……当我不知觉中把学习当成任务的时候,当我把付出努力的最终目标视作一个分数的时候,当我为了这个数字符号甚至变得都有点不择手段的时候,德国人是怎么做的?回首在国内读大学的时候,越来越会算计怎么去跟老师套近乎好让老师透题,算计哪门课权重高好好考试拉学分,然后,最后,算计奖学金……学习变成了纯功利性的追逐……如果我在国内演讲,绝对不可能会冒着“虽然发现错了,可是我也不知道正确答案是什么”导致拿不到好分的风险而去拆穿资料中证明的错误。可是这里的Betreuer不让我这么做。

          只见他抓起笔来就在纸上抓狂似的算……式子又套式子的递归方程组,我还真是不知道究竟该从何下笔。

          随后我去上另一门课,可是我那Betreuer的话总是在脑海里萦回,上完课回家我也抓起笔来狂算,用了十几组数据终于推导出规律,解出了递归方程组。幸好,虽然资料里的中间步骤错了,但结果并不影响结论。打开邮件,Betreuer在我上课的时候就把他自己算的结果发给了我,对照我自己的一看,果然没错。

          治学严谨、对真理执着的追求,我不想用“迂腐”来形容他们,这正是中国人所欠缺的。