我想根据某些标准填充蒙版图像中的“孔”。我有以下原始的frame
:
接下来,我在此帧上应用蒙版,得到masked
:
现在我想将帧分成16x16块。为了定义block(x,y)
,我们在垂直和水平方向上的x-th和y-th块中定义了一组像素。如果块内黑色像素的百分比为non-field (field)
而不是larger (smaller)
,则将该块定义为0.5
。代码如下:
def blocked_img(img, x_pixels, y_pixels):
blocked = img.copy()
gray = cv2.cvtColor(blocked, cv2.COLOR_BGR2GRAY)
for x in range(0, blocked.shape[1], x_pixels):
for y in range(0, blocked.shape[0], y_pixels):
block = gray[y:y+y_pixels, x:x+x_pixels]
if (cv2.countNonZero(block) / block.size) < 0.5:
# non-field
cv2.rectangle(blocked, (x, y), (x+x_pixels, y+y_pixels), (0,255,255), 2)
else:
# field
break
return blocked
masked.shape
返回以下内容:
(720, 1280, 3)
因此,我使用以下命令调用函数blocked_img
:
blocked = blocked_img(masked, 80, 45) # divide by 16
blocked
输出看起来如下:
目前,编写我的代码是,一旦没有达到0.5-threshold
,它就会循环到下一行。可以看出,在右边的列中,此方法过早停止(准确地说是第9、11、12、13、16列),因此无法产生理想的结果]
如果要满足以下两个条件之一,我想在列中继续循环:
重写,
block(x,y) = 1 if [block(x-1,y) = 1 and {block(x+1,y) = 1 or block(x+2,y) = 1}] or [{block(x-2, y) = 1 or block(x-1, y) = 1} and block(x+1, y) = 1] # where 1 = non-field
您知道如何将其包含在代码中吗?预先感谢!
我建议您多次遍历您的块。这就是我的想法-
def blocked_img(img, x_pixels, y_pixels):
blocked = img.copy()
blocks = np.zeros((blocked.shape[1]//x_pixels,blocked.shape[0]//y_pixels)) ##array to keep track of blocks status
gray = cv2.cvtColor(blocked, cv2.COLOR_BGR2GRAY)
prev_num_blocks = np.sum(blocks)
for x in range(0, blocked.shape[1], x_pixels):
for y in range(0, blocked.shape[0], y_pixels):
block = gray[y:y+y_pixels, x:x+x_pixels]
if (cv2.countNonZero(block) / block.size) < 0.5:
# non-field
cv2.rectangle(blocked, (x, y), (x+x_pixels, y+y_pixels), (0,255,255), 2)
blocks[x,y] = 1
else:
# field
continue
while (np.sum(blocks)>prev_num_blocks): ##keep going unless no change occurs in prev loop
for x in range(2, blocks.shape[0]-2, x_pixels):
for y in range(2, blocks.shape[1]-2, y_pixels):
###the advance update rule here
if (.....):
blocks[x,y]=1
cv2.rectangle(blocked,...) ##recreate the rect indices using the x,y
return blocked
从我的角度来看,需要使用while循环,因为在周期1中将块状态更改为非字段会影响列中它之前的块,因为它成为其他块的next_block和next_next块。
这可能不是最有效的方法,但是肯定会收敛并退出while循环。
def blocked_img(img, x_pixels, y_pixels):
blocked = img.copy()
gray = cv2.cvtColor(blocked, cv2.COLOR_BGR2GRAY)
for x in range(0, blocked.shape[1], x_pixels):
for y in range(0, blocked.shape[0], y_pixels):
block = gray[y:y+y_pixels, x:x+x_pixels]
next_block = gray[y+y_pixels:y+(2*y_pixels), x:x+x_pixels]
next_next_block = gray[y+(2*y_pixels):y+(3*y_pixels), x:x+x_pixels]
if (cv2.countNonZero(block) / block.size) < 0.75:
# non-field
cv2.rectangle(blocked, (x, y), (x+x_pixels, y+y_pixels), (0,0,0), -1)
else:
if ((cv2.countNonZero(next_block) / block.size) < 0.75) or ((cv2.countNonZero(next_next_block) / block.size) < 0.75):
# non-field
cv2.rectangle(blocked, (x, y), (x+x_pixels, y+y_pixels), (0,0,0), -1)
else:
# field
break
return blocked
我不确定这是否是最快的方法吗?