Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

cmv_threshold.h

Go to the documentation of this file.
00001 #ifndef __CMV_THRESHOLD_H__
00002 #define __CMV_THRESHOLD_H__
00003 
00004 /*! @file
00005 * @brief Color threshold support for #CMVision
00006 * @author James R. Bruce, School of Computer Science, Carnegie Mellon University
00007 *
00008 * Licensed under the <a href="../gpl-2.0.txt">GNU GPL version 2</a>
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   // yuyv *buf,p;
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 //void ThresholdImageYUVPlanar(cmap_t *cmap,image &img,cmap_t *tmap,DummyT1I3<element,bits_y,bits_u,bits_v> dummy=DummyT1I3<element,bits_y,bits_u,bits_v>())
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   //int nonzero_cnt=0;
00073 
00074   // element *buf_y,*buf_u,*buf_v;
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       if(row==height/2 && col==width/2) {
00131         printf("py=%u pu=%u pv=%u tmap_idx=%d tmap val=%u\n",py,pu,pv,tmap_idx,tmap[tmap_idx]);
00132       }
00133       */
00134       rowidx+=img.col_stride;
00135     }
00136   }
00137 
00138 }
00139 
00140 //#define ENABLE_JOIN_NEARBY
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;//AdvanceToNextRun(i,map);
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 //  int by,bu,bv;
00292   int size,read;
00293   bool invertUV;
00294 
00295   in = fopen(filename,"r");
00296   if(!in) return(false);
00297 
00298   // read magic
00299   if(!fgets(buf,256,in)) goto error;
00300   buf[4] = 0;
00301   if(strcmp(buf,"TMAP")) goto error;
00302 
00303   // read type
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   // read size
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   /*//for(by=1; (num_y>>by)!=0; by++) {}
00321   for(bu=1; (num_u>>bu)!=0; bu++) {}
00322   for(bv=1; (num_v>>bv)!=0; bv++) {}
00323   by=bu+bv;
00324   bu=bv;
00325   bv=0;*/
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 } // namespace
00370 
00371 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:37 2016 by Doxygen 1.6.3