I have the input image in
, and the mask image lev
(which label each pixel as a number from 1 to nlevels
, nlevels
=4). I need to get image out, which from each region in==lev
will be replaced by its average value.
Here is my brute force approach. I'm wondering if there is any better way of doing it.
Mat ACA::global_average(Mat in, const Mat &lev)
{
// in: CV_32F
// lev: CV_32S
int M=in.rows;
int N=in.cols;
in.convertTo(in, CV_32FC3);
// vector holds average value for each category
vector<float> count(nlevels,0);
vector<Vec3f> average(nlevels);
int pixlev;
for (int i=0; i < M; i++)
for (int j=0; j < N; j++)
{
pixlev = lev.at<int>(i,j);
assert (pixlev<nlevels);
average[pixlev] += in.at<Vec3f>(i,j);
count[pixlev]++;
}
for (int i=0; i<nlevels; i++)
average[i] /=count[i];
Mat out=Mat::zeros(M,N,CV_32FC3);
for (int i=0; i<M; i++)
for (int j=0; j<N; j++)
{
pixlev = lev.at<int>(i,j);
out.at<Vec3f>(i,j)=average[pixlev];
}
return out;
}
P/S:
Here is an example.
Input Image:
Mask image, it is basically a matrix labelling the pixels into one of 4 categories
Output picture is the average of input image, for each category of pixels. For example, at first I find all pixels has category 1, find their average, and replace all those pixels by the average value.