【问题标题】:Which is the most efficient way to do alpha mask in opencv?在opencv中做alpha掩码的最有效方法是什么?
【发布时间】:2012-10-19 04:25:57
【问题描述】:

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

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

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

【问题讨论】:

    标签: performance optimization opencv


    【解决方案1】:

    我做了这样的事情来修复。

    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 是正常的三通道彩色图像。

    【讨论】:

      【解决方案2】:

      我有一个类似的问题,我想应用一个透明的 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);
      }
      

      【讨论】:

        【解决方案3】:

        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);
        

        请记住,您无法使用cv::imshow 查看 RGBA 图像,如read-rgba-image-opencv 中所述,并且您无法将图像保存为 jpeg,因为该格式不支持透明度。看来您可以使用cv::cvtcolor 组合频道,如opencv-2-3-convert-mat-to-rgba-pixel-array 所示

        【讨论】:

        • 谢谢,但是如果我把一张 RGBA 图片放在另一张上面会怎样?是否根据Alpha通道调整upper-one的透明度?
        • 我没有尝试使用 cv::addWeighted 之类的东西组合两个 rgba 图像,但我想它会根据以下等式工作:dst = saturate(src1*alpha + src2*beta + gamma)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-29
        • 2018-04-25
        • 2011-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多