我知道OpenCV只支持二進制掩碼。
但我需要做一個覆蓋,我有一個灰度掩模,指定覆蓋層的透明度。哪個是在opencv中做alpha屏蔽的最有效方法?
例如,如果蒙版中的像素爲50%白色,則應該表示該像素的操作爲cv::addWeighted
,alpha = beta = 0.5,gamma = 0.0。
現在,如果沒有opencv庫函數,您會建議哪種算法最有效?
我知道OpenCV只支持二進制掩碼。
但我需要做一個覆蓋,我有一個灰度掩模,指定覆蓋層的透明度。哪個是在opencv中做alpha屏蔽的最有效方法?
例如,如果蒙版中的像素爲50%白色,則應該表示該像素的操作爲cv::addWeighted
,alpha = beta = 0.5,gamma = 0.0。
現在,如果沒有opencv庫函數,您會建議哪種算法最有效?
我做了這樣的修復。
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是普通的三通道彩色圖像。
OpenCV支持RGBA圖像,您可以使用mixchannels
或split
和merge
函數將您的圖像與灰度蒙版組合。我希望這是你正在尋找的!
使用這種方法,你可以像這樣與你的形象相結合的灰度蒙版:
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
我有一個類似的問題,我想申請一個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);
}
謝謝,但如果我把一個RGBA圖片上的其他的頂部會發生什麼?根據Alpha通道調整上層的透明度嗎? –
我還沒有嘗試過使用類似cv :: addWeighted的方法來組合兩個rgba圖像,但我想它可以按照公式工作:dst =飽和(src1 * alpha + src2 * beta + gamma)。 – cwadding