-1

So I have a grey-scale image (2D matrix with cell values ranging from 0.0 to 1.0). I am manipulating it using python.

I would expect it to have gradual changes of values, but it comes with some clearly undesired 'artifacts', as the one marked in red in the picture bellow (and the others around).

I want to 'remove' the darker artifacts like the one marked in red

Is there an already-implemented library (or known algorithm) that programmatically 'fills' them with somewhat like the 'weighted average of the surrounding pixels'? They can be characterized as 'groups of pixels surrounded by a value gradient of at -0.1 or less'.

adlzanchetta
  • 151
  • 1
  • 14
  • 1
    [OpenCV Inpainting](https://docs.opencv.org/master/df/d3d/tutorial_py_inpainting.html) and [Image inpainting with OpenCV and Python](https://www.pyimagesearch.com/2020/05/18/image-inpainting-with-opencv-and-python/) – furas Sep 09 '20 at 04:19
  • This seems to be what I was looking for. Thank you very much, furas! – adlzanchetta Sep 09 '20 at 12:41

1 Answers1

1

interesting problem, i wrote a program that will recursively loop through the image and smooth out the pixels by averaging them. It looks for absolute values over a certain size, and if detected will average those 2 values rebuilding the matrix. let me know what you think:

from statistics import mean
myimage = [
    [0,0,0,0,.1],
    [0,.1,3,1,.1],
    [1,.1,4,.2,.1],
    [0,1,0,0,.1],
    [.1,.9,0,0,.1]
]
def smooth(matrix, delta):
    noise=0
    reduction=matrix.copy()
    for i,row in enumerate(matrix):
        for j,pixel in enumerate(row):
            if j<len(row)-1:
                if (abs(row[j]-row[j+1]))>=delta:
                    noise=1
                    av = mean([row[j],row[j+1]])
                    mv,iv=max((v,i) for i,v in enumerate((row[j],row[j+1])))
                    if iv==0:
                        reduction[i][j]=av
                    else:
                        reduction[i][j+1]=av
            if i<len(matrix)-1:
                if abs(row[j]-matrix[i+1][j])>=delta:
                    noise=1
                    av = mean([row[j],matrix[i+1][j]])
                    mv,iv=max((v,i) for i,v in enumerate((row[j],matrix[i+1][j])))
                    if iv==0:
                        reduction[i][j]=av
                    else:
                        reduction[i+1][j]=av

    if noise==1:
        return smooth(reduction, delta)
    else:
        return reduction

x=smooth(myimage, 0.5)
for line in x:
    print(line)  


#[0, 0, 0, 0, 0.1]
#[0, 0.1, 0.4, 0.25, 0.1]
#[0.25, 0.1, 0.3625, 0.2, 0.1]
#[0, 0.275, 0, 0, 0.1]
#[0.1, 0.29375, 0, 0, 0.1]
barker
  • 1,005
  • 18
  • 36
  • Thanks for sharing the code with me, barker. But I am not looking for an way to smooth the picture, just to 'fill specific holes'. The inpainting tool suggested by furas is closer to what I was looking for. – adlzanchetta Sep 09 '20 at 12:40