MATLAB Answers

How do I make a weighted MEDIAN filter in matlab?

조회 수: 38(최근 30일)
Eduardo
Eduardo 19 May 2011
편집: Jan Rubak 17 Mar 2019
Hi everybody... I want to build a weighted median filter, (not an weighted average filter). A proffessor told me that I could use an histogram but I really dont know what he reffers to and he didn't told me anymore about. I really need help with that.
Greetings from Venezuela!

  댓글 수: 1

bym
bym 19 May 2011
the median value would be where the area of the histogram is equal to 50%. Is this an image processing application?

Sign in to comment.

답변(1개)

Jan Rubak
Jan Rubak 19 May 2011
편집: Jan Rubak 17 Mar 2019
Hi Eduardo,
[This answer is incorrect. Please see the update in the comment below it.]
A weighted median is probably just another word for a percentile calculation from a data set where the weight parameter is a value between 0 and 100 (with the 50th percentile returning the traditional median value).
If your data set is not too large, then the easiest way to obtain a percentile value is simply to sort it into ascending order and look at the corresponding index in the sorted array. A histogram and a sorted data vector contain basically the same information (one is the derivative of the other flipped on its side).
function Value = GetPercentileValue(DataVector,Percentile)
DataVector = sort(DataVector(:));
idxTarget = 1+(numel(DataVector)-1)*Percentile/100;
idx1 = floor(idxTarget);
idx2 = ceil(idxTarget);
idxFract = idxTarget - idx1;
Value = DataVector(idx1)*(1-idxFract) + DataVector(idx2)*idxFract;
If you're looking to apply this to a one-dimensional DSP problem, then with a bit of bookkeeping, you could maintain a temporally local sorted list of the data which slides along in time, dropping individual values as they pass out of the window while adding the new ones that enter on the other side. If your window size is small enough, it may suit you better to just brute force it by sorting the whole interval from scratch with each new iteration. Depending on your data sizes, this could be vectorized pretty easily by constructing a two-dimensional array where each column contains your entire time-series shifted by one step, and then calling sort(DataArray,2) and using similar logic as above to combine the two appropriate columns in the sorted array.
For a two-dimensional image processing problem, the sliding window approach can be generalized so that each horizontal step you drop a line of pixels out of your list from one side of your window and add a line of new pixels from the other side (and of course a little more care needs to be taken each time you shift down one raster line). If the window size is small, say 5x5 pixels (depending on your image size and available memory), you can create a three-dimensional array with 25 layers, each layer being an appropriately shifted copy of the original image, call sort() along dimension 3 and then combine the appropriate two layers in the result.
In those cases where you want to compute a percentile value from a very large set of data (i.e. large enough that a sort() operation is overkill or not practical due to memory/runtime issues), you'll need to construct a histogram or a cumulative histogram from the data, and then use that to tell you the percentile value. I'm not sure if the Matlab-native hist() function or any of its compatriots allow you to do something like that easily, or if they're mainly just tools for generating plots. I have a personal routine for analyzing multi-gigabyte data files that does something like this, but it's not mature enough yet for me to share it with the File Exchange community at this point, and in any case this doesn't sound like what you probably need.
Hope this helps.
-Jan

  댓글 수: 1

Jan Rubak
Jan Rubak 17 Mar 2019
Oops. Years later I encountered the weighted median in some literature, and realized how wrong my answer was for this. What I described above is just a quantile calculation.
Here's a simple function that computes the weighted median of a vector:
function val = WeightedMedian(xVec,wVec)
validateattributes(xVec,{'numeric'},{'vector'},'WeightedMedian()','x')
validateattributes(wVec,{'numeric'},{'nonnegative' 'size' szX},'WeightedMedian()',w)
[xVec,idx] = sort(xVec);
massVec = cumsum(double(wVec(idx)));
val = xVec( find( massVec >= 0.5*massVec(end) ,1,'first') );
end
And, with a very minor modification this can also be used to compute a weighted quantile:
function val = WeightedQuantile(xVec,wVec,q)
validateattributes(xVec,{'numeric'},{'vector'},'WeightedQuantile()','x')
validateattributes(wVec,{'numeric'},{'nonnegative' 'size' szX},'WeightedQuantile()',w)
validateattributes(q,{'single' 'double'},{'scalar' '>=' 0 '<=' 1},'WeightedQuantile()',q)
[xVec,idx] = sort(xVec);
massVec = cumsum(double(wVec(idx)));
val = xVec( find( massVec >= q*massVec(end) ,1,'first') );
end
Incidentally, Wikipedia also has an entry now (since 2013) on the weighted median.

Sign in to comment.


Translated by