ImageProcessor.cpp

Go to the documentation of this file.
00001 // ImageProcessor.cpp: implementation of the ImageProcessor class.
00002 //
00004 
00005 #include "stdafx.h"
00006 //#include "legoproject.h"
00007 
00008 #include "resource.h"
00009 #include "legoprojectDlg.h"
00010 
00011 //#include "CVIPtoolsInc.h"
00012 #include "ImageProcessor.h"
00013 
00014 #include "defines.h"
00015 
00016 
00017 #ifdef _DEBUG
00018 #undef THIS_FILE
00019 static char THIS_FILE[]=__FILE__;
00020 #define new DEBUG_NEW
00021 #endif
00022 
00023 
00024 //#include "rover_pc.h" // this may NOT be include in a MFC class (only generic classes)
00025                        // otherwise message map wil give compile errors
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 #define WINAPI __stdcall
00055 
00056 int myview =0;
00057 
00058 //const WM_TAKEPICT= WM_USER + 100;
00059 
00061 // Construction/Destruction
00063 
00064 
00065 
00066 
00067 
00068 //extern CLegoprojectDlg *dlg;
00069 
00070 
00071 
00072 int iImageCount=0;
00073 char szNameFormat[100];
00074 char szFileName[100];
00075 
00076 ImageProcessor::ImageProcessor()
00077 {
00078  
00079 
00080 }
00081 
00082 ImageProcessor::~ImageProcessor()
00083 {
00084 
00085 }
00086 
00087 
00088 
00089 Image *ImageProcessor::dib2cvip(CImage  *dib)
00090 {
00091         int rows=(int)dib->m_pbi->biHeight;
00092         int cols=(int)dib->m_pbi->biWidth;
00093         byte *pixels=(BYTE *)dib->m_lpbits;
00094 
00095     Image *cvipImage = NULL;
00096     //LPVOID result;
00097         int r, c, b;
00098         byte **image;
00099         byte *p;
00100  
00101         cvipImage = new_Image(PPM,RGB,3,rows,cols,CVIP_BYTE,REAL);
00102 
00103         for(b=0; b< 3; b++) 
00104         {
00105                 image = (byte **)getData_Image(cvipImage,b);
00106                 p=(byte *)pixels;
00107                 for(r=rows-1;r>=0;r--)
00108                         for(c=0;c<cols;c++) 
00109                         {//scanline alligment!!
00110                         // p[0] is Blue , p[1] is Green, p[2] is Red
00111                                 image[r][c]=(byte)p[2-b]; //BGR in BMP
00112                                 p +=3;
00113                         }
00114         }
00115 //      result = (void *)cvipImage;
00116   //  return result;
00117     return cvipImage;
00118 }
00119 
00120 void ImageProcessor::cvip2dib(CImage  *dib, Image *cvipImage)
00121 {
00122   int rows=(int)dib->m_pbi->biHeight;
00123   int cols=(int)dib->m_pbi->biWidth;
00124   byte *pixels=(BYTE *)dib->m_lpbits;
00125 
00126  // Image *cvipImage = NULL;
00127  // Image *cvipImage_unmapped = NULL;
00128  // cvipImage_unmapped= (Image*) cvipImageVoid;
00129   
00130  // byte conversie naar standaard byte formaat used by CImage 
00131  cvipImage=remap_Image(cvipImage,CVIP_BYTE, 0, 255);
00132  //delete_Image(cvipImage_unmapped); 
00133  
00134  int r, c, b;
00135  byte **imagetwee;
00136  byte *p;
00137 
00138  
00139  for(b=0; b< getNoOfBands_Image(cvipImage); b++) {
00140    imagetwee = (byte **)getData_Image(cvipImage,b);
00141    p=(byte *)pixels;
00142    for(r=rows-1;r>=0;r--)for(c=0;c<cols;c++) {//scanline alligment!!
00143    //  p[2-b]=200;
00144               p[2-b]= imagetwee[r][c];
00145      p += 3;
00146    }
00147  }
00148  
00149  delete_Image(cvipImage);
00150 }
00151 
00152 
00153 // CVIP image
00154 //  3 separate matrices (RGB order), one for each color
00155 
00156 // DIB/VIS image
00157 //   1 matrix with pixel structures, a pixel is in BGRA order 
00158 //   (A reserved for future)
00159 
00160 // => walk through DIB/VIS matrix filling the three separate CVIP color matrices
00161 
00162 void ImageProcessor::vis2cvip(Image *cvipImage, CImage  *vis)
00163 {
00164     // incoming CVIP Image
00165     //Image *cvipImage = (Image *) cvipImageVoid;
00166 
00167     // incoming VIS Image
00168         int rows=vis->visimage.Height();
00169         int cols=vis->visimage.Width();
00170         byte *pixels=(BYTE *)vis->visimage.RowPointer(0);
00171 
00172 
00173     // work variables
00174         int r, c, b;
00175 
00176         byte *p;
00177     
00178      byte **image[3];
00179     // let image reference the three color bands (RGB) of the CVIP image
00180         for(b=0; b< 3; b++) 
00181         {
00182                 image[b] = (byte **)getData_Image(cvipImage,b);
00183     }
00184 
00185                 p=(byte *)pixels;
00186         // loop in reverse way through rows 
00187         //    DIB has bottom row first in memory  (DOWN-TOP)
00188         //    CVIP has it the other way around    (TOP-DOWN) 
00189         //    VIS has the same as CVIP            (TOP-DOWN)
00190                 //for(r=rows-1;r>=0;r--)
00191         for(r=0;r<rows;r++)
00192         {   
00193             // loop through columns
00194                         for(c=0;c<cols;c++) 
00195             { 
00196                 // loop through color bands RGB
00197                     for(b=0; b< 3; b++) 
00198                 {
00199                    
00200                                // p[0] is Blue , p[1] is Green, p[2] is Red
00201                                    image[b][r][c]=(byte)p[2-b]; //BGR in BMP
00202                                    //p +=3;
00203                    //p++;
00204                    //if (b > 0 ) { image[b][r][c]=0; }
00205                 }
00206                 p+=4;
00207             }
00208          }
00209   
00210 }
00211 
00212 
00213 void ImageProcessor::cvip2vis(CImage  *vis, Image *cvipImage)
00214 {
00215     // incoming CVIP Image
00216   //  Image *cvipImage = (Image *) cvipImageVoid;
00217         int rows=getNoOfRows_Image(cvipImage);
00218         int cols=getNoOfCols_Image(cvipImage);
00219     int bands=getNoOfBands_Image(cvipImage);
00220     // incoming VIS Image
00221     if (! vis->visimage.IsValid()) {
00222         vis->visimage.Allocate(cols,rows);
00223     }
00224         //int rows=vis->visimage.Height();
00225         //int cols=vis->visimage.Width();
00226         byte *pixels=(BYTE *)vis->visimage.RowPointer(0);
00227     // byte *pixels=vis->visimage.PbPixel(vis->visimage.StartPoint(), 0);
00228    // byte *pixels=(BYTE *)(vis->visimage.MemBlock()->PbData);
00229 
00230   
00231 
00232     // work variables
00233         int r, c, b;
00234 
00235         byte *p;
00236     
00237 
00238     byte **image[3];
00239     // let image reference the three color bands (RGB) of the CVIP image
00240         for(b=0; b< bands; b++) 
00241         {
00242                 image[b] = (byte **)getData_Image(cvipImage,b);
00243     }
00244 
00245                 p=(byte *)pixels;
00246         // loop in reverse way through rows 
00247         //    DIB has bottom row first in memory  (DOWN-TOP)
00248         //    CVIP has it the other way around    (TOP-DOWN) 
00249         //    VIS has the same as CVIP            (TOP-DOWN)
00250                 //for(r=rows-1;r>=0;r--)
00251         for(r=0;r<rows;r++)
00252         {   
00253             // loop through columns
00254                         for(c=0;c<cols;c++) 
00255             { 
00256                 // loop through color bands RGB
00257                     for(b=0; b< bands; b++) 
00258                 {
00259                    
00260                                // p[0] is Blue , p[1] is Green, p[2] is Red
00261                                    //image[b][r][c]=(byte)p[2-b]; //BGR in BMP
00262                    p[2-b]=(unsigned char) image[b][r][c]; //BGR in BMP
00263                                    //p +=3;
00264                    //p++;
00265                    //if (b > 0 ) { image[b][r][c]=0; }
00266                 }
00267                 p+=4;
00268             }
00269          }
00270   
00271        
00272 }
00273 
00274 
00275 
00276 // IMAGE PROCESSING ALGORITHM
00277 //
00278 // this algorithm is executed in thread or by single un
00279 //
00281 //
00282 // howto use alternative viewer   
00283 // view_Image(cvipImage,"view_image");
00284 //
00285 // howto write/read input image to/from file
00286 // IMAGE_FORMAT format=PPM;
00287 // char sFile[]="c:\\TEMP\\temp.ppm";
00288 // inputImage=read_Image(sFile,CVIP_NO); 
00289 //
00290 // how to free an image
00291 // delete_Image(inputImage);
00292 Image  *ImageProcessor::MyAlgorithm(Image *cvipImage)
00293 {     
00294     // to let the log_Image function work
00295     // if this is not wanted (for speed) comment out the next line
00296 
00297 #define  LOGIMAGE 
00298 
00299          
00300     // VIEWER is defined in CVIP.h 
00301     (void) setDisplay_Image(VIEWER, "Default");
00302     
00303     iImageCount=0;
00304 
00305     char *logpath= get_log_path();
00306     delete_old_logimages(logpath);  
00307         delete logpath;
00308 
00309 
00310      // pgm -> gray, or ppm -> color file
00311     
00312     List <Entity> objectlist;
00313     Image *tmp1,*tmp2,*blue_comp,*red_comp,*green_comp;
00314     tmp1 = duplicate_Image(cvipImage);
00315 //    tmp2 = duplicate_Image(cvipImage);
00316     blue_comp=find_color_objects(cvipImage,LEGO_BLUE,&objectlist);
00317     //delete_Image(blue_comp);
00318     red_comp=find_color_objects(tmp1,LEGO_RED,&objectlist);
00319     //delete_Image(red_comp);
00320 
00321         blue_comp=add_Image(blue_comp,red_comp);
00322         log_Image(blue_comp,"_all_objects");
00323 
00324  //   green_comp=find_color_objects(tmp2,LEGO_GREEN,&objectlist);
00325  //   delete_Image(green_comp);
00326     
00327     print_entities(&objectlist);
00328         send_entities(&objectlist);
00329    
00330     //Sleep(500)
00331     return blue_comp;
00332 }
00333 
00334 
00335 void print_entities(List <Entity> *objectlist) 
00336 {
00337     List <Entity>::iterator i;
00338     int color,type,x,y,angle;
00339     myprintf("--------");
00340     for ( i= objectlist->begin(); i != objectlist->end(); ++i )
00341     { 
00342         color=(*i).getColor();
00343         x=(*i).getX();
00344         y=(*i).getY();
00345         type=(*i).getType();
00346         if ( type == Entity::ROBOT ) {
00347             angle=(*i).getAngle();
00348             myprintf("robot \r\n %d,%d,%d,%d",x,y,angle,color);
00349         } 
00350         if ( type == Entity::SUBJECT ) {
00351             myprintf("subject \r\n %d,%d,%d",x,y,color);
00352         }
00353         if ( type == Entity::GOAL ) {
00354             myprintf("goal \r\n %d,%d,%d",x,y,color);
00355         }        
00356     }
00357 
00358 }
00359 
00360 void send_entities(List <Entity> *objectlist) 
00361 {
00362     List <Entity>::iterator i;
00363     short color,type,x,y,angle;
00364     myprintf("--------");
00365     for ( i= objectlist->begin(); i != objectlist->end(); ++i )
00366     { 
00367         color=(*i).getColor();
00368         x=(*i).getX();
00369         y=(*i).getY();
00370         type=(*i).getType();
00371 
00372         packetx *cmd_pack; 
00373                 cmd_pack=new packetx(sizeof(color)+sizeof(type)+sizeof(x)+sizeof(y)+sizeof(angle));
00374                 cmd_pack->set_pack_mode();
00375                 cmd_pack->process(color);
00376                 cmd_pack->process(type);
00377                 cmd_pack->process(x);
00378                 cmd_pack->process(y);
00379 
00380 
00381         if ( type == Entity::ROBOT ) {
00382             angle=(*i).getAngle();
00383                         cmd_pack->process(angle);
00384             cmd_pack->send(ADDR_RCX,PORT_PC);
00385         } 
00386 
00387         if ( (type == Entity::SUBJECT ) || (type == Entity::GOAL) ) {
00388             cmd_pack->send(ADDR_RCX,PORT_PC);
00389         }
00390                 
00391                 delete(cmd_pack);
00392     }
00393 
00394 }
00395 
00396 
00397 // per color
00398 Image *find_color_objects(Image *inputimage, int color ,
00399                                List <Entity> *objectlist ) 
00400 {
00401      int row,col,angle,label,center_row,center_col,ret;
00402      long objectarea;
00403      int *ctr;
00404      Image *component_img;
00405      Image *labeled_img;
00406      Entity object;
00407 
00408     // get color objects in labeled image
00409      component_img=get_component(inputimage, color);
00410    
00411     // label objects ( connented values not null)
00412      if ( !get_first_non_null_point(component_img,&row,&col) ) {
00413                 myprintf("first label : EMPTY IMG ");
00414         return false;
00415         }
00416     Image *temp = duplicate_Image(component_img); 
00417     labeled_img = ::label(temp);
00418 
00419 
00420     object.setColor((Entity::Color)color);
00421 
00422     // per object
00423     // 1. find first coordinates row col of a object with label  'label'
00424     //    start with first label=1
00425     label=1;
00426     row=col=0;
00427     //get_first_non_null_point(labeled_image, &row,&col);
00428             // find labeled object with label higher than 'label'
00429     while ( find_labeled_object(labeled_img,row,col,label) ) {
00430        //myprintf("label,pos: %d %d %d  ", label,row ,col);
00431         
00432        // 2. determine area a --> obj_type  
00433        objectarea=area(labeled_img,row,col);
00434        //myprintf("area : %d",objectarea);
00435         
00436        // 3. find center coordinates 
00437        if  ( (SUBJECT_MINAREA < objectarea) && (objectarea <= GOAL_MAXAREA ) ) {
00438            // find center
00439            ctr=centroid(labeled_img,row,col);
00440            center_row=ctr[0];
00441            center_col=ctr[1];
00442 
00443            object.setX(center_col);
00444                    //swap orientation y-as!!
00445            object.setY(240-center_row);
00446            delete(ctr);
00447        }
00448 
00449        
00450        // 4. set object type, and if type=robot find angle 
00451        if  ( (ROBOT_MINAREA < objectarea) && (objectarea <= ROBOT_MAXAREA ) ) {
00452            // set type to robot
00453            object.setType(Entity::ROBOT);
00454            // find angle robot
00455            ret=robot_angle(component_img,center_row,center_col,angle); 
00456            if (ret ) {
00457               object.setAngle(angle);
00458               // 5. add object to objectlist
00459               objectlist->push_back(object); 
00460               //myprintf("rover:\n  angle=%d,row=%d,col=%d,",angle,row,col);
00461            }
00462        }
00463        if  ( (SUBJECT_MINAREA < objectarea) && (objectarea <= SUBJECT_MAXAREA ) ) {
00464            // set type 
00465            object.setType(Entity::SUBJECT);
00466            // 5. add object to objectlist
00467            objectlist->push_back(object); 
00468            //myprintf("subject:\n  row=%d,col=%d,",row,col);
00469        }
00470        if  ( (GOAL_MINAREA < objectarea) && (objectarea <= GOAL_MAXAREA ) ) {
00471            // set type 
00472            object.setType(Entity::GOAL);
00473            // 5. add object to objectlist
00474            objectlist->push_back(object); 
00475            //myprintf("goal:\n  row=%d,col=%d,",row,col);
00476        }
00477 
00478        label++;
00479     }
00480 
00481 
00482 
00483  
00484  
00485 
00486         delete_Image(labeled_img);
00487 
00488     return component_img;
00489 
00490 }
00491 
00492 
00493 bool ImageProcessor::Init(LPVOID param)
00494 {
00495         CLegoprojectDlg *mdlg;
00496         mdlg = (CLegoprojectDlg*)param;
00497         DWORD dwThreadID;
00498         
00499         h_MyThread = CreateThread(NULL,0,mdlg->imageproc.MyThread,mdlg,NULL,&dwThreadID);
00500         if (!h_MyThread) {
00501                 AfxMessageBox("Thread not started (?!?)", MB_ICONINFORMATION | MB_OK);
00502                 return 0;
00503         }
00504         //SetThreadPriority(h_MyThread,THREAD_PRIORITY_BELOW_NORMAL);
00505         return 1;
00506 }
00507 
00508 
00509 
00510 bool ImageProcessor::Stop()
00511 {
00512         Sleep(700);
00513    // StopThread(h_MyThread);
00514     return 1;
00515 }
00516 
00517 
00518  DWORD __stdcall ImageProcessor::MyThread(LPVOID pParam)
00519 //AFX_THREADPROC   ImageProcessor::MyThread(LPVOID pParam)
00520 {
00521         CLegoprojectDlg *mdlg;   // Main Dialog window
00522         mdlg = (CLegoprojectDlg*) pParam;
00523 
00524         ImageProcessor *MyImageProc;     // instantie van ImageProcessor object
00525         MyImageProc = (ImageProcessor*)&(mdlg->imageproc);
00526 
00527         // images used
00528         CImage *vis = NULL; // format to view in dialog
00529     CImage *visout = NULL; // format to view in dialog
00530         //Image *cvipimage = NULL; //format used in CVIPtools
00531         Image *cvipimage = NULL;
00532     Image *viewimage = NULL;
00533 
00534 
00535         // laat dib naar workimage wijzen
00536     vis=&(mdlg->m_image2);
00537     visout=&(mdlg->m_image3);
00538 
00539     // send  "take picture" message to dialog class
00540     PostMessage(mdlg->dlghandle,WM_TAKEPICT,0,0);
00541 
00542     // wait for "picture taken" event signaled
00543     WaitForSingleObject(mdlg->picttaken,INFINITE);
00544 
00545     int rows=vis->visimage.Height();
00546         int cols=vis->visimage.Width(); 
00547 
00548     while (mdlg->imageprocessor_active) {       
00549           
00550       // get_image
00551 
00552       // send  "take picture" message to dialog class
00553           PostMessage(mdlg->dlghandle,WM_TAKEPICT,0,0);
00554 
00555           // wait for "picture taken" event signaled
00556       WaitForSingleObject(mdlg->picttaken,INFINITE);
00557 
00558       // get new empty 3 band image (changed in loop to 1 band);
00559       cvipimage = new_Image(PPM,RGB,3,rows,cols,CVIP_BYTE,REAL);
00560 
00561 
00562 
00563     // convert image to format used by CVIPtools
00564           MyImageProc->vis2cvip( cvipimage,vis);
00565       
00566           // imageprocessing
00567       cvipimage=MyImageProc->MyAlgorithm(cvipimage);
00568       // WATCH OUT : image returned only one band
00569 
00570       // transform image to visible 0-255 byte format
00571       viewimage = remap_Image(cvipimage ,CVIP_BYTE,0,255);
00572       delete_Image(cvipimage);
00573 
00574           // convert image back to format used for viewing in dailog window
00575           MyImageProc->cvip2vis(visout,viewimage);
00576           delete_Image(viewimage);
00577 
00578       //  alternatives :  show a logged image
00579       //view_logged_Image(visout,2); // reads logged image into visout (which is shown in m_image3)
00580       //mdlg->OpenLogNumber(2); // reads logged image directly from file into m_image3
00581     
00582       visout->Invalidate(TRUE); 
00583     }
00584         DWORD ExitCode=0;
00585         ExitThread(ExitCode);
00586         return 0;
00587 }
00588 
00589 void ImageProcessor::SingleRun(LPVOID pParam)
00590 {
00591         CLegoprojectDlg *mdlg;   // Main Dialog window
00592         mdlg = (CLegoprojectDlg*) pParam;
00593 
00594         ImageProcessor *MyImageProc;     // instantie van ImageProcessor object
00595         MyImageProc = (ImageProcessor*)&(mdlg->imageproc);
00596 
00597         // images used
00598         CImage *vis = NULL; // format to view in dialog
00599     CImage *visout = NULL; // format to view in dialog
00600         //Image *cvipimage = NULL; //format used in CVIPtools
00601         Image *cvipimage = NULL;
00602     Image *viewimage = NULL;
00603 
00604         // laat dib naar workimage wijzen
00605     vis=&(mdlg->m_image2);
00606   
00607     visout=&(mdlg->m_image3);
00608 
00609 
00610     // get_image
00612         vis->Snap();
00613         /* following doesn't work
00614     // send  "take picture" message to dialog class
00615     PostMessage(mdlg->dlghandle,WM_TAKEPICT,0,0);
00616     // wait for "picture taken" event signaled
00617     WaitForSingleObject(mdlg->picttaken,INFINITE);
00618     */
00619 
00620 
00621     int rows=vis->visimage.Height();
00622         int cols=vis->visimage.Width(); 
00623 
00624     // get new empty 3 band image (changed in loop to 1 band);
00625     cvipimage = new_Image(PPM,RGB,3,rows,cols,CVIP_BYTE,REAL);
00626 
00627     // convert image to format used by CVIPtools
00628         MyImageProc->vis2cvip(cvipimage,vis);
00629       
00630         // imageprocessing
00631     cvipimage=MyImageProc->MyAlgorithm(cvipimage);
00632     
00633     // transform image to visible 0-255 byte format
00634     viewimage = remap_Image(cvipimage ,CVIP_BYTE,0,255);
00635     delete_Image(cvipimage);
00636         
00637     // convert image back to format used for viewing in dailog window
00638         MyImageProc->cvip2vis(visout,viewimage);
00639         delete_Image(viewimage);
00640 
00641     //  alternatives :  show a logged image
00642     //view_logged_Image(visout,2); // reads logged image into visout (which is shown in m_image3)
00643     //mdlg->OpenLogNumber(2); // reads logged image directly from file into m_image3
00644    
00645     visout->Invalidate(TRUE);   
00646 }
00647 
00648 
00649 
00650 Image *get_component (Image *inputImage , int color)
00651 {
00652     Image *resultImage;
00653         Matrix *mat;
00654 
00656         if (color == LEGO_RED)   // RED COMPONENT
00657         {
00658                 Image *band2, *band3 ;
00659                 band2 = duplicate_Image(inputImage);
00660                 band3 = duplicate_Image(inputImage);
00661                 band2 = extract_band(band2, 2);
00662                 band3 = extract_band(band3, 3);
00663                 inputImage = extract_band(inputImage, 1);
00664                 inputImage = gray_multiply2(inputImage,2.0);    
00665                 inputImage = subtract_Image(inputImage, band2);
00666                 inputImage = subtract_Image(inputImage, band3);
00667         }
00669 
00670 
00671         if (color == LEGO_GREEN)   // GREEN COMPONENT
00672         {
00673                 Image *band1, *band3 ;
00674                 band1 = duplicate_Image(inputImage);
00675                 band3 = duplicate_Image(inputImage);
00676                 band1 = extract_band(band1, 1);
00677                 band3 = extract_band(band3, 3);
00678                 inputImage = extract_band(inputImage, 2);
00679                 inputImage = gray_multiply2(inputImage,2.5);    
00680                 inputImage = subtract_Image(inputImage, band1);
00681                 inputImage = subtract_Image(inputImage, band3);
00682         }
00683                 
00685 
00686         if (color == LEGO_BLUE)   // BLUE COMPONENT
00687         {
00688                 Image *band1, *band2 ;
00689                 band1 = duplicate_Image(inputImage);
00690                 band2 = duplicate_Image(inputImage);
00691                 band1 = extract_band(band1, 1);
00692                 band2 = extract_band(band2, 2);
00693                 inputImage = extract_band(inputImage, 3);
00694                 inputImage = gray_multiply2(inputImage,2.0);    
00695                 inputImage = subtract_Image(inputImage , band1);
00696                 inputImage = subtract_Image(inputImage , band2);
00697         }
00698                         
00699  //log_Image(inputImage);
00700    log_Image(inputImage,"_subtractedband");
00701 
00702     Image *temp;
00703         temp = remap_Image(inputImage ,CVIP_SHORT,-255,255);
00704         delete_Image(inputImage);
00705 
00706     //view_Image(inputImage,"band1short");
00707 
00708         mat=(Matrix *)get_default_filter(BLUR_SPATIAL,5,0);
00709         temp = (Image *)convolve_filter(temp,mat);
00710     delete_Matrix(mat);
00711         temp = gray_linear(temp ,130.0,255.0,255.0,0.0,0, -1);
00712         
00713     resultImage = remap_Image(temp ,CVIP_BYTE,0,255);   
00714         delete_Image(temp);
00715    
00716     log_Image(resultImage,"_component");
00717   //log_Image(resultImage);
00718     return resultImage;
00719 }
00720 
00721 // returns true if a non-null pixel exist 
00722 // center_row and center_col are set to the  center of 
00723 // the non-null area attached to this pixel
00724 // inputImage : not changed (not deleted from memory)
00725 bool get_centroid_off_first_object(Image *inputImage, int *center_row, int *center_col)
00726 {
00727     int row,col;
00728     Image *lab = NULL;
00729         lab             = duplicate_Image(inputImage);
00730   
00731     // get the coordinates of the first pixel with non-null value
00732         // if no non null pixel are found then return
00733     //   -> otherwise label function makes no sense!!
00734     //         (even crashes?)
00735     if ( !get_first_non_null_point(lab,&row,&col) ) {
00736                 myprintf("first label : EMPTY IMG ");
00737         return false;
00738         }
00739     // label objects ( connented values not null)
00740         lab             = label(lab); //-> if more than one object found -> error
00741     // find centroid of object containing first non-null point
00742         int *ctr=centroid(lab,row,col);
00743     delete_Image(lab);
00744     *center_row=ctr[0];
00745     *center_col=ctr[1]; 
00746     delete(ctr);
00747 
00748     return true;
00749 }
00750 
00751 
00752 
00753 
00754 // returns true if non-null pixel found
00755 // row,column : coordinates of this pixel
00756 // inputImage : not changed (not deleted from memory)
00757 bool get_first_non_null_point(Image *inputImage, int *row,int *column)
00758 {
00759     int r, c, rows ,cols;
00760     bool found=false;
00761     byte **image;
00762 
00763 
00764     rows = getNoOfRows_Image(inputImage);
00765     cols = getNoOfCols_Image(inputImage);
00766         image = (unsigned char ** )getData_Image(inputImage, 0);
00767     for(r=0; r < rows; r++) 
00768         {
00769         for(c=0; c < cols; c++) 
00770                 {
00771                 if (!found)
00772                         {
00773                                 if ( image[r][c] != 0 ) 
00774                                 {
00775                                         *row=r;
00776                         *column=c;
00777                                         found = true;
00778                                 }
00779                         }
00780         }
00781     }
00782         
00783         return found;
00784 }
00785 
00786 
00787 bool find_labeled_object(Image *inputImage, int &row,int &col, int &label) {
00788     int r, c, rows ,cols;
00789 
00790     //byte **image;
00791     int **image;
00792 
00793     // get dimensions of image
00794     rows = getNoOfRows_Image(inputImage);
00795     cols = getNoOfCols_Image(inputImage);
00796     // access data in image
00797 //      image = (unsigned char ** )getData_Image(inputImage, 0);
00798     image = (int ** )getData_Image(inputImage, 0);
00799     // search for object with label value 'label'
00800     // starting at 'row','col' until end of image
00801     for(r=row; r < rows; r++) 
00802         {
00803         for(c=0; c < cols; c++) 
00804                 {
00805                 
00806           //  if ( image[r][c] != 0) {
00807           //     myprintf("r,c,i[r,c] : %d %d %d", r,c, image[r][c]);
00808           //  }
00809                 // check for new label value which 
00810                 //   - must not be equal old label
00811                 //   - and label must not be 0 (means no object)
00812           //    if ( (image[r][c] != label) && (image[r][c] !=0)  ) 
00813             if ( image[r][c] == label ) 
00814                         {
00815                     label=image[r][c];
00816                     row=r;
00817                     col=c;                    
00818                     return true;
00819                         }
00820         }
00821     }
00822     return false;
00823 }
00824 
00825 
00826 bool robot_angle(Image *inputimage,int &center_row,int &center_col,int &angle) 
00827 {
00829 
00830     //--------------------------------------------------
00831     // segmenting the little  circle(s)
00832     //--------------------------------------------------
00833     //Image *bigcircle_with_holes=remap_Image(inputimage,CVIP_BYTE,0,255);
00834     Image *Ccircle,*big_circle,*holes, *holes_and_edgecircle;
00835 
00836         // creating a circle a little smaller than the bigcircle
00837         Ccircle                 = create_circle(320,240,center_col,center_row,6);  
00838 
00839  
00840 
00841     Image *bigcircle_with_holes,*bigcircle_with_holes_copy1,
00842            *bigcircle_with_holes_copy2;
00843 
00844     bigcircle_with_holes        = duplicate_Image(inputimage); 
00845     bigcircle_with_holes_copy1  = duplicate_Image(inputimage);
00846     bigcircle_with_holes_copy2  = duplicate_Image(inputimage);
00847     //log_Image(bigcircle_with_holes);
00848 
00849     holes_and_edgecircle        = xor_Image(bigcircle_with_holes_copy2,Ccircle); 
00850     big_circle              = or_Image(bigcircle_with_holes_copy1,holes_and_edgecircle);
00851     holes                           = xor_Image(bigcircle_with_holes,big_circle);
00852     log_Image(holes,"_holes");
00853 //      log_Image(holes);
00854     // holes :
00855     // - if we only have the white hole -> we found this white hole
00856           //white_hole=holes;
00857     // - however when there is also a black hole, than we have found
00858     //   both the black and white hole
00859            // we than should label both objects. For each found object
00860            // sum the pixel values of the colorband -> the one with 
00861           //    - the lowest value : black circle
00862           //    - highest value : white circle
00863    // --> advantages : 
00864      //   - the angle is more precise !!            
00865      //   - the center is the real center !!
00866    
00867     //if (myview ) view_Image(temp,"view_image");
00868 
00869     
00870 
00871     // find center of hole
00872     int center_row_hole,center_col_hole;
00873     bool found=get_centroid_off_first_object(holes,&center_row_hole,&center_col_hole);
00874     if ( !found )
00875     {
00876                 myprintf("first label : EMPTY IMG ");
00877         delete_Image(holes);
00878         return( false ) ;
00879         }    
00880     delete_Image(holes);     
00881     
00882     
00883 
00886     int delta_col,delta_row;
00887         delta_col = center_col_hole - center_col; 
00888         delta_row = center_row_hole - center_row;
00889 
00890  
00891     // calculate angle
00892     //   put - sign before delta_row because in a normal mathematical sense
00893     //   the y-axis has the opposite direction as the row axis
00894     angle=atan2(-delta_row ,delta_col )*180/PI;
00895 
00896         if (angle < -180) angle = angle +180;
00897         if (angle >  180) angle = angle -180;
00898 
00899 
00900     
00901 
00902 
00903     return true;
00904 }
00905 
00906 
00907 
00908 
00909 
00910   
00911 void log_Image(Image *cvipimage, char *description)
00912 {
00913 
00914 #ifdef LOGIMAGE
00915 
00916 
00917 
00918 
00919     iImageCount++;
00920 
00921 
00922 
00923         // set logpath
00924         char *logpath= get_log_path();
00925     strcpy(szNameFormat,logpath);
00926         delete logpath;
00927 
00928     if (getNoOfBands_Image(cvipimage) == 3) {
00929         strcat(szNameFormat,"lego%03d");
00930                 strcat(szNameFormat, description);
00931                 strcat(szNameFormat,".ppm");
00932  //     strcat(szNameFormat,"C:\\LEGO\\log\\lego%03d.ppm");
00933 
00934         sprintf(szFileName,szNameFormat , iImageCount);
00935     } else {
00936         strcat(szNameFormat,"lego%03d");
00937                 strcat(szNameFormat, description);
00938                 strcat(szNameFormat,".pgm");
00939 //      strcat(szNameFormat,"C:\\LEGO\\log\\lego%03d.pgm");
00940 
00941         sprintf(szFileName,szNameFormat , iImageCount);
00942     }
00943 
00944     Image *resultimage = remap_Image(cvipimage ,CVIP_BYTE,0,255);
00945 
00946     write_Image(resultimage,szFileName,CVIP_YES,CVIP_NO,PPM,CVIP_NO);
00947 #endif
00948      
00949 }
00950 
00951 
00952 void view_logged_Image(CImage *visimg, int number)
00953 {
00954 
00955 #ifdef LOGIMAGE
00956 
00957 
00958 
00959         // set logpath
00960         char *logpath= get_log_path();
00961     strcpy(szNameFormat,logpath);
00962 
00963 
00964 
00965 //   strcat(szNameFormat,"C:\\LEGO\\log\\lego%03d");
00966         strcat(szNameFormat,"lego%03d*.p?m");
00967     sprintf(szFileName,szNameFormat , number);
00968 
00969 
00970         // zoekpath met wildcards
00971         WIN32_FIND_DATA win32finddata;
00972         HANDLE hFindFirstFile;
00973         //zoek first file met zoekpath met wildcards
00974         
00975         hFindFirstFile = FindFirstFile(szFileName, &win32finddata);
00976 
00977         // indien geen file gevonden , stop met deze loop
00978     if ( hFindFirstFile == INVALID_HANDLE_VALUE) {
00979                 return;
00980         }
00981 
00982         // maak found file string
00983         strcpy(szNameFormat,logpath);
00984     strcat(szNameFormat,win32finddata.cFileName);
00985         //debug_printf(szLogFileName);
00986 
00987         delete logpath; 
00988 
00989     visimg->ReadFromFile(szNameFormat);
00990     //visimg->ReadFromFileGuessExt(szFileName);
00991 #endif
00992      
00993 }
00994 
00995 
00996 
00997 
00998 
00999 
01003 
01004 // determines the angle and position of a Red circle containing a small white circle
01005 //  position -> the center of the red circle
01006 //  angle    -> the disposition of the small white circle in the Red circle 
01007 // returns an image with the white circle
01008 Image *Robot_Position_and_Angle(Image *inputImage)
01009 {
01010     int row,col,angle;
01011     Image *result;
01012     Image *inputImage2=duplicate_Image(inputImage);
01013     Image *inputImage3=duplicate_Image(inputImage);
01014     result=Object_Position_and_Angle(inputImage,LEGO_RED,&row,&col,&angle);
01015     delete_Image(result);
01016     myprintf("RED pos: r=%d, c=%d, ang: a=%d", row, col, angle);
01017     result=Object_Position_and_Angle(inputImage2,LEGO_GREEN,&row,&col,&angle);
01018     delete_Image(result);
01019     myprintf("GREEN pos: r=%d, c=%d, ang: a=%d", row, col, angle);
01020     result=Object_Position_and_Angle(inputImage3,LEGO_BLUE,&row,&col,&angle);
01021     myprintf("BLUE pos: r=%d, c=%d, ang: a=%d", row, col, angle);
01022     return result;
01023 }
01024 
01025 // determines the angle and position of a Basic color (RGB) circle 
01026 // containing a small white circle
01027 //  position -> the center of the red circle
01028 //  angle    -> the disposition of the small white circle in the bigger circle 
01029 // returns an image with the small white circle
01030 /*   example :
01031      //RED
01032      result=Object_Position_and_Angle(inputImage3,RED,&row,&col,&angle);
01033      myprintf("REDs: r=%d, c=%d, ang: a=%d", row, col, angle);
01034      log_Image(result);
01035 */
01036 Image *Object_Position_and_Angle(Image *inputImage,int obj_color, int *obj_row, 
01037                                 int *obj_col,int *obj_angle)
01038 {       
01039     Image *lab = NULL, *Ccircle = NULL;
01040     Image *bigcircle_with_holes, *holes_and_edgecircle,*big_circle,*holes;
01041 
01042 
01043     bool found;
01044      
01045     int center_row_1,center_col_1, center_row_2,center_col_2;
01046         int delta_row, delta_col;
01047 
01048   
01049 
01050 
01051 
01053 
01054 
01055 
01056 
01057 
01058   //if (myview ) view_Image(redband,"redband");
01059 
01060 
01061     // get the (pure Red or Green or Blue) color component of the image
01062     // gets the pure color pixels : retrieves a binary (0 or 255) image
01063     bigcircle_with_holes = get_component(inputImage,obj_color);
01064         
01065     // get center of first red object
01066     found=get_centroid_off_first_object(bigcircle_with_holes,&center_row_1,&center_col_1);
01067     if ( !found )
01068     {
01069                 myprintf("first label : EMPTY IMG ");
01070         return( bigcircle_with_holes) ;
01071         }    
01072 
01073 
01074 
01075 
01076 
01078 
01079     //--------------------------------------------------
01080     // segmenting the little  circle(s)
01081     //--------------------------------------------------
01082 
01083         // creating a circle a little smaller than the bigcircle
01084         Ccircle                 = create_circle(320,240,center_col_1,center_row_1,6);  
01085         
01086     Image *bigcircle_with_holes_copy1,*bigcircle_with_holes_copy2;
01087     bigcircle_with_holes_copy1  = duplicate_Image(bigcircle_with_holes); 
01088     bigcircle_with_holes_copy2  = duplicate_Image(bigcircle_with_holes); 
01089     //log_Image(bigcircle_with_holes);
01090 
01091     holes_and_edgecircle        = xor_Image(bigcircle_with_holes_copy2,Ccircle); 
01092     big_circle              = or_Image(bigcircle_with_holes_copy1,holes_and_edgecircle);
01093     holes                           = xor_Image(bigcircle_with_holes,big_circle);
01094     log_Image(holes,"_holes");
01095 //  log_Image(holes);
01096 
01097     // holes :
01098     // - if we only have the white hole -> we found this white hole
01099           //white_hole=holes;
01100     // - however when there is also a black hole, than we have found
01101     //   both the black and white hole
01102            // we than should label both objects. For each found object
01103            // sum the pixel values of the colorband -> the one with 
01104           //    - the lowest value : black circle
01105           //    - highest value : white circle
01106    // --> advantages : 
01107      //   - the angle is more precise !!            
01108      //   - the center is the real center !!
01109    
01110     //if (myview ) view_Image(temp,"view_image");
01111 
01112     
01113 
01114     // find center of hole
01115     found=get_centroid_off_first_object(holes,&center_row_2,&center_col_2);
01116     if ( !found )
01117     {
01118                 myprintf("first label : EMPTY IMG ");
01119         return( holes) ;
01120         }    
01121      
01122     
01123     
01124 
01127         delta_col = center_col_2 - center_col_1; 
01128         delta_row = center_row_2 - center_row_1;
01129 
01130         int angle; 
01131     // calculate angle
01132     //   put - sign before delta_row because in a normal mathematical sense
01133     //   the y-axis has the opposite direction as the row axis
01134     angle=atan2(-delta_row ,delta_col )*180/PI;
01135 
01136         if (angle < -180) angle = angle +180;
01137         if (angle >  180) angle = angle -180;
01138 
01139         //  RESULTS
01141 //    myprintf("arrow = ( %d , %d )",delta_col,delta_row);
01142 //      myprintf("pos: r=%d, c=%d, ang: a=%d", center_row_1, center_col_1, angle);
01143 
01144         *obj_angle=angle;
01145     *obj_row=center_row_1;
01146     *obj_col=center_col_1;
01147     return holes;
01148 }

Generated on Wed Nov 29 01:18:47 2006 by  doxygen 1.4.6