Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which is the most efficient way to do alpha mask in opencv?

I know OpenCV only supports binary masks.
But I need to do an overlay where I have a grayscale mask that specifies transparency of the overlay.

Eg. if a pixel in the mask is 50% white it should mean a cv::addWeighted operation for that pixel with alpha=beta=0.5, gamma = 0.0.

Now, if there is no opencv library function, what algorithm would you suggest as the most efficient?

like image 445
Barney Szabolcs Avatar asked Oct 29 '12 19:10

Barney Szabolcs


People also ask

What is alpha channel in image OpenCV?

Alpha blending is the process of overlaying a foreground image with transparency over a background image. The transparency is often the fourth channel of an image ( e.g. in a transparent PNG), but it can also be a separate image. This transparency mask is often called the alpha mask or the alpha matte.

How do I mask an image in OpenCV?

Masking is a common technique to extract the Region of Interest (ROI). In openCV, it is possible to construct arbitrary masking shape using draw function and bitwise operation.


2 Answers

I did something like this for a fix.

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

I have not optimized nor made safe this code yet with assertions.
Working assumptions: all Mat's and the Mask are the same size and Mat's are normal three channel color images.

like image 172
Barney Szabolcs Avatar answered Oct 08 '22 12:10

Barney Szabolcs


I have a similar problem, where I wanted to apply a png with transparency. My solution was using Mat expressions:

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);
}
like image 26
Marcos Lima Avatar answered Oct 08 '22 12:10

Marcos Lima