I have been trying to come up with a better solution for the quantitative analysis of electronic properties of wafers (photoluminescense to be precise). The kind of measurement doesn't play a role here. What's important to know, there is a geometry on the structures with a well known geometry and I would like to extract the pixel value of each field. In case of the example below, there are 7*7 = 49 square fields, besides the corners, they're all squares. Within each of those 49 fields the pixel values should be constant. Artifacts however, caused by defects in the wafer like dirt on the surface or scratches while handling, impair the material quality, thus lower the pixel values locally. The imaging artifacts are always of LOWER signal, they can't generate a higher signal. These defects influence their surrounding depending on their parameters, so there is a certain "unsharpness" to the information. This diffusion is not a constant however so at this point it makes no sense to try to look for an inverse point spread function or something.
What I'm looking for now is a better way to extract the "true pixel value" of each field, IGNORING the artifacts. I'm certain there should be a workflow or algorithm taking into account the boundary conditions at hand, which is.
- the parameters of the fields are independent from one another so: With artifact-free images one can expect a constant pixel value in each field, the image should be locally flat, see example. That is ignoring the intersection of one field to the next, one would ignore the outermost 10 -20px anyways
- The artifacts have no geometrical correlation to the fields meaning, they can stretch from one to the next or are just locally confined. Thus: Any trend of the signal that changes across fields can with 100% certainty considered an artifact and should therefore be taken into account.
- Artifacts can only cause a decrease in intensity, never an increase!
combined these 'boundary conditions' should be helpful in identifying what the actual value are.
A binary mask or even a pixel weighting based on confidence that the signal is not-impaired is what I'm looking for. Maybe there is also a way to make it an optimization problem, trying to simulate the local values based on the known pattern with locally unknown values. I'd really appreciate any input on the issue!
So far I've tried:
- frequency filtering --> no good since it doesn't 'ignore' bad areas. If at all, it is only effective against either very small dot-like defects or global gradients like a vignette. But those aren't the problem.
- Apply gradient filter then identify areas of lower pixel value surrounded by strong gradients and mask those out. This kind of works when looking at a singular field, however, if the entire field or a large portion of it which spans all the way to the perimeter of the field is affected the method fails.
- Defining defect sizes by hand... basically a cascade of local thresholding, image segmentation and masking. Utterly hard to get a general use case out of it and the results simply aren't very promising
- ImageJ - Subtract Background. One of the subjectively best methods I've found, however, this also attenuates the values to a certain extent which is NOT WANTED. Does anyone know this algorithm that ImageJ uses? At the 'right size', the values of the fields are being ignored yet the artifacts get identified. The input parameter is a 'rolling ball radius'. The useful output is the background and the background is obviously bright since we postulate that the brighter values are the more correct ones. First, I don't actually know what it does but since imageJ is open souce this should be doable. Second though, this still doesn't take into consideration the geometry information which I think should give a great advantage. Strctures that span across fields should be handled better in a final version, see below
example of raw image with 'artifacts' on top of square structures:
marked areas that are 'subjectivelly' giving the right values:
how I currently filter using local gradients
ImageJ > subtract background >rolling ball 50px + light background + create background
ImageJ subtract background rolling ball --> actually correct