在蒙版帧中填充 holes/blocks

Fill holes/blocks in masked frames

我想根据特定条件在我的蒙版图像中填充 "holes"。我有以下原始 frame

接下来,我在此帧上应用蒙版,从而得到 masked:

现在我想将帧分成 16x16 块。为了定义block(x,y),我们定义了一组像素在x-thy-th块中的垂直和水平方向。 如果块内黑色像素的百分比 larger (smaller)0.5,则该块被定义为 non-field (field)。代码如下所示:

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 returns 如下:

 (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

我不确定这是否是最快的方法?