#include<cv.h>
#include<highgui.h>
#include<stdio.h>
#define TH1 80
#define refBlue 255
#define refGreen 255
#define refRed 255
#define refBlue1 0
#define refGreen1 0
#define refRed1 0
int main()
{
IplImage * src1;
IplImage * grey;
IplImage * img;
IplImage * logoImg;
IplImage * logoImg2;
CvCapture * capture = cvCreateCameraCapture(0);
src1 = cvQueryFrame(capture);
grey = cvCreateImage(cvSize(src1->width,src1->height), IPL_DEPTH_8U, 1);
img = cvCreateImage(cvSize(src1->width,src1->height), IPL_DEPTH_8U, 3);
logoImg=cvLoadImage("images01.jpg");//皇冠1
logoImg2=cvLoadImage("images.jpg");//皇冠2
while(true)
{
src1 = cvQueryFrame(capture);
//cvShowImage("webcam",src);
cvCvtColor(src1,img, CV_BGR2YCrCb);
cvInRangeS(img,cvScalar(0,137,77), cvScalar(240,177,127),grey);
//cvShowImage("webcam2",grey);
int mouseX=0;//西瓜X座標
int mouseY=0;//西瓜Y座標
float redPixelNumber=0;//紀錄顏色出現的次數
float redPixelX=0;//顏色出現的X位置
float redPixelY=0;//顏色出現的Y位置
for (int y=0; y<grey->height; y++) //兩個for迴圈在跑全部出現出現的顏色(用於皮膚偵測)(皮膚變白色)
{
uchar* ptr1=(uchar*) (grey->imageData +(y)*grey->widthStep);
for (int x=0; x<grey->width; x++)
{
if(ptr1[x]==255){
redPixelNumber++;
redPixelX+=x;
redPixelY+=y;
}
}
}
if (redPixelNumber>0) //計算十字架出現的位置
{
mouseX=(int)(redPixelX/redPixelNumber);
mouseY=(int)(redPixelY/redPixelNumber);
}
//cvLine(src1,cvPoint(mouseX-10,mouseY),cvPoint(mouseX+10,mouseY),CV_RGB(255,0,0),3,8,0);//十字架水平長度、顏色、
cvLine(src1,cvPoint(160,0),cvPoint(160,240),CV_RGB(255,0,0),3,8,0);//十字架垂直長度、顏色、
//此for迴圈主要在跑皇冠的圖片
for (int y=0; y<logoImg->height; y++)
{
uchar* ptr1=(uchar*) (logoImg->imageData +y*logoImg->widthStep);//宣告一個指標指向給西瓜
uchar* ptr2=(uchar*) (src1->imageData +(y)*src1->widthStep); //宣告一個指標指向給原圖
for (int x=0; x<logoImg->width; x++)
{
int D= (ptr1[3*x] - refBlue) * (ptr1[3*x] - refBlue) + //變數D為儲存類似白色的點
(ptr1[3*x+1] - refGreen) * (ptr1[3*x+1] -refGreen) +
(ptr1[3*x+2] - refRed) * (ptr1[3*x+2] - refRed);
if(sqrt(D) > TH1)
{
ptr2[3*(x+15)]=ptr1[3*(x)];
ptr2[3*(x+15)+1]=ptr1[3*(x)+1]; //圖片加入視訊
ptr2[3*(x+15)+2]=ptr1[3*(x)+2]; }
}
}
for (int y=0; y<logoImg2->height; y++)
{
uchar* ptr1=(uchar*) (logoImg2->imageData +y*logoImg2->widthStep);//宣告一個指標指向給西瓜
uchar* ptr2=(uchar*) (src1->imageData +(y)*src1->widthStep); //宣告一個指標指向給原圖
for (int x=0; x<logoImg2->width; x++)
{
int D= (ptr1[3*x] - refBlue) * (ptr1[3*x] - refBlue) + //變數D為儲存類似白色的點
(ptr1[3*x+1] - refGreen) * (ptr1[3*x+1] -refGreen) +
(ptr1[3*x+2] - refRed) * (ptr1[3*x+2] - refRed);
if(sqrt(D) > TH1)
{
ptr2[3*(x+175)]=ptr1[3*(x)];
ptr2[3*(x+175)+1]=ptr1[3*(x)+1]; //圖片加入視訊
ptr2[3*(x+175)+2]=ptr1[3*(x)+2]; }
}
}
if(mouseX < 160)
{
for (int y=0; y<logoImg->height; y++)
{
uchar* ptr1=(uchar*) (logoImg->imageData +y*logoImg->widthStep);//宣告一個指標指向給皇冠
uchar* ptr2=(uchar*) (src1->imageData +(y+mouseY-150)*src1->widthStep); //宣告一個指標指向給原圖
for (int x=0; x<logoImg->width; x++)
{
int D= (ptr1[3*x] - refBlue) * (ptr1[3*x] - refBlue) + //變數D為儲存類似白色的點
(ptr1[3*x+1] - refGreen) * (ptr1[3*x+1] -refGreen) +
(ptr1[3*x+2] - refRed) * (ptr1[3*x+2] - refRed);
if(sqrt(D) > TH1)
{
ptr2[3*(x+mouseX-140)]=ptr1[3*(x)];
ptr2[3*(x+mouseX-140)+1]=ptr1[3*(x)+1]; //圖片加入視訊
ptr2[3*(x+mouseX-140)+2]=ptr1[3*(x)+2];
}
}
}
}
else if(mouseX > 160)
{
for (int y=0; y<logoImg2->height; y++)
{
uchar* ptr1=(uchar*) (logoImg2->imageData +y*logoImg2->widthStep);//宣告一個指標指向給皇冠
uchar* ptr2=(uchar*) (src1->imageData +(y+mouseY-150)*src1->widthStep); //宣告一個指標指向給原圖
for (int x=0; x<logoImg2->width; x++)
{
int D= (ptr1[3*x] - refBlue) * (ptr1[3*x] - refBlue) + //變數D為儲存類似白色的點
(ptr1[3*x+1] - refGreen) * (ptr1[3*x+1] -refGreen) +
(ptr1[3*x+2] - refRed) * (ptr1[3*x+2] - refRed);
if(sqrt(D) > TH1)
{
ptr2[3*(x+mouseX)]=ptr1[3*(x)];
ptr2[3*(x+mouseX)+1]=ptr1[3*(x)+1]; //圖片加入視訊
ptr2[3*(x+mouseX)+2]=ptr1[3*(x)+2];
}
}
}
}
cvShowImage("webcam",src1);
cvShowImage("grey",grey);
char key = cvWaitKey(33);
if(key == 27)break;
}
}
考試心得:
這次的考試分為兩個部分,須將畫面正中央的紅線畫出來,再分別在左右放兩個不同的皇冠,當頭移動到某一邊時,皇冠需自動顯示在頭頂上。
而我在考試時只有將紅線畫出來,兩個皇冠的有出現在左右,卻無法在頭移動時自動跑出皇冠,後來中裕告訴我他的方法,他將左右以160做分隔,如果小於160就是左半邊,大於160就是右半邊,我覺得這個方法非常的好,可以很迅速地做判斷,接著就運用老師在上課時所教的西瓜那一次的作業,再將座標位置慢慢做調整,最後我在與同學的討論下完成了此作業。其中我很感謝昊穎,因為他在星期日和我一起到教室做練習,我們將所有上課所做過的作業都拿出來討論,而我也把我不懂得問他,他都非常詳細的回答我。雖然考試時並沒有完成全部,但是如果沒有經過討論與練習,我可能連紅線都有困難。
沒有留言:
張貼留言