00001 #ifndef __CMV_THRESHOLD_H__
00002 #define __CMV_THRESHOLD_H__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <stdio.h>
00018 #include "cmv_types.h"
00019
00020 namespace CMVision{
00021
00022 template<int x,int y,int z>
00023 class DummyI3 {
00024 };
00025
00026 template<class T,int x,int y,int z>
00027 class DummyT1I3 {
00028 };
00029
00030 template <class cmap_t,class image,int bits_y,int bits_u,int bits_v>
00031 void ThresholdImage(cmap_t *cmap,image &img,cmap_t *tmap,DummyI3<bits_y,bits_u,bits_v> dummy=DummyI3<bits_y,bits_u,bits_v>())
00032 {
00033
00034 uyvy *buf,p;
00035 int i,m,size;
00036
00037 int rshift_y,rshift_u,rshift_v;
00038 int lshift_y,lshift_u,lshift_v;
00039
00040 rshift_y = 8 - bits_y;
00041 rshift_u = 8 - bits_u;
00042 rshift_v = 8 - bits_v;
00043
00044 lshift_y = bits_u + bits_v;
00045 lshift_u = bits_v;
00046 lshift_v = 0;
00047
00048 size = img.width * img.height;
00049 buf = img.buf;
00050
00051 for(i=0; i<size; i++){
00052 p = buf[i / 2];
00053 m = ((p.u >> rshift_u) << lshift_u) +
00054 ((p.v >> rshift_v) << lshift_v);
00055 cmap[i + 0] = tmap[m + ((p.y1 >> rshift_y) << lshift_y)];
00056 cmap[i + 1] = tmap[m + ((p.y1 >> rshift_y) << lshift_y)];
00057 }
00058 }
00059
00060 template <class cmap_t,class image>
00061 void ThresholdImageRGB16(cmap_t *cmap,image &img,cmap_t *tmap)
00062 {
00063 unsigned short *buf;
00064 int i,size;
00065
00066 size = img.width * img.height;
00067 buf = (unsigned short*)img.buf;
00068
00069 for(i=0; i<size; i++){
00070 cmap[i] = tmap[buf[i]];
00071 }
00072 }
00073
00074
00075 template <class cmap_t,class image,class element,int bits_y,int bits_u,int bits_v>
00076 void ThresholdImageYUVPlanar(cmap_t *cmap,image &img,cmap_t *tmap)
00077 {
00078
00079
00080
00081 int row,col;
00082 int width,height;
00083 int py,pu,pv;
00084 int tmap_idx;
00085 #ifdef CALC_AVG_IMG_COLOR
00086 ulong total_y;
00087 ulong total_u;
00088 ulong total_v;
00089 #endif
00090
00091 int rshift_y,rshift_u,rshift_v;
00092 int lshift_y,lshift_u,lshift_v;
00093
00094 element *row_y,*row_u,*row_v;
00095 cmap_t *row_cmap;
00096
00097 rshift_y = 8 - bits_y;
00098 rshift_u = 8 - bits_u;
00099 rshift_v = 8 - bits_v;
00100
00101 lshift_y = bits_u + bits_v;
00102 lshift_u = bits_v;
00103 lshift_v = 0;
00104
00105 width = img.width;
00106 height = img.height;
00107 #ifdef CALC_AVG_IMG_COLOR
00108 total_y = 0;
00109 total_u = 0;
00110 total_v = 0;
00111 #endif
00112
00113 for(row=0; row<height; row++) {
00114 row_y = img.buf_y + row*img.row_stride;
00115 row_u = img.buf_u + row*img.row_stride;
00116 row_v = img.buf_v + row*img.row_stride;
00117 row_cmap = cmap + row*width;
00118
00119 int rowidx=0;
00120 for(col=0; col<width; col++) {
00121 py = row_y[rowidx] >> rshift_y;
00122 pu = row_u[rowidx] >> rshift_u;
00123 pv = row_v[rowidx] >> rshift_v;
00124 tmap_idx =
00125 (py << lshift_y) +
00126 (pu << lshift_u) +
00127 (pv << lshift_v);
00128 row_cmap[col] = tmap[tmap_idx];
00129 #ifdef CALC_AVG_IMG_COLOR
00130 total_y += row_y[rowidx];
00131 total_u += row_u[rowidx];
00132 total_v += row_v[rowidx];
00133 #endif
00134
00135
00136
00137
00138
00139
00140 rowidx+=img.col_stride;
00141 }
00142 }
00143
00144 }
00145
00146
00147
00148 template <class rle_t,class color_class_state_t>
00149 void RmapToRgb(rgb *img,rle_t *map,int last_run,int width,int height,
00150 color_class_state_t *color,int num)
00151 {
00152 int i,x,y=0,next_x;
00153
00154 i=0;
00155 next_x=0;
00156 #ifdef ENABLE_JOIN_NEARBY
00157 i=AdvanceToNextRun(i,map);
00158 #endif
00159 while(i < last_run) {
00160 rle_t *currun;
00161 currun = &map[i];
00162
00163 y=currun->y;
00164 if(y>=height) {
00165 return;
00166 }
00167
00168 x=currun->x;
00169 if(x<next_x) {
00170 return;
00171 }
00172
00173 if(x!=next_x) {
00174 for(x=next_x; x<currun->x; x++)
00175 img[y*width + x] = color[0].color;
00176 }
00177
00178 next_x = currun->x+currun->width;
00179 for(x=currun->x; x<next_x; x++)
00180 img[y*width + x] = color[currun->color].color;
00181
00182 if(next_x == width) {
00183 y++;
00184 next_x = 0;
00185 }
00186
00187 i=i+1;
00188 }
00189 for(x=next_x; x<width; x++)
00190 img[y*width + x] = color[0].color;
00191 }
00192
00193 template <class cmap_t>
00194 void RgbToIndex(cmap_t *map,rgb *img,int width,int height,
00195 rgb *colors,int num)
00196 {
00197 int i,j,size;
00198
00199 size = width * height;
00200
00201 j = 0;
00202 for(i=0; i<size; i++){
00203 if(img[i] != colors[j]){
00204 j = 0;
00205 while(j<num && img[i]!=colors[j]) j++;
00206 if(j==num)
00207 j = 0;
00208 }
00209 map[i] = j;
00210 }
00211 }
00212
00213 template <class cmap_t,class color_class_state_t>
00214 void IndexToRgb(rgb *img,cmap_t *map,int width,int height,
00215 color_class_state_t *color,int num)
00216 {
00217 int i,size;
00218
00219 size = width * height;
00220
00221 for(i=0; i<size; i++){
00222 img[i] = color[map[i]].color;
00223 }
00224 }
00225
00226 template <class cmap_t>
00227 void IndexToRgb(rgb *img,cmap_t *map,int width,int height,
00228 rgb *colors,int num)
00229 {
00230 int i,size;
00231
00232 size = width * height;
00233
00234 for(i=0; i<size; i++){
00235 img[i] = colors[map[i]];
00236 }
00237 }
00238
00239 template <class data>
00240 data Get3D(data *arr,int num_i,int num_j,int num_k,int i,int j,int k)
00241 {
00242 int l;
00243 l = i*num_j*num_k + j*num_k + k;
00244 return(arr[l]);
00245 }
00246
00247 template <class data>
00248 void Set3D(data *arr,int num_i,int num_j,int num_k,int i,int j,int k,data v)
00249 {
00250 int l;
00251 l = i*num_j*num_k + j*num_k + k;
00252 arr[l] = v;
00253 }
00254
00255 template <class tmap_t>
00256 int RemapTMapColor(tmap_t *tmap,int num_y,int num_u,int num_v,int src_id,int dest_id)
00257 {
00258 int i,n,size;
00259
00260 size = num_y * num_u * num_v;
00261 n = 0;
00262
00263 for(i=0; i<size; i++){
00264 if(tmap[i] == src_id){
00265 tmap[i] = dest_id;
00266 n++;
00267 }
00268 }
00269
00270 return(n);
00271 }
00272
00273 template <class tmap_t>
00274 int CheckTMapColors(tmap_t *tmap,int num_y,int num_u,int num_v,int colors,int default_id)
00275 {
00276 int i,n,size;
00277
00278 size = num_y * num_u * num_v;
00279 n = 0;
00280
00281 for(i=0; i<size; i++){
00282 if(tmap[i] >= colors){
00283 tmap[i] = default_id;
00284 n++;
00285 }
00286 }
00287
00288 return(n);
00289 }
00290
00291 template <class tmap_t>
00292 bool LoadThresholdFile(tmap_t *tmap,int num_y,int num_u,int num_v,const char *filename)
00293 {
00294 FILE *in;
00295 char buf[256];
00296 int ny,nu,nv;
00297
00298 int size,read;
00299 bool invertUV;
00300
00301 in = fopen(filename,"r");
00302 if(!in) return(false);
00303
00304
00305 if(!fgets(buf,256,in)) goto error;
00306 buf[4] = 0;
00307 if(strcmp(buf,"TMAP")) goto error;
00308
00309
00310 if(!fgets(buf,256,in)) goto error;
00311 if(strcmp(buf,"YUV8\n")==0)
00312 invertUV=true;
00313 else if(strcmp(buf,"YUV'8\n")==0)
00314 invertUV=false;
00315 else goto error;
00316
00317
00318 if(!fgets(buf,256,in)) goto error;
00319 ny = nu = nv = 0;
00320 sscanf(buf,"%d %d %d",&ny,&nu,&nv);
00321 if(invertUV) {
00322 if(num_y!=ny || num_u!=nv || num_v!=nu) goto error;
00323 } else {
00324 if(num_y!=ny || num_u!=nu || num_v!=nv) goto error;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333 size = num_y * num_u * num_v;
00334 if(!invertUV) {
00335 read = fread(tmap,sizeof(tmap_t),size,in);
00336 } else {
00337 read=0;
00338 for(int yi=0; yi<num_y; yi++) {
00339 for(int vi=0; vi<num_v; vi++) {
00340 for(int ui=0; ui<num_u; ui++) {
00341 if(fread(tmap+ui*num_v+vi,sizeof(tmap_t),1,in)!=1) goto error;
00342 }
00343 }
00344 tmap+=num_u*num_v;
00345 read+=num_u*num_v;
00346 }
00347 }
00348
00349 fclose(in);
00350
00351 return(read == size);
00352 error:
00353 if(in) fclose(in);
00354 return(false);
00355 }
00356
00357 template <class tmap_t>
00358 bool SaveThresholdFile(tmap_t *tmap,int num_y,int num_u,int num_v,char *filename)
00359 {
00360 FILE *out;
00361 int size,wrote;
00362
00363 out = fopen(filename,"w");
00364 if(!out) return(false);
00365
00366 fprintf(out,"TMAP\nYUV%d\n%d %d %d\n",
00367 sizeof(tmap_t),num_y,num_u,num_v);
00368 size = num_y * num_u * num_v;
00369 wrote = fwrite(tmap,sizeof(tmap_t),size,out);
00370 fclose(out);
00371
00372 return(wrote == size);
00373 }
00374
00375 }
00376
00377 #endif