我知道 OpenCV 只支持二进制掩码。
但我需要做一个覆盖,我有一个灰度蒙版,指定覆盖的透明度。
例如。如果掩码中的像素为 50% 白色,则表示cv::addWeighted
该像素的操作为 alpha=beta=0.5,gamma = 0.0。
现在,如果没有 opencv 库函数,您会建议哪种算法最有效?
我知道 OpenCV 只支持二进制掩码。
但我需要做一个覆盖,我有一个灰度蒙版,指定覆盖的透明度。
例如。如果掩码中的像素为 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 是正常的三通道彩色图像。
我有一个类似的问题,我想应用一个透明的 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);
}
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-opencvcv::imshow
中的描述查看 RGBA 图像,并且您无法将图像保存为 jpeg,因为该格式不支持透明度。似乎您可以使用opencv-2-3-convert-mat-to-rgba-pixel-array中所示的方式组合通道cv::cvtcolor