How to identify and measure square ceiling tiles

asked 2020-10-21 06:11:58 -0500

mj1610 gravatar image

I am trying to get line lengths ( in pixels ) from any single ceiling tile from a ceiling full of them. From the line lengths I find, I can then perform additional calculations to find the distance the camera is from that specific tile.

Example of what it looks like:

Example of the lines I want to pick up ( the metal strip that runs between each tile )

I am using OpenCV to do this. I use Hough lines on live camera footage to highlight the individual lines that run between each tile and I can also find the intersect points of these lines using these two methods:

def segmented_intersections(lines):
    # Finds the intersections between groups of lines
    intersections = []
    for i, group in enumerate(lines[:-1]):
        for next_group in lines[i + 1:]:
            for line1 in group:
                for line2 in next_group:
                    foundIntersections = intersection(line1, line2)
                    if foundIntersections is None:
                        # if intersections are outside camera frame , ignore them
                        if foundIntersections[0][0] >= 0 and foundIntersections[0][1] >= 0:
                            if foundIntersections[0][0] <= width and 
                             foundIntersections[0][1] <= height:

    return intersections

def mark_intersections(img, intersections, color=None, markerType=cv2.MARKER_TRIANGLE_UP, markerSize=5):
    color = color or (0, 255, 255) if len(img.shape) == 3 else 255
    for point in intersections:
        if point[0][0] <= intersectionLengthLimit:
            for x, y in point:
                if np.nan in [x, y]:
                    print('Not a number')
                cv2.drawMarker(img, (x, y), color, markerType, markerSize)
    return img

I then filter out some of the intersection points, such as any near the very edge of the frame and any that are within a few pixels of each other. From this I then create a rectangle from those points. Using this code I can get the pixel lengths of the sides:

for (i, j) in zip(range(4), [1, 2, 3, 0]):
                      length = np.sqrt(np.sum((centers[i] - centers[j]) ** 2.0))

The issue I have is that it's very difficult to routinely find 4 correct points of a ceiling tile. I often find the points that get connected are from multiple tiles rather than just 1 singular. This then makes the pixel lengths useless to me. For example:

If I reduce the filtering I perform I end up with way too many points.

This is what I am trying to achieve:

What techniques can I use to help me achieve this ? I don't know if this just isn't possible or if I am not using the correct search terms.

edit retag flag offensive close merge delete



please put your images here, not on an external bin, where they will expire, and render your question useless.

(and please stay away from imgur, which is blocked in several countries)

berak gravatar imageberak ( 2020-10-21 08:01:26 -0500 )edit