首頁  >  文章  >  web前端  >  OpenCV成長之路(3):模仿PhotoShop中魔術棒工具

OpenCV成長之路(3):模仿PhotoShop中魔術棒工具

高洛峰
高洛峰原創
2017-02-20 09:09:251541瀏覽

本文的主題其實是影像的色彩空間的轉換,借助一個顏色選取程式來說明OpenCV中顏色轉換函數的用法以及一些注意事項。

一、幾種常見的色彩空間:

RGB顏色空間:RGB採用加法混色法,因為它是描述各種「光」透過何種比例來產生顏色。光線從暗黑開始不斷疊加 產生顏色。 RGB描述的是紅綠藍三色光的數值。數位影像儲存方面一般都是用RGB模式,值得注意的是OpenCV里三聲道的儲存順序是BGR。

HSV,HSI:這兩個顏色格式都是根據人眼對顏色的區分來定義的格式,其中H(hue)表示色相,S(saturation)表示飽和度,V(value)表示明度,I( intensity)代表了亮度。

Lab空間:模型中均勻改變對應於在感知顏色中的均勻改變,所以我們可以把Lab想像為顏色空間中的一個點,相鄰的點靠的越近說明兩者的顏色越接近,所以Lab空間常用來度量兩個顏色的相似性。

更多色彩空間的知識可以參考:http://en.wikipedia.org/wiki/Color_space

二、OpenCV中的顏色空間轉換

OpenCV裡透過cvtColor函數來完成圖片的顏色轉換,cvtColor是在opencv2/imgproc/imgproc.hpp頭檔中定義的,它的C++介面如下:

void cvtColor(InputArray src, OutputArray 0 )src:輸入影像。 dst:輸出影像。

code:顏色轉換類型,例如:CV_BGR2Lab,CV_BGR2HSV,CV_HSV2BGR,CV_BGR2RGB。

dstCn:輸出影像的通道號,如果預設為0,則表示按輸入影像的通道數。

把image影像由BGR轉換為Lab:cvtColor(image,image,CV_BGR2Lab)

三、簡單的魔術棒程式

首先我們定義一個colorDetect類:

class colorDetect{private:    int minDist; //minium acceptable distance    Vec3b target;//target color;    
    Mat result; //the resultpublic:
    colorDetect();    void SetMinDistance(int dist);    void SetTargetColor(uchar red,uchar green,uchar blue);    void SetTargetColor(Vec3b color); //set the target color    Mat process(const Mat& image); //main process};

首先我們定義一個colorDetect類:

Mat colorDetect::process(const Mat& image)
{    Mat ImageLab=image.clone();
    result.create(image.rows,image.cols,CV_8U);    
    //将image转换为Lab格式存储在ImageLab中    
    cvtColor(image,ImageLab,CV_BGR2Lab);    
    //将目标颜色由BGR转换为Lab    
    Mat temp(1,1,CV_8UC3);
    temp.at<Vec3b>(0,0)=target;//创建了一张1*1的临时图像并用目标颜色填充    
    cvtColor(temp,temp,CV_BGR2Lab);
    target=temp.at<Vec3b>(0,0);//再从临时图像的Lab格式中取出目标颜色

    // 创建处理用的迭代器    
    Mat_<Vec3b>::iterator it=ImageLab.begin<Vec3b>();    
    Mat_<Vec3b>::iterator itend=ImageLab.end<Vec3b>();    
    Mat_<uchar>::iterator itout=result.begin<uchar>();    
    while(it!=itend)
    {        
    //两个颜色值之间距离的计算        
    int dist=static_cast<int>(norm<int,3>(Vec3i((*it)[0]-target[0],
            (*it)[1]-target[1],(*it)[2]-target[2])));        
            if(dist<minDist)
            (*itout)=255;        
            else            
            (*itout)=0;
        it++;
        itout++;
    }    return result;
}

首先我們定義一個colorDetect類:

rrreee

首先我們定義一個colorDetect類:

rrreee

限定兩種顏色之間的距離,相當於PhotoShop中魔術棒工具的閾值。

target是目標顏色,相當於種子顏色。 result是儲存處理得到的結果。

process是主要的處理程序,下面我們來看process的內容。

rrreee

程式中有2點需要特別注意:

1,在將影像轉換為Lab空間後,目標顏色也需要轉換,做法是建立了臨時影像。

2,判斷兩個顏色之間的距離運算了norm函數,它的運算是norm(v)。其中v是一個dim維的向量。程式中是一個三維的適量,是兩個顏色值兩減後的結果。

那值得思考的是能不能把Vec3i((*it)[0]-target[0],(*it)[1]-target[1],(*it)[2]-target[2] )替換為Vec3i((*it)-target)呢?答案是否的,因為(*it)-target在實際運算過程中會自動的把相減的結果進行類型限制。

OpenCV成長之路(3):模仿PhotoShop中魔術棒工具我們對目標顏色和閾值進行這樣的設定後可以得到一個範例的效果:

cdet.SetTargetColor(150,150,150);

cdet.SetMinDistance(50);🎜🎜🎜cdet.SetMinDistance(50);🎜🎜🎜 ):模仿PhotoShop中魔術棒工具相關文章請關注PHP中文網! 🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn