I have an images sequence representing depth information which I'd like to clean. There are some outliers (values with intensity below 25, for a 0-255 range) which I would like to be filled with an acceptable alternative (an average value localised to that specific area could be a good guess).
Can someone see a simple way to do this? I've tried to use a median filter (filter size of 10) substituting the undesired values with NaN, but it did worsen the situation, which improves instead by substituting them with a general average value.
P.S. Someone has already suggested me to use a fast wavelet reconstruction, but I would not really know where to start...
The solution I implemented (before reading about inpaint_nans
suggested by tmpearce) is:
img2 = img;
img2(img < .005) = mean(img(:));
H = fspecial('disk',10);
img3 = imfilter(img2,H,'symmetric');
img4 = img;
img4(img < .3) = img3(img < .3);
filterSize = 10;
padopt = {'zeros','indexed','symmetric'};
IMG = medfilt2(img4, [1 1]*filterSize, padopt{p});
When you decide to remove outliers, document the excluded data points and explain your reasoning. You must be able to attribute a specific cause for removing outliers. Another approach is to perform the analysis with and without these observations and discuss the differences.
The outlier detection and removal method reduced the variance of the training data. Test accuracy was improved from 63% to 76%, matching the accuracy of clinical judgment of expert burn surgeons, the current gold standard in burn injury assessment.
It's best to remove outliers only when you have a sound reason for doing so. Some outliers represent natural variations in the population, and they should be left as is in your dataset.
I recommend the inpaint_nans contribution from the MATLAB File Exchange
- start as you've already done by replacing outliers with NaN
and use the link to go from there.
From the description of the function:
Interpolate NaN elements in a 2-d array using non-NaN elements. Can also extrapolate, as it does not use a triangulation of the data. Inpaint_nans offers several different approaches to the interpolation, which give tradeoffs in accuracy versus speed and memory required. All the methods currently found in inpaint_nans are based on sparse linear algebra and PDE discretizations. In essence, a PDE is solved to be consistent with the information supplied.
Hooray for reusable code!
Use a function called roifill
. You need to mess with it a little bit. I had to use imdilate
because it interpolates from the boundary.
Code:
testimage = imread('BAPz5.png');
testimage = double(rgb2gray(testimage));
testimage_filt = roifill(testimage,imdilate(testimage<100,true(4)));
figure(1);
subplot(1,2,1);
imshow(testimage,[]);
subplot(1,2,2);
imshow(testimage_filt,[]);
Output:
The post is answered but just for the record, in [1], the author based on a basic principle of natural shapes, i.e., the objects follow a second order smoothness, he suggests an in-painting method that minimize curvature in a least-squares sense. He also offers code. Good luck.
[1] Α Categoty-Level 3-D Object Database: Putting the kineckto Work (ICCV)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With