I would like to remove horizontal black lines on an image:
To do this, I interpolate the RGB values of each column of pixels.
The black line disappear but I think it is possible to optimize this function:
def fillMissingValue(img_in):
img_out = np.copy(img_in)
#Proceed column by column
for i in tqdm(range(img_in.shape[1])):
col = img_in[:,i]
col_r = col[:,0]
col_g = col[:,1]
col_b = col[:,2]
r = interpolate(col_r)
g = interpolate(col_g)
b = interpolate(col_b)
img_out[:,i,0] = r
img_out[:,i,1] = g
img_out[:,i,2] = b
return img_out
def interpolate(y):
x = np.arange(len(y))
idx = np.nonzero(y)
interp = interp1d(x[idx],y[idx],fill_value="extrapolate" )
return interp(x)
if __name__ == "__main__":
img = cv2.imread("lena.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (1024,1024))
start = time.time()
img2 = fillMissingValue(img)
end = time.time()
print("Process time: {}".format(np.round(end-start,3)))
Do you have any ideas ? I thought of doing a prepocessing step by identifying the position of the black lines. And thus only interpolated neighboring pixels. But I don't think it's faster
Current result:


interpolate, for given size of an image,xwill be the same in all calls, no need to recalculate it (and allocate a new array) each time.idxonce for the whole image... and then with a little bit of reshaping do the whole thing in a single call tointerp1d. A quick prototype: pastebin.com/zHxYmdjx -- variant 3 takes 1/6 of the time yours did (without the progress bar).np.nonzeroto differentiate between picture and BLACK line (zero)....