Home > Blockchain >  How to compare two point of two objects
How to compare two point of two objects

Time:02-03

My purpose is to check whether these cubes are in one column or not. Having problem with detecting objects properly. not sure why numbers are placed there like that. My main questions:

  1. How to compare two point of two objects to check if they are fit well or not?
  2. How can I improve detecting objects?

Thanks in advance.

enter image description here enter image description here

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)

CodePudding user response:

Since the boxes are touching each other, watershed algorithm works well in this cases to extract the box contours. Then the x coordinates position of the rectangle contours can be used to say whether they are aligned or not.

Steps:

  1. Watershed algorithm to get markers.
  2. Filter out boxes(rectangles)
  3. To see if its aligned or not using standard deviation of all the boxes x coordinates. (the threshold can be set accordingly)

Code:

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)

Output:

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

enter image description here

  •  Tags:  
  • Related