題目:
中線左右各放一個皇冠,頭到左邊會戴上左邊的皇冠,到右邊則戴上右邊的皇冠。
一開始把中間的線畫出來,皇冠就相當於把圖片放上去~
考試的時候沒有順利把皇冠放上去,再想可能是位子出了問題。
皇冠要怎麼跟著頭的移動改變位子,一開始想到是利用皮膚偵測的方式,但最後也沒有成功的移動。
修改過後的程式碼:
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include "stdio.h"
int main()
{
IplImage * frame;
IplImage* mergeImg = NULL;
IplImage* pic1 = NULL;
IplImage* pic2 = NULL;
IplImage* pImg = 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);
pImg = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1);
//讀取圖片檔案
pic1 = cvLoadImage("11.jpg");
pic2 = cvLoadImage("22.jpg");
cvNamedWindow("webcam",0);
cvNamedWindow("Webcam1",0);
while(true)
{
frame=cvQueryFrame(capture);
cvFlip(frame,frame,1);//翻轉視訊畫面
cvCvtColor(frame, frame, CV_BGR2YCrCb);//轉換色彩空間
// 將膚色轉白色其他轉黑色,範圍是顏色下限與上限
cvInRangeS(frame, cvScalar(0,137,77), cvScalar(256,177,127),pImg);
//再轉回原本視訊影像
frame=cvQueryFrame(capture);
cvFlip(frame,frame,1);
//複製原本的畫面至mergeImg
mergeImg=cvCloneImage(frame);
//劃出中線
cvLine(mergeImg,cvPoint(150,0),cvPoint(150,255),CV_RGB(255,0,0),3,8,0);
---------------------------------------------------
int redPixelNumber=0;
int redPixelX=0;
int redPixelY=0;
//抓取膚色後變為白色
for (int y=0; y<pImg->height; y++)
{
uchar* ptr1=(uchar*) (pImg->imageData +y*pImg->widthStep);
for (int x=0; x<pImg->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<pic1->height; y++)
{
uchar* ptr1=(uchar*) (mergeImg->imageData +(y)*mergeImg->widthStep);//原本畫面
uchar* ptr2=(uchar*) (pic1->imageData +y*pic1->widthStep);// 1皇冠
uchar* ptr3=(uchar*) (pic2->imageData +y*pic2->widthStep);// 2皇冠
//將第一皇冠(左)放到原本畫面上
for (int x=0; x<pic1->width; x++)
{
if(ptr2[3*x]!=255)
{
ptr1[3*(x+20)]=ptr2[3*(x)];
ptr1[3*(x+20)+1]=ptr2[3*(x)+1];
ptr1[3*(x+20)+2]=ptr2[3*(x)+2];
}
}
//將第二皇冠(右)放到原本畫面上
for (int x=0; x<pic2->width; x++)
{
if(ptr2[3*x]!=255)
{
ptr1[3*(x+180)]=ptr3[3*(x)];
ptr1[3*(x+180)+1]=ptr3[3*(x)+1];
ptr1[3*(x+180)+2]=ptr3[3*(x)+2];
}
}
}
---------------------------------------------------
// 偵測第一個皇冠會在頭上
for (int y=0; y<pic1->height; y++)
{
uchar* ptr1=(uchar*) (mergeImg->imageData +(y+mouseY-170)*mergeImg->widthStep);
uchar* ptr2=(uchar*) (pic1->imageData + y*pic1->widthStep);
for (int x=0; x<pic1->width; x++)
{
if(mouseX <150)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<pic2->height; y++)
{
uchar* ptr1=(uchar*) (mergeImg->imageData +(y+mouseY-150)*mergeImg->widthStep);
uchar* ptr2=(uchar*) (pic2->imageData + y*pic2->widthStep);
for (int x=0; x<pic2->width; x++)
{
if(mouseX >155)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",pImg );
cvShowImage("Webcam1",mergeImg );
char key = cvWaitKey(33);
if(key == 27)break;
}
}
---------------------------------------------------
心得:
上機考的時候看到題目也先愣一下,了解題目後有些部分有一點想法。
雖然最後都沒有成功做出來,但是至少有方向,
考試後有順利完成其實很感動,有想法後有人教就有比較理解。
很謝謝那些教我、幫我一起完成的同學們 :)
沒有留言:
張貼留言