2013年6月7日 星期五

99360941 徐伯誠




#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include "stdio.h"



int main()
{
     IplImage * frame;
     IplImage* mergeImg = NULL;  //複製
     IplImage* photo01 = NULL;
     IplImage* photo02 = NULL;
     IplImage* pImg1 = NULL; //黑白的
   
     int mouseX=0;
     int mouseY=0;

     CvCapture * capture = cvCreateCameraCapture(0);        
     frame=cvQueryFrame(capture);     //讀取視訊畫面
     //為圖片申請空間
     mergeImg = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 3);
     pImg1 = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1);
       
      //讀取圖片檔案
     cvNamedWindow("webcam",0);
     cvNamedWindow("Webcam1",0);

     crown01 = cvLoadImage("001.jpg");
     crown02 = cvLoadImage("002.jpg");
   
   
    while(true)
    {
     
        frame=cvQueryFrame(capture);//讀進畫面
           
        cvFlip(frame,frame,1);//翻轉
        cvCvtColor(frame, frame, CV_BGR2YCrCb);//轉換色彩空間      
        cvInRangeS(frame, cvScalar(0,137,77), cvScalar(256,177,127),pImg1);
        // 膚色轉白其他轉黑,顏色下限與上限  這裡是可以讓皇冠去讀到膚色的部分讓皇冠對應到頭上
       
        frame=cvQueryFrame(capture); //再轉回原本視訊影像
        cvFlip(frame,frame,1);
        mergeImg=cvCloneImage(frame);  //複製原本的畫面至
       
        cvLine(mergeImg,cvPoint(300,0),cvPoint(300,800),CV_RGB(255,0,0),3,8,0);
        //畫中線  座標位置   可以改變顏色和長度的部分
         
        int redPixelNumber=0;
        int redPixelX=0;
        int redPixelY=0;    
        //抓取膚色後變為白色  
        for (int y=0; y<pImg1->height; y++)
        {
          uchar* ptr1=(uchar*) (pImg1->imageData +y*pImg1->widthStep);
          for (int x=0; x<pImg1->width; x++)
          {  
             if(ptr1[x]==255)
             {      
             redPixelNumber++;
             redPixelX+=x;
             redPixelY+=y;
             }
          }
        }
      //變白色之後找平均點為了要帶皇冠
        if (redPixelNumber>0)
        {
         mouseX=redPixelX/redPixelNumber;
         mouseY=redPixelY/redPixelNumber;
        }
       
        //將皇冠固定在頁面上
        for (int y=0; y<crown01->height; y++)
        {
           //原圖
           uchar* ptr1=(uchar*) (mergeImg->imageData +(y)*mergeImg->widthStep);//原本畫面
           uchar* ptr2=(uchar*) (photo01->imageData +y*photo01->widthStep);// 1皇冠
           uchar* ptr3=(uchar*) (photo02->imageData +y*photo02->widthStep);// 2皇冠
         
           //寫入第一皇冠(左)//1皇冠放到原本畫面上
           for (int x=0; x<photo01->width; x++)
           {
               if(ptr2[3*x]!=255)
               {    
                   ptr1[3*(x+70)]=ptr2[3*(x)];
                   ptr1[3*(x+70)+1]=ptr2[3*(x)+1];
                   ptr1[3*(x+70)+2]=ptr2[3*(x)+2];  
               }
            }
           
            //寫入第二皇冠(右)//2皇冠放到原本畫面上
            for (int x=0; x<photo02->width; x++)
            {
               if(ptr2[3*x]!=255)
               {    
                   ptr1[3*(x+450)]=ptr3[3*(x)];
                   ptr1[3*(x+450)+1]=ptr3[3*(x)+1];
                   ptr1[3*(x+450)+2]=ptr3[3*(x)+2];  
               }
            }    
        }
     
      // 偵測第一個皇冠會在頭上
         for (int y=0; y<photo01->height; y++)
         {
           uchar* ptr1=(uchar*) (mergeImg->imageData +(y+mouseY-170)*mergeImg->widthStep);
           uchar* ptr2=(uchar*) (photo01->imageData + y*photo01->widthStep);
           for (int x=0; x<photo01->width; x++)
           {    
                 if(mouseX <300)if(ptr2[3*x]!=255)
                 {
                     ptr1[3*(x+mouseX-60)]=ptr2[3*(x)] ;
                     ptr1[3*(x+mouseX-60)+1]=ptr2[3*(x)+1] ;
                     ptr1[3*(x+mouseX-60)+2]=ptr2[3*(x)+2] ;
                 }  
           }
         }
       // 偵測第二個皇冠會在頭上
          for (int y=0; y<photo02->height; y++)
          {
           uchar* ptr1=(uchar*) (mergeImg->imageData +(y+mouseY-170)*mergeImg->widthStep);
           uchar* ptr2=(uchar*) (photo02->imageData + y*photo02->widthStep);
           for (int x=0; x<photo02->width; x++)
           {    
                 if(mouseX >305)if(ptr2[3*x]!=255)
                 {
                     ptr1[3*(x+mouseX-50)]=ptr2[3*(x)] ;
                     ptr1[3*(x+mouseX-50)+1]=ptr2[3*(x)+1] ;
                     ptr1[3*(x+mouseX-50)+2]=ptr2[3*(x)+2] ;
                 }  
           }
       }
     
      cvShowImage("Webcam",pImg1 );
      cvShowImage("Webcam1",mergeImg );  
             
      char key = cvWaitKey(33);
      if(key == 27)break;      
    }  
}


心得:在課堂上考試的時候,只寫得出中間的線,其實程式碼的部分是我很不拿手的部分,所以特地跑到同學家去請教同學該怎麼做,從一開始的不會到慢慢懂每段程式碼要做的工作是什麼,有些部分似乎沒有想像的那麼困難,但是有些部分還是我無法了解,例如:程式碼的位置'變數還有宣告的東西.做完成品似乎還有一些不完整的地方,皇冠好像沒有辦法快速的偵測到膚色,不知道是不是背景影響到視訊讀取顏色的關係.



沒有留言:

張貼留言