哪个是在opencv中进行alpha掩码的最有效方法?

时间:2012-10-29 19:57:46

标签: performance optimization opencv

我知道OpenCV只支持二进制掩码 但我需要做一个叠加,我有一个灰度蒙版,指定叠加的透明度。

EG。如果掩码中的像素为50%白色,则表示该像素的cv::addWeighted操作,alpha = beta = 0.5,gamma = 0.0。

现在,如果没有opencv库函数,你会建议哪种算法最有效?

3 个答案:

答案 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图像,您可以使用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

所示