2012-10-29 39 views
7

我知道OpenCV只支持二進制掩碼。
但我需要做一個覆蓋,我有一個灰度掩模,指定覆蓋層的透明度。哪個是在opencv中做alpha屏蔽的最有效方法?

例如,如果蒙版中的像素爲50%白色,則應該表示該像素的操作爲cv::addWeighted,alpha = beta = 0.5,gamma = 0.0。

現在,如果沒有opencv庫函數,您會建議哪種算法最有效?

回答

5

我做了這樣的修復。

typedef double Mask_value_t; 
typedef Mat_<Mask_value_t> Mask; 
void cv::addMasked(const Mat& src1, const Mat& src2, const Mask& mask, Mat& dst) 
{ 
    MatConstIterator_<Vec3b> it1 = src1.begin<Vec3b>(), it1_end = src1.end<Vec3b>(); 
    MatConstIterator_<Vec3b> it2 = src2.begin<Vec3b>(); 
    MatConstIterator_<Mask_value_t> mask_it = mask.begin(); 
    MatIterator_<Vec3b> dst_it = dst.begin<Vec3b>(); 

    for(; it1 != it1_end; ++it1, ++it2, ++mask_it, ++dst_it) 
    *dst_it = (*it1) * (1.0-*mask_it) + (*it2) * (*mask_it); 
} 

我還沒有優化,也沒有使這個代碼安全與斷言。
工作假設:所有Mat和Mask的大小相同,Mat是普通的三通道彩色圖像。

-1

OpenCV支持RGBA圖像,您可以使用mixchannelssplitmerge函數將您的圖像與灰度蒙版組合。我希望這是你正在尋找的!

使用這種方法,你可以像這樣與你的形象相結合的灰度蒙版:

cv::Mat gray_image, mask, rgba_image; 
    std::vector<cv::Mat> result; 
    cv::Mat image = cv::imread(image_path); 
    cv::split(image, result); 
    cv::cvtColor(image, gray_image, CV_BGR2GRAY); 
    cv::threshold(gray_image, mask, 128, 255, CV_THRESH_BINARY); 
    result.push_back(mask); 
    cv::merge(result, rgba_image); 
    imwrite("rgba.png", rgba_image); 

請記住,你不能查看使用在read-rgba-image-opencv描述cv::imshow RGBA圖像,你不能保存爲JPEG圖像,因爲該格式不支持透明度。看來你可以使用cv::cvtcolor來合併頻道,如opencv-2-3-convert-mat-to-rgba-pixel-array

+1

謝謝,但如果我把一個RGBA圖片上的其他的頂部會發生什麼?根據Alpha通道調整上層的透明度嗎? –

+0

我還沒有嘗試過使用類似cv :: addWeighted的方法來組合兩個rgba圖像,但我想它可以按照公式工作:dst =飽和(src1 * alpha + src2 * beta + gamma)。 – cwadding

3

我有一個類似的問題,我想申請一個png與透明度。 我的解決辦法是使用墊表達式:

void AlphaBlend(const Mat& imgFore, Mat& imgDst, const Mat& alpha) 
{ 
    vector<Mat> vAlpha; 
    Mat imgAlpha3; 
    for(int i = 0; i < 3; i++) vAlpha.push_back(alpha); 
    merge(vAlpha,imgAlpha3) 

    Mat blend = imgFore.mul(imgAlpha3,1.0/255) + 
       imgDst.mul(Scalar::all(255)-imgAlpha3,1.0/255); 
    blend.copyTo(imgDst); 
} 
相關問題