我知道OpenCV只支持二进制掩码 但我需要做一个叠加,我有一个灰度蒙版,指定叠加的透明度。
EG。如果掩码中的像素为50%白色,则表示该像素的cv::addWeighted
操作,alpha = beta = 0.5,gamma = 0.0。
现在,如果没有opencv库函数,你会建议哪种算法最有效?
答案 0 :(得分: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 :(得分:4)
我有类似的问题,我想在其中应用具有透明度的png。 我的解决方案是使用Mat表达式:
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);
}
答案 2 :(得分:-1)
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