如何比较两个对象的两个点

How to compare two point of two objects

我的目的是检查这些立方体是否在一列中。正确检测对象有问题。不知道为什么数字会那样放在那里。我的主要问题:

  1. 如何比较两个对象的两个点来检查它们是否合适?
  2. 如何改进对象检测?

提前致谢。

import cv2

image = cv2.imread('test1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(
    thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cv2.imshow('Canny Edges', thresh)

for (i, c) in enumerate(contours):
    ((x, y), _) = cv2.minEnclosingCircle(c)
    cv2.putText(image, "#{}".format(i + 1), (int(x) + 0, int(y) + 0),
        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)
    cv2.drawContours(image, [c], -1, (0, 255, 0), 2)

cv2.imshow('Contours', image)
cv2.waitKey(0)

由于盒子相互接触,分水岭算法在这种情况下可以很好地提取盒子轮廓。然后矩形轮廓的x坐标位置可以用来表示它们是否对齐。

步骤:

  1. 分水岭算法获取标记。
  2. 过滤掉方框(矩形)
  3. 使用所有方框 x 坐标的标准差来查看其是否对齐。 (阈值可以相应设置)

代码:

import cv2
import numpy as np


def watershed_algorithm(image):

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    # noise removal
    kernel = np.ones((5,5),np.uint8)
    opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

    # sure background area
    sure_bg = cv2.dilate(opening,kernel,iterations=3)

    # Finding sure foreground area
    dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
    ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

    # Finding unknown regio3
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg,sure_fg)

    # Marker labelling
    ret, markers = cv2.connectedComponents(sure_fg)

    # Add one to all labels so that sure background is not 0, but 1
    markers = markers+1

    # Now, mark the region of unknown with zero
    markers[unknown==255] = 0

    markers = cv2.watershed(image,markers)
    
    return markers

def is_rect_contour(contour):
    peri = cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, 0.04 * peri, True)
    if len(approx) == 4:
        return True
    else:
        return False
    
def get_rectangle_contours(markers, shape):
    rectangle_contours = []
    
    for marker in np.unique(markers):
        if marker == 0 or marker==-1:
            continue
        mask = np.zeros(shape, dtype="uint8")
        mask[markers == marker] = 255
        cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
            cv2.CHAIN_APPROX_SIMPLE)
        c = max(cnts[0], key=cv2.contourArea)
        if is_rect_contour(c):
            rectangle_contours.append(c)
    
    return rectangle_contours

def draw_and_display_contours(contours, image):
    for i,c in enumerate(contours):
        (x, y, w, h) = cv2.boundingRect(c)
        cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
        cv2.putText(image, "#{}".format(i+1), (int(x) - 10, int(y)),
            cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
    
    cv2.imshow('Contours', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
def is_boxes_aligned(rectangle_contours):
    x_coord_list = []
    for c in rectangle_contours:
        (x, y, w, h) = cv2.boundingRect(c)
        x_coord_list.append(x)
    
    threshold_std_deviation_in_X_coordinates = 10
    if np.std(x_coord_list) < threshold_std_deviation_in_X_coordinates:
        print("Box are aligned in same column with a standard deviation of {}".format(np.std(x_coord_list)))
    else:
        print("Box are not aligned in same column")

    

image = cv2.imread("./cubes.jpg")
markers = watershed_algorithm(image)
rectangle_contours = get_rectangle_contours(markers, image.shape[:2])
draw_and_display_contours(rectangle_contours,image)
is_boxes_aligned(rectangle_contours)

输出:

Box are aligned in same column with a standard deviation of 4.027681991198191