2013-02-26 112 views
5

基本上我想爲我的繪畫應用程序實現顏色替換功能。 下面是原始的和預期的輸出iPhone應用程序的圖像中的顏色替換

原文: original

用戶與某個閾值以及選擇更換改變牆壁的顏色

desired output 我已經嘗試了兩種方法,但不能得到預期運行後

方法1:
Queue-based Flood Fill算法顏色替換 但我得到低於輸出非常緩慢,牆影未得到保存。

flood fill output

方法2: 所以我必須想看看另一種選擇和SO How to change a particular color in an image?

發現下面的文章,但我無法理解我的,從代碼實現的邏輯,而不是確定第3步。

請根據我的理解,找到以下代碼,瞭解每個步驟。

1)使用cvCvtColor將圖像從RGB轉換爲HSV(我們只想更改色調 )。

IplImage *mainImage=[self CreateIplImageFromUIImage:[UIImage imageNamed:@"original.jpg"]]; 
IplImage *hsvImage = cvCreateImage(cvGetSize(mainImage), IPL_DEPTH_8U, 3); 
IplImage *threshImage = cvCreateImage(cvGetSize(mainImage), IPL_DEPTH_8U, 3); 
cvCvtColor(mainImage,hsvImage,CV_RGB2HSV); 

2)隔離與cvThreshold指定 一定公差的顏色(要一定範圍的顏色,而不是一個平面彩色)。的最小尺寸以下的顏色

cvThreshold(hsvImage, threshImage, 0, 100, CV_THRESH_BINARY); 

3)棄區域使用斑點檢測 庫等cvBlobsLib。這將消除場景中類似 顏色的點。 我是否需要指定原始圖像或thresold圖像?

CBlobResult blobs = CBlobResult(threshImage, NULL, 0); 
blobs.Filter(blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, 10); 

4)面膜與cvInRangeS顏色和使用 所得掩模以應用新的色調。

不確定這個函數如何幫助顏色替換,並且不能理解要提供的參數。

5)cv將新圖像與 新色調合成一個圖像,並在第1步中保存的飽和度和亮度 通道組成。

我明白,cvMerge會合並H S和V三個通道,但我如何使用以上三個步驟的輸出。

所以基本上堅持了OpenCV的實現,

如果可能的話,請指導我對OpenCV的實行或任何其他解決方案試訓。

+1

是 代替CVSET這是不夠的修改在步驟4中只是色相,然後使用原始飽和度在第5步。看看你的例子中的牆。它是灰色的。灰色的飽和度爲零(或非常接近於零),這意味着色調沒有影響。要將牆壁變成藍色,您需要將飽和度設置爲接近1(*和*您需要設置色調)。 – 2013-02-26 05:38:59

+0

rob你認爲我的第二步和第三步是正確的嗎? – 2013-02-26 15:13:58

+0

@JigarParekh我有同樣的問題,但我必須做到實時(在相機圖像的手段),所以你可以指導如何做到這一點 – Prabhakar 2015-06-18 07:58:39

回答

3

最後,我能夠使用下面的javacv代碼實現一些所需的輸出,並且同樣移植到opencv。

該解決方案具有2個問題

  1. 沒有邊緣檢測,我想使用輪廓我可以實現它
  2. 更換顏色具有平坦的色調和飽和應該設置基於源 像素的色調,其坐在差異,但不知道如何實現。可以使用cvAddS

    IplImage image = cvLoadImage("sample.png"); 
    CvSize cvSize = cvGetSize(image); 
    
    
    IplImage hsvImage = cvCreateImage(cvSize, image.depth(),image.nChannels()); 
    
    IplImage hChannel = cvCreateImage(cvSize, image.depth(), 1); 
         IplImage sChannel = cvCreateImage(cvSize, image.depth(), 1); 
         IplImage vChannel = cvCreateImage(cvSize, image.depth(), 1); 
    cvSplit(hsvImage, hChannel, sChannel, vChannel, null); 
    
    
    IplImage cvInRange = cvCreateImage(cvSize, image.depth(), 1); 
    CvScalar source=new CvScalar(72/2,0.07*255,66,0); //source color to replace 
    CvScalar from=getScaler(source,false); 
    CvScalar to=getScaler(source, true); 
    
    cvInRangeS(hsvImage, from , to, cvInRange); 
    
    IplImage dest = cvCreateImage(cvSize, image.depth(), image.nChannels()); 
    
    IplImage temp = cvCreateImage(cvSize, IPL_DEPTH_8U, 2); 
    cvMerge(hChannel, sChannel, null, null, temp); 
    
    cvSet(temp, new CvScalar(45,255,0,0), cvInRange);// destination hue and sat 
    cvSplit(temp, hChannel, sChannel, null, null); 
    cvMerge(hChannel, sChannel, vChannel, null, dest); 
    cvCvtColor(dest, dest, CV_HSV2BGR); 
    cvSaveImage("output.png", dest); 
    

方法用於計算閾

CvScalar getScaler(CvScalar seed,boolean plus){ 
    if(plus){ 
     return CV_RGB(seed.red()+(seed.red()*thresold),seed.green()+(seed.green()*thresold),seed.blue()+(seed.blue()*thresold)); 
    }else{ 
     return CV_RGB(seed.red()-(seed.red()*thresold),seed.green()-(seed.green()*thresold),seed.blue()-(seed.blue()*thresold)); 
    } 
     } 
+0

很好的答案... +1 – jagdish 2014-06-25 07:44:43

+1

你可以請分享你指的是什麼材料或教程此功能 ?我也在研究類似的功能..找不到合適的東西:( – Shailesh 2014-12-15 06:21:12

+0

如果你可以分享的話會很棒 – woohoou 2016-12-13 06:58:35