~f0ma/cuneiform-linux/devel

« back to all changes in this revision

Viewing changes to cuneiform_src/cli/cuneiform-xcli.cpp

  • Committer: Stanislav Ivanov
  • Date: 2017-06-07 15:03:51 UTC
  • Revision ID: ivstdm@gmail.com-20170607150351-dlzbzl54zvs57z57
New command line interface with multipage support and input image filtering.
Alpha state. No checks for build in other platform. Tests is missing.
Magick++ and C++0x is requried.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "ocelot.h"
 
2
#include <glob.h>
 
3
 
 
4
class simpleArgParser {
 
5
    
 
6
    vector <string> shortkeys;
 
7
    vector <string> longkeys;
 
8
    vector <bool> flags;
 
9
    
 
10
    vector <string> vflags;
 
11
    map <string,string> values;
 
12
    vector <string> vfreeargs;
 
13
 
 
14
public:
 
15
    void addFlag(string longform, string shortform = "") {
 
16
        longkeys.push_back(longform);
 
17
        shortkeys.push_back(shortform);
 
18
        flags.push_back(true);
 
19
    }
 
20
    
 
21
    void addKey(string longform, string shortform = "") {
 
22
        longkeys.push_back(longform);
 
23
        shortkeys.push_back(shortform);
 
24
        flags.push_back(false);
 
25
    }
 
26
 
 
27
    bool parse(int argc, char **argv){
 
28
        
 
29
        for(int i=1; i<argc; i++){
 
30
            
 
31
            bool parsed = false;
 
32
        
 
33
            auto sk = shortkeys.begin();
 
34
            auto lk = longkeys.begin();
 
35
            auto fk = flags.begin();
 
36
            
 
37
            for (;sk<shortkeys.end();){
 
38
                
 
39
                    if ((*fk) && (((*lk) == argv[i]) || ((*sk) == argv[i]))){
 
40
                        vflags.push_back((*lk));
 
41
                        parsed = true;
 
42
#ifdef _DEBUG
 
43
                        printf("Flag: %s\n",argv[i]);
 
44
#endif
 
45
                        break;
 
46
                      }
 
47
 
 
48
                    if (!(*fk) && (((*lk) == argv[i]) || ((*sk) == argv[i]))){
 
49
                        if (i+1 >= argc)
 
50
                            return false;
 
51
                        values[*lk] = argv[i+1];
 
52
                        parsed = true;
 
53
#ifdef _DEBUG
 
54
                        printf("Value: %s %s\n",lk->c_str(),values[*lk].c_str());
 
55
#endif
 
56
                        i++;
 
57
                        break;
 
58
                      }
 
59
                      
 
60
                    sk++;
 
61
                    lk++;
 
62
                    fk++;
 
63
                    
 
64
               }
 
65
            
 
66
            if (!parsed){
 
67
#ifdef _DEBUG
 
68
                printf("Free arg: %s\n",argv[i]);
 
69
#endif
 
70
                glob_t globbuf;
 
71
                if(glob(argv[i], 0, NULL, &globbuf) == 0){
 
72
                
 
73
                    for (size_t gi = 0; gi < globbuf.gl_pathc; gi++) {
 
74
#ifdef _DEBUG
 
75
                        printf("Glob resolver: %s\n",globbuf.gl_pathv[gi]);
 
76
#endif
 
77
                        vfreeargs.push_back(globbuf.gl_pathv[gi]);
 
78
                    }
 
79
                    globfree(&globbuf);
 
80
                } else {
 
81
                    cerr << "File not found: " << argv[i] << endl;
 
82
                }
 
83
                
 
84
            }
 
85
        }
 
86
    
 
87
        return true;
 
88
    }
 
89
    
 
90
    bool flag (string longform) {
 
91
        return find(vflags.begin(), vflags.end(), longform) != vflags.end();
 
92
    }
 
93
    
 
94
    string value (string longform, string defval) {
 
95
        if (values.count(longform) > 0) {
 
96
            return values[longform];
 
97
        }
 
98
        return defval;
 
99
    }
 
100
    
 
101
    vector <string> freeargs () {
 
102
        return vfreeargs;
 
103
    }
 
104
};
 
105
 
 
106
int main(int argc, char **argv) {
 
107
    
 
108
    simpleArgParser parser;
 
109
    
 
110
    parser.addFlag("--help", "-h");
 
111
    
 
112
    parser.addKey("--language", "-l");
 
113
    parser.addKey("--format", "-f");
 
114
    parser.addKey("--output", "-o");
 
115
    parser.addKey("--dpi", "-d");
 
116
    parser.addKey("--verbose", "-v");
 
117
    parser.addKey("--filter-leveler", "-flv");
 
118
    parser.addKey("--filter-bsh", "-fbsh");
 
119
    
 
120
    parser.addKey("--dump-image");
 
121
//    parser.addKey("--dump-layout");
 
122
//    parser.addKey("--dump-lines");
 
123
 
 
124
    
 
125
    parser.addKey("--datafiles");
 
126
    
 
127
    parser.addFlag("--dotmatrix");
 
128
    parser.addFlag("--fax");
 
129
    parser.addFlag("--singlecolumn");
 
130
    parser.addFlag("--no-multipage");
 
131
    
 
132
    if (!parser.parse(argc,argv) || parser.flag("--help") || parser.freeargs().size() == 0){
 
133
        cout << "Cuneiform command line interface " << CF_VERSION << "\n";
 
134
 
 
135
        cout << "Usage: " << argv[0] << " [options] imagefile [imagefile ...]\n";
 
136
        cout << "Options: \n";
 
137
        cout << "-h / --help\t\tShow this message\n";
 
138
        cout << "-l / --language\tSet regonition language\n";
 
139
        cout << "--show-langs\tShow regonition languages list\n";
 
140
        cout << "-f / --format\tSet output file format (text, smarttext, hocr, html)\n";
 
141
        cout << "-o / --output\t\tOutput file name\n";
 
142
        cout << "-d / --dpi\t\tInput file dpi\n";
 
143
        cout << "-v / --verbose\t\tShow recognition details\n";
 
144
        cout << "--datafiles\t\tSet path to Cuneiform DataFiles\n";
 
145
        cout << "--dotmatrix\t\tВetter regonition for matrix printer images\n";
 
146
        cout << "--fax\t\tBetter regonition for fax images\n";
 
147
        cout << "--singlecolumn\t\tDisable columns search\n";
 
148
        cout << "--no-multipage\t\tPrevent to load multipage image\n";
 
149
        
 
150
        return 0;
 
151
    }
 
152
    
 
153
    Ocelot ocelot;
 
154
    
 
155
    bool isok = true;
 
156
    
 
157
    isok = ocelot.setDataPath(parser.value("--datafiles",INSTALL_DATADIR));
 
158
    
 
159
    if(!isok){
 
160
        cout <<"Cuneiform DataFiles not found!" << endl;
 
161
        cout <<"Path: "<< parser.value("--datafiles",INSTALL_DATADIR) << endl;
 
162
        return -10;
 
163
    }
 
164
    
 
165
    isok = ocelot.setLanguage(parser.value("--language","eng"));
 
166
    
 
167
    if(!isok){
 
168
        cout <<"Unknown language code!" << endl;
 
169
        return -11;
 
170
    }
 
171
    
 
172
    isok = ocelot.setOutputFormat(parser.value("--format","smarttext"));
 
173
    
 
174
    if(!isok){
 
175
        cout <<"Unknown output format!" << endl;
 
176
        return -11;        
 
177
    }
 
178
    
 
179
    ocelot.setDensity(parser.value("--dpi","300"));
 
180
    ocelot.setOutputFileName(parser.value("--output","cuneiform-out.txt"));
 
181
    
 
182
    if(parser.flag("--dotmatrix"))
 
183
        ocelot.setDotMatrixMode();
 
184
    
 
185
    if(parser.flag("--fax"))
 
186
        ocelot.setFaxMode();
 
187
    
 
188
    if(parser.flag("--singlecolumn"))
 
189
        ocelot.setOneColumn();
 
190
    
 
191
    vector <string> infiles = parser.freeargs();
 
192
    
 
193
    for(auto i = infiles.begin(); i<infiles.end(); i++){
 
194
        ocelot.addPages(*i, !parser.flag("--no-multipage"));
 
195
    }
 
196
    
 
197
    ocelot.startPuma();
 
198
 
 
199
    for (uint i=0; i<ocelot.pageCount(); i++){
 
200
    
 
201
        ocelot.setCurrentPage(i);
 
202
        
 
203
        if(parser.value("--filter-leveler","")!=""){
 
204
            ocelot.filterLeveler(stoi(parser.value("--filter-leveler","30")));
 
205
        }
 
206
 
 
207
        if(parser.value("--filter-bsh","")!=""){
 
208
            ocelot.filterBSH(stoi(parser.value("--filter-leveler","2")));
 
209
        }
 
210
        
 
211
        if(parser.value("--dump-image","")!=""){
 
212
            ocelot.filterSaveImage(parser.value("--dump-image","filtred.jpg"));
 
213
        }
 
214
        
 
215
        ocelot.loadRaster();
 
216
        ocelot.layoutPage();
 
217
 
 
218
        if(parser.flag("--verbose")) {
 
219
            vector<OcelotBlock> blks = ocelot.getBlockInfo();
 
220
        
 
221
            for (auto i = blks.begin(); i<blks.end(); i++){
 
222
                printf("Block: %s: %d,%d %d,%d\n",
 
223
                       i->typeName().c_str(),
 
224
                       i->x(),
 
225
                       i->y(),
 
226
                       i->w(),
 
227
                       i->h());
 
228
            }
 
229
        }
 
230
        
 
231
        ocelot.recognizePage();
 
232
        
 
233
        if(parser.flag("--verbose")) {
 
234
            vector<OcelotLine> lns = ocelot.getRecognizedLines();
 
235
    
 
236
            for (auto i = lns.begin(); i<lns.end(); i++){
 
237
                printf("Line: %d,%d : %d\n",
 
238
                       i->x(),
 
239
                       i->y(),
 
240
                       i->getUserTag());
 
241
                
 
242
                for (auto j = i->symbols.begin(); j<i->symbols.end(); j++){
 
243
                printf("%s",j->text().c_str());
 
244
                    
 
245
                }
 
246
                printf("\n");
 
247
                
 
248
            }
 
249
        }
 
250
        
 
251
        ocelot.savePage();
 
252
        ocelot.freeRaster();
 
253
        
 
254
    }
 
255
    
 
256
    return 0;
 
257
}