OPENCV如何完成缺少的矩形?

时间:2018-07-31 20:48:55

标签: python opencv

我的问题太简单了。我有一个这样的矩形。我想填补这个广场的缺失部分。我还需要缺少零件的坐标。我怎样才能做到这一点? Rectangle

我应该像经过处理的第二张图片。Second Image

1 个答案:

答案 0 :(得分:2)

以下是此方法的摘要:

  1. 逐行水平扫描
  2. 按col垂直扫描col
  3. 准备潜在点列表
  4. 按距离分组点
  5. 在子分组点周围找到边界框
  6. 计算矩形,并忽略那些接触图像边界的矩形。

源代码:

首先,导入所需的库。

import numpy as np
import cv2

第二,定义一个计算两点之间距离的函数,更重要的是,它允许您决定是否要在终端中打印“太简单”

def too_easy_distance(pt1, pt2, is_print=False):
    if is_print: print ("too easy!")
    return ((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2) ** 0.5

第三,加载图像并找出宽度和高度。

img = cv2.imread("broken_rect.png", 0)
height, width = img.shape[:2]
active_threshold = 25   # adjust this parameter based on the thickness of borders
potential_pts = []

现在,逐行水平扫描图像。

for i in range(height):
    if len (np.where(img[i:i+1,:]==0)[1] ) < active_threshold:
        continue
    is_start = False
    is_real_start = False
    for j in range(width):
        if img[i,j] == 0 and is_start is False:
            is_start = True
            continue
        # Enter the valid region
        if is_start and is_real_start is False:
            if img[i,j] == 255:
                is_real_start = True
            else:
                is_real_start = False

        if is_real_start:
            if img[i,j] == 255:
                potential_pts.append((j, i)) 
            else:
                is_real_start = False

然后,逐列垂直扫描图像。

for j in range(width):
    if len (np.where(img[:, j:j+1]==0)[1] ) < active_threshold:
        continue
    is_start = False
    is_real_start = False
    for i in range(height):
        if img[i,j] == 0 and is_start is False:
            is_start = True
            continue
        # Enter the valid region
        if is_start and is_real_start is False:
            if img[i,j] == 255:
                is_real_start = True
            else:
                is_real_start = False

        if is_real_start:
            if img[i,j] == 255:
                potential_pts.append((j, i))
            else:
                is_real_start = False

最后,对列表进行排序并显示结果图像。

grouped_pts = []  #list of list
for pt in potential_pts:
    if len(grouped_pts) == 0:
        grouped_pts.append([pt])  # create a new sublist and add pt to the new sublist
    # enter the grouped_pts loop
    is_found_place = False
    for sublist in grouped_pts:
        for prev_pt in sublist:
            if too_easy_distance(pt, prev_pt) < 2:
                sublist.append(pt) # add to the list
                is_found_place = True
                break
    # if nothing happend
    if is_found_place is False:
        grouped_pts.append([pt]) # create a new sublist and add pt to the new sublist

result_image = cv2.cvtColor(img.copy(), cv2.COLOR_GRAY2RGB)

for sublist in grouped_pts:
    x,y,w,h = cv2.boundingRect(np.array(sublist))
    if x == 0 or y == 0 or x+w == width or y+h == height:
        continue

    rect = ((x, y), (x+w-1, y+h-1))
    cv2.rectangle(result_image, rect[0], rect[1], (0,255,0), -1)
    print ("Rect Found! [Top-Left]: " + str(rect[0]) + " [Bottom-Right]: " + str([rect[1]]) )

cv2.imshow("result_image", result_image)
cv2.waitKey()

结果图片: Result Image

端子输出:

Rect Found! [Top-Left]: (267, 62) [Bottom-Right]: [(313, 69)]
Rect Found! [Top-Left]: (552, 327) [Bottom-Right]: [(559, 364)]