2010年3月28日 星期日

HW04: Color Detection

Extend the HW01.cpp and HW04.cpp to generate a program that can change your black hair into red hair.
偵測黑色改成紅色


偵測黑色,分成上下,改變成其他的顏色
把黑色的改變成其他顏色,分4塊





Extend the above program such that you can draw a picture using your hair in another window.

因為我的房間太暗了,很多部是黑色的地方都偵測成黑色,剛好衣服上有紅色,所以我改成偵測紅色,以下是沒有動的時候,剛好畫出一個愛心


之後小小的移動一下,愛心就變形了


過程中,我先不求畫白底,先求能夠把pixel的值改變後就殘留,不要像視訊一樣畫面不斷更新。我照了我的想法去做,把視訊圖偵測到的地方在另外一個新開的視窗上一樣的位子改變BGR,但結果還是會像視訊一樣被更新畫面,就像只是偵測出哪裡有顏色並變色一樣。
我檢查了我變色部分的code覺得沒有錯,於是我把畫白底的code插進去,並且只讓他執行一次,並調整cvWaitKey的值,把它設大,發現一開始的時候,會先出現白底,後來又變成黑底,想不通黑底到底是怎麼跑出來的,而且後來效果還是會像視訊一樣被洗掉,找不到原因,想了很久後來上網找看有沒有類似的code可以參考時發現了一句話:cvCreateImage()
創造一個全黑的基本圖片.....原來問題出在這,因為在while迴圈裡面宣告他,所以會一直不斷的出現新的黑底+被偵測出來的顏色,難怪不會殘留。所以白底的cvCreateImage()只能執行一次。

再來就是要先畫出一張白色的底,我使用的是就把每個pixel的BGR設成255,255,255而且只能畫一次(不然會被洗掉),所以我在回圈內使用了一個int當開關,當跑過一次之後他就被設成0,用if來判斷是否執行過宣告白底的frame和畫白底圖的動作
if(i==1)
{
//產生視窗
frame2 = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 3);
for (int y=0; yheight; y++)
{
uchar* ptr2=(uchar*) (frame2->imageData +y*frame2->widthStep);
for (int x=0; xwidth; x++)
{
//畫白底
ptr2[3*x]=255;
ptr2[3*x+1]=255;
ptr2[3*x+2]=255;
}
}

我要的效果有了,白底+會殘留的變色,但我發現,殘留的變色部分會一直閃爍,而且是上下對稱的閃爍法,我就猜是cvFlivp在搞怪,果然,因為我的程式架構是先把殘留部分畫好,然後再flip(因為所抓到的影像是上下顛倒的),每一秒都會flip個好幾次,當然會閃爍。於是我就把flip先砍了,然後再多創一個frame,讓他不顯示出來,並且將他上下轉正,以這個frame為準來做顏色的偵測,而不是最一開始抓到的那張圖為準(如果用最一開始的那張圖為準偵測到的會是上下顛倒)。 過程差不多是這樣完成。

顏色偵測的演算法
TH1為基準值
ptr1:取出顏色的pixel值
refBlue /refGreen/ refRed:要偵測的顏色BGR
D:(算pixel的BGR和要偵測的顏色BGR差距)^2 開根號 (就像是算2點的距離一樣)
如果 sqrt(D) < d=" (ptr1[3*x]">

沒有留言:

張貼留言