Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

How to identify and measure square ceiling tiles

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:

https://www.ceilingtilesuk.co.uk/wp-content/uploads/2018/10/Ceiling-Tiles-UK-Suspended-Ceiling.jpg

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

https://www.industrialsuppliesco.co.uk/uploads/products/suspended-ceiling-tiles-square-edge-595-x-595mm-10-per-box-600-x-600402361.jpg

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:
                        pass
                    else:
                        # 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:
                                intersections.append(foundIntersections)

    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')
                    continue
                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:

https://imgur.com/xSpWSwr

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

This is what I am trying to achieve:

https://imgur.com/JB0vKA9

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.