2013年6月7日 星期五

期末專題 揮手變臉


#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include "cxcore.h"
#define refBlue 168
#define refGreen 182
#define refRed 205

CvCapture *capture;

int main(){
    IplImage* pImg = NULL;
    IplImage* pImg2 = NULL;  
    IplImage* pImg1 = NULL;
    IplImage* logoImg= NULL;
    IplImage* l1= NULL;
    IplImage* l2= NULL;
    IplImage* l3= NULL;
    IplImage* l4= NULL;
    IplImage* l5= NULL;
    IplImage* l6= NULL;
    IplImage* l7= NULL;
    IplImage* l8= NULL;
    IplImage* l9= NULL;
    IplImage* l10= NULL;
    IplImage* l11= NULL;
    IplImage* l12= NULL;
    IplImage* l13= NULL;
    IplImage* l14= NULL;
    IplImage* l15= NULL;
    IplImage* l16= NULL;
    IplImage* l17= NULL;
    IplImage* l18= NULL;
    IplImage* l19= NULL;
    IplImage* l20= NULL;
 
    int mouseX=0;
    int mouseY=0;
    CvPoint P1,P2,P3,P4;
    CvScalar Color;
    l1=cvLoadImage("1.jpg");
    l2=cvLoadImage("2.jpg");
    l3=cvLoadImage("3.jpg");
    l4=cvLoadImage("5.jpg");
    l5=cvLoadImage("6.jpg");
    l6=cvLoadImage("7.jpg");
    l7=cvLoadImage("8.jpg");
    l8=cvLoadImage("9.jpg");
    l9=cvLoadImage("10.jpg");
    l10=cvLoadImage("11.jpg");
    l11=cvLoadImage("12.jpg");
    l12=cvLoadImage("13.jpg");
    l13=cvLoadImage("14.jpg");
    l14=cvLoadImage("15.jpg");
    l15=cvLoadImage("16.jpg");
    l16=cvLoadImage("17.jpg");
    l17=cvLoadImage("18.jpg");
    l18=cvLoadImage("19.jpg");
    l19=cvLoadImage("20.jpg");
    l20=cvLoadImage("21.jpg");
 
    capture=cvCreateCameraCapture(1);
    cvNamedWindow("Original Image", 1);
    cvNamedWindow("123", 1);
 
    while(true){
 
    pImg=cvQueryFrame(capture);
    pImg1 = cvCreateImage(cvSize(pImg->width,pImg->height), IPL_DEPTH_8U, 1);
    pImg2 = cvCreateImage(cvSize(pImg->width,pImg->height), IPL_DEPTH_8U, 3);
 
 
    cvCvtColor(pImg, pImg, CV_BGR2YCrCb);
    cvInRangeS(pImg, cvScalar(0,137,77), cvScalar(256,177,127),pImg1);
    pImg=cvQueryFrame(capture);
    pImg2=cvCloneImage(pImg);
 

    int redPixelNumber=0;
    int redPixelX=0;
    int redPixelY=0;
    int s=0,R,S;
 
    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;
       s+=1;}
     }
     }
     if(R>20)R=0;
     if(s>30000)R=rand()%20;
     if(R==0)logoImg=cvCloneImage(l1);
     if(R==1)logoImg=cvCloneImage(l2);
     if(R==2)logoImg=cvCloneImage(l3);
     if(R==3)logoImg=cvCloneImage(l4);
     if(R==4)logoImg=cvCloneImage(l5);
     if(R==5)logoImg=cvCloneImage(l6);
     if(R==6)logoImg=cvCloneImage(l7);
     if(R==7)logoImg=cvCloneImage(l8);
     if(R==8)logoImg=cvCloneImage(l9);
     if(R==9)logoImg=cvCloneImage(l10);
     if(R==10)logoImg=cvCloneImage(l11);
     if(R==11)logoImg=cvCloneImage(l12);
     if(R==12)logoImg=cvCloneImage(l13);
     if(R==13)logoImg=cvCloneImage(l14);
     if(R==14)logoImg=cvCloneImage(l15);
     if(R==15)logoImg=cvCloneImage(l16);
     if(R==16)logoImg=cvCloneImage(l17);
     if(R==17)logoImg=cvCloneImage(l18);
     if(R==18)logoImg=cvCloneImage(l19);
     if(R==19)logoImg=cvCloneImage(l20);
     if (redPixelNumber>0) {
      mouseX=redPixelX/redPixelNumber;
      mouseY=redPixelY/redPixelNumber;
      }
   
      P1 = cvPoint(mouseX-10,mouseY);                                  
      P2 = cvPoint(mouseX+10,mouseY);
      P3 = cvPoint(mouseX,mouseY-10);                                  
      P4 = cvPoint(mouseX,mouseY+10);                                  
      Color=CV_RGB(255,0,0);
      //cvLine(pImg2,P1,P2,Color,2,8,0);
      //cvLine(pImg2,P3,P4,Color,2,8,0);
   
   
      for (int y=0; y<logoImg->height; y++) {
      uchar* ptr1=(uchar*) (pImg2->imageData +(y+mouseY-170)*pImg2->widthStep);
      uchar* ptr2=(uchar*) (logoImg->imageData + y*logoImg->widthStep);
      for (int x=0; x<logoImg->width; x++) {  
       if(ptr2[3*x]!=255){
       ptr1[3*(x+mouseX-80)]=ptr2[3*(x)] ;
       ptr1[3*(x+mouseX-80)+1]=ptr2[3*(x)+1] ;
       ptr1[3*(x+mouseX-80)+2]=ptr2[3*(x)+2] ;}  
      }
 
}
   

 cvShowImage( "Original Image", pImg2 );
 cvShowImage( "123", pImg1 );
 cvReleaseImage( &pImg2 );

 cvWaitKey(10);
 
}

 
 
   }

雖然程式很簡單 但是對於成是很弱的我依舊很有難度 我跑去找了吳鍾昊幫忙 請他幫我修改並且debug 他真的很厲害 一下子就修改完成了!

程式碼本體 是老師上課的作業 : 皮膚偵測
我多加了一個揮手偵測 也就是     
if(R>20)R=0;
if(s>30000)R=rand()%20;
這兩行精華所在
當手在視訊前時 因為皮膚色變多 所以程式開始隨機產生1~20值
當手消失在視訊前時 因為皮膚色變少 所以程式選定一個當時隨機到的1~20值
並且產生那個值所代表的面具

這程式有個大家都會錯的BUG 也就是 當圖片碰到視訊邊界時 程式就會當掉
所以我選擇了新的視訊硬體 讓視訊邊界變得更大 減少BUG產生的機會
但是 這是治標不治本的辦法 最好的辦法 依舊是要設定X Y 不要超過中間區域
不過真的是有點複雜 加上我的圖片太多 沒有太多時間可去一一比對修改 所以...
我才會用這個偷懶的方式 哈哈

沒有留言:

張貼留言