#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include "stdio.h"
#define x1 0
#define y1 0
#define x2 161
#define y2 0
IplImage* bImg = NULL;
IplImage* gImg = NULL;
IplImage* rImg = NULL;
IplImage* logoImg1 = NULL;
IplImage* logoImg2 = NULL;
IplImage* mergeImg = NULL;
IplImage* grey = NULL;
IplImage* img = NULL;
int main()
{
int mouseX=0;
int mouseY=0;
float blackPixelNumber=0;
float blackPixelX=0;
float blackPixelY=0;
logoImg1=cvLoadImage("photo1.jpg");
logoImg2=cvLoadImage("photo2.jpg");
IplImage * src;
CvCapture * capture = cvCreateCameraCapture(0);
while(true)
{
src = cvQueryFrame(capture);
cvLine(src,cvPoint(160,0),cvPoint(160,240),CV_RGB(255,0,0),1,8,0);
mergeImg = cvCreateImage(cvSize(src->width,src->height), IPL_DEPTH_8U, 3);
grey = cvCreateImage(cvSize(src->width,src->height), IPL_DEPTH_8U, 1);
img = cvCreateImage(cvSize(src->width,src->height), IPL_DEPTH_8U, 3);
cvCvtColor(src, img, CV_BGR2YCrCb);
cvInRangeS(img, cvScalar(0,137,77), cvScalar(256,177,127),grey);
for (int y=0; y<grey->height; y++) {
uchar* ptr1=(uchar*) (grey->imageData +y*grey->widthStep);
for (int x=0; x<grey->width; x++) {
if(ptr1[x] == 255){
blackPixelNumber++;
blackPixelX+=x;
blackPixelY+=y;
}
}
}
if (blackPixelNumber > 0) {
mouseX=blackPixelX/blackPixelNumber;
mouseY=blackPixelY/blackPixelNumber;
}
mergeImg=cvCloneImage(src);
for (int y=0; y<logoImg1->height; y++) {
uchar* ptr1=(uchar*) (logoImg1->imageData +y*logoImg1->widthStep);
uchar* ptr2=(uchar*) (mergeImg->imageData +(y+y1)*mergeImg->widthStep);
for (int x=0; x<logoImg1->width; x++) {
if(ptr1[3*(x)] < 210 && ptr1[3*(x+1)] < 210 && ptr1[3*(x+2)] < 210){
ptr2[3*(x+x1)]=ptr1[3*(x)] ;
ptr2[3*(x+x1)+1]=ptr1[3*(x)+1] ;
ptr2[3*(x+x1)+2]=ptr1[3*(x)+2] ;
}
}
}
for (int y=0; y<logoImg2->height; y++) {
uchar* ptr1=(uchar*) (logoImg2->imageData +y*logoImg2->widthStep);
uchar* ptr2=(uchar*) (mergeImg->imageData +(y+y2)*mergeImg->widthStep);
for (int x=0; x<logoImg2->width; x++) {
if(ptr1[3*(x)] < 239 && ptr1[3*(x+1)] < 239 && ptr1[3*(x+2)] < 239){
ptr2[3*(x+x2)]=ptr1[3*(x)] ;
ptr2[3*(x+x2)+1]=ptr1[3*(x)+1] ;
ptr2[3*(x+x2)+2]=ptr1[3*(x)+2] ;
}
}
}
for (int y=0; y<logoImg1->height; y++) {
uchar* ptr1=(uchar*) (logoImg1->imageData +y*logoImg1->widthStep);
uchar* ptr2=(uchar*) (mergeImg->imageData +(y+mouseY-110)*mergeImg->widthStep);
for (int x=0; x<logoImg1->width; x++) {
if(mouseX<=155)
if(ptr1[3*(x)] < 210 && ptr1[3*(x+1)] < 210 && ptr1[3*(x+2)] < 210){
ptr2[3*(x+mouseX-50)]=ptr1[3*(x)];
ptr2[3*(x+mouseX-50)+1]=ptr1[3*(x)+1];
ptr2[3*(x+mouseX-50)+2]=ptr1[3*(x)+2];
}
}
}
for (int y=0; y<logoImg2->height; y++) {
uchar* ptr1=(uchar*) (logoImg2->imageData +y*logoImg2->widthStep);
uchar* ptr2=(uchar*) (mergeImg->imageData +(y+mouseY-110)*mergeImg->widthStep);
for (int x=0; x<logoImg2->width; x++) {
if(mouseX>=165)
if(ptr1[3*(x)] < 239 && ptr1[3*(x+1)] < 239 && ptr1[3*(x+2)] < 239){
ptr2[3*(x+mouseX-50)]=ptr1[3*(x)];
ptr2[3*(x+mouseX-50)+1]=ptr1[3*(x)+1];
ptr2[3*(x+mouseX-50)+2]=ptr1[3*(x)+2];
}
}
}
cvShowImage("webcam2",mergeImg);
cvShowImage("webcam1",grey);
mouseX=0;
mouseY=0;
blackPixelNumber=0;
blackPixelX=0;
blackPixelY=0;
cvWaitKey(10);
}
cvReleaseCapture(&capture);
cvDestroyWindow("Webcam1");
cvDestroyWindow("Webcam2");
}
遇到的問題:
在上機考的過程中,有做到畫中線及放置去背的兩個圖片,而在偵測人在左右半邊分別會在頭上出現不同的帽子部分,在左右會分別顯示出該部分的圖片,但是在判斷範圍上不夠明確,及無法上出現的帽子圖片是顯示在頭上。
解決方法:
for (int y=0; y<logoImg1->height; y++) {
uchar* ptr1=(uchar*) (logoImg1->imageData +y*logoImg1->widthStep);
uchar* ptr2=(uchar*) (mergeImg->imageData +(y+mouseY-110)*mergeImg->widthStep);
for (int x=0; x<logoImg1->width; x++) {
if(mouseX<=155)
if(ptr1[3*(x)] < 210 && ptr1[3*(x+1)] < 210 && ptr1[3*(x+2)] < 210){
ptr2[3*(x+mouseX-50)]=ptr1[3*(x)];
ptr2[3*(x+mouseX-50)+1]=ptr1[3*(x)+1];
ptr2[3*(x+mouseX-50)+2]=ptr1[3*(x)+2];
}
}
}
for (int y=0; y<logoImg2->height; y++) {
uchar* ptr1=(uchar*) (logoImg2->imageData +y*logoImg2->widthStep);
uchar* ptr2=(uchar*) (mergeImg->imageData +(y+mouseY-110)*mergeImg->widthStep);
for (int x=0; x<logoImg2->width; x++) {
if(mouseX>=165)
if(ptr1[3*(x)] < 239 && ptr1[3*(x+1)] < 239 && ptr1[3*(x+2)] < 239){
ptr2[3*(x+mouseX-50)]=ptr1[3*(x)];
ptr2[3*(x+mouseX-50)+1]=ptr1[3*(x)+1];
ptr2[3*(x+mouseX-50)+2]=ptr1[3*(x)+2];
}
}
}
為了要在畫面兩側分別戴上不同的帽子,主要程式碼的部分在上面,經由膚色偵測後可以得到mouse X,Y的座標點,首先為要判斷臉是在畫面的左半部還右半部,因此對於mouseX的位子加上了一層判斷 ( if(mouseX<=155) 和 if(mouseX>=165) )。再來是要在兩側分別顯示戴上不同的帽子,這也是使用先前插入去背景圖片的方法,但為了要讓圖片能跟著視訊的人移動,因此加入mouse X 與mouse Y 的判定,讓圖片能跟著偵測到臉的點來移動,但是這樣沒有戴帽子的感覺,跟同學討論了之後,在mouse X 與mouse Y的位子上再做加減,就能控制帽子圖片顯示的位子,經由多次的實驗測試後,得到的結果如上面藍色標記的,經由這些程式碼的修改後,就可以達到老師所要求100分的成果。
心得:
這次的考試其實不會很難,只要能好好運用到先前課堂上所學到的東西,就能完成,但考試時可能是緊張,一時想不出方法來做,但經由上機考後與同學的討論及回家後自己測試,問題也一一完成,也讓我知道了先前上課一些不了解的地方,經過這學期的課,雖然學到的東西感覺不是很多,但經由大家各自的努力,在期中及期末專案上變化出了許多有趣的作品,在面對這些專案及上機考,因為必須由自己實際動手去做、去思考,也讓我真的學到了很多東西。
沒有留言:
張貼留言