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