我有一张包含黑色像素的图片,可能是垂直线条也可能是简单的点。
我想要用相邻像素(左右)的平均值替换这些像素。
黑色像素的左右邻居都与黑色不同。
目前我的代码如下:
import numpy as np
from matplotlib import pyplot as plt
import time
#Creating test img
test_img = np.full((2048, 2048, 3), dtype = np.uint8, fill_value = (255,127,127))
#Draw vertical black line
test_img[500:1000,1500::12] = (0,0,0)
test_img[1000:1500,1000::24] = (0,0,0)
#Draw black point
test_img[250,250] = (0,0,0)
test_img[300,300] = (0,0,0)
#Fill hole functions
def fill_hole(img):
#Find coords of black pixek
imggray = img[:,:,0]
coords = np.column_stack(np.where(imggray < 1))
print(len(coords))
#Return if no black pixel
if len(coords) == 0:
return img
percent_black = len(coords)/(img.shape[0]*img.shape[1]) * 100
print(percent_black)
#Make a copy of input image
out = np.copy(img)
#Iterate on all black pixels
for p in coords:
#Edge management
if p[0] < 1 or p[0] > img.shape[0] - 1 or p[1] < 1 or p[1] > img.shape[1] - 1:
continue
#Get left and right of each pixel
left = img[p[0], p[1] - 1]
right = img[p[0], p[1] + 1]
#Get new pixel value
r = int((int(left[0])+int(right[0])))/2
g = int((int(left[1])+int(right[1])))/2
b = int((int(left[2])+int(right[2])))/2
out[p[0],p[1]] = [r,g,b]
return out
#Function call
start = time.time()
img = fill_hole(test_img)
end = time.time()
print(end - start)
这段代码在我的示例中运行良好,但是对黑色像素列表进行循环需要一定的时间,具体取决于其大小。
有没有一种方法可以优化它?
inpaint()
函数可以非常快速地实现你想要的效果。https://docs.opencv.org/4.x/d7/d8b/group__photo__inpaint.html#gaedd30dfa0214fec4c88138b51d678085 - Mark Setchell[0.5,0,0.5]
通过黑色像素蒙版应用。 - Mark Setchell