gpt4 book ai didi

Python:去除图像中水平黑线的快速方法

转载 作者:行者123 更新时间:2023-12-05 04:35:00 25 4
gpt4 key购买 nike

我想去除图像上的水平黑线:

enter image description here

为此,我对每列像素的 RGB 值进行插值。

黑线消失了,但我认为可以优化这个功能:

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)))

你有什么想法吗?我想通过识别黑线的位置来做一个预处理步骤。因此仅内插相邻像素。但我不认为它更快

当前结果:

enter image description here

最佳答案

interp1d 效率不高。

正如@ChristophRackwitz 在评论中提出的,您可以检测线条的位置并使用 OpenCV 提供的修复方法:

img = cv2.imread('lena.jpg')

# Locate the relatively black lines
threshold = 25
lineIdx = np.where(np.mean(img, axis=(1,2)) < threshold)

# Perform inpainting on the located lines
mask = np.zeros(img.shape[:2], dtype=np.uint8)
mask[lineIdx] = 255

# Actual inpainting.
# Note: using 2 or 1 instead of 3 make the computation
# respectively ~2 and ~4 time faster on my machine but
# the result is not as beautiful with 3.
img2 = cv2.inpaint(img, mask, 3, cv2.INPAINT_NS)

计算部分在我的机器上需要 87 毫秒,而您的代码需要 342 毫秒。请注意,由于 JPEG 压缩,结果不是很好。您可以修复相邻的线(例如 lineIdx-1lineIdx+1),以便以较慢的计算速度为代价获得更好的结果(大约慢 2.5我的机器)。


另一种解决方案是在 Numpy 中自己执行插值:

%%time
# Locate the relatively black lines
threshold = 25
lineIdx = np.where(np.mean(img, axis=(1,2)) < threshold)[0]
lineIdxSet = set(lineIdx)

img2 = img.copy()
start, end = None, None
interpolate = False
for i in range(img.shape[0]+1):
if i in lineIdxSet:
if start is None:
start = i
end = i
else:
if not (start is None):
assert not (end is None)
# The first lines are black
if start <= 0:
i0, i1 = end+1, end+1
# The last lines are black
elif end >= img.shape[0]-1:
i0, i1 = start-1, start-1
# usual case
else:
i0, i1 = start-1, end+1
# The full image is black
if i0 < 0 or i1 >= img.shape[0]:
continue
end = min(end, img.shape[0]-1)
# Actual linear interpolation (of a bloc of lines)
coef = np.linspace(0, 1, end-start+3)[1:-1].reshape(-1, 1)
l0 = img[i0].reshape(-1)
l1 = img[i1].reshape(-1)
img2[start:end+1] = (coef * l0 + (1.0-coef) * l1).reshape(-1, img.shape[1], 3)
start, end = None, None

这段代码在我的机器上只需要 5 毫秒。结果应该与您的原始代码相似,除了它是逐行工作而不是逐列工作,并且每个颜色 channel 的检测不是独立的。请注意,当大块线条为黑色时,修复方法会给出更漂亮的结果。

关于Python:去除图像中水平黑线的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71129710/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com