python-2.7opencv3.0houghlinesp

How to detect randomly curved non-continuous fixed colored lines from an image?


I am very new in the python openCV. I wanted to find the 7 fixed colored randomly curved lines from an image. The result should be boolean which will give me if the image contains the 7 fixed colored randomly curved lines or not. The sample input image is as below: Sample Input Image

I also wanted to find out the non-continuous faint green colored trapezium from the image. I have written the below code to filter out the specific color from the image but unable to detect the lines & unable to conclude if the image is containing the 7 different lines & trapezium. Below is my sample code for the same:

import cv2
import numpy as np

boundaries = [
    (32, 230, 32),   # 2 Green lines
    (10, 230, 230),  # 1 Yellow line
    (230, 72, 32),   # 1  Blue line
    (255, 255, 255), # 2 White lines
    (32, 72, 230)    # 1 Red line
]

box = [(0, 100, 0), (100, 255, 100)]

image = cv2.imread('testImage5.png')

image = removeBlackBands(image)
# cv2.imshow('Cropped Image', image)
# cv2.waitKey(0)

for row in boundaries:
    # create NumPy arrays from the boundaries
    row = np.array(row, dtype="uint8")

    mask = cv2.inRange(image, row, row)
    cv2.GaussianBlur(mask, (5,5), 0)
    cv2.imshow('Filtered', mask)
    cv2.waitKey(0)

    lines = cv2.HoughLinesP(mask, cv2.HOUGH_PROBABILISTIC, np.pi / 180, 50, 50, 100)
    if lines is not None:
        for x in range(0, len(lines)):
            print("line ", x)
            for x1, y1, x2, y2 in lines[x]:
                print("x1 = {}, y1 = {}, x2 = {}, y2 = {}".format(x1, y1, x2, y2))
                cv2.line(image,(x1,y1),(x2,y2),(0,0, 255),2, cv2.LINE_AA)
                pts = np.array([[x1, y1], [x2, y2]], np.int32)
                cv2.polylines(image, [pts], True, (0, 255, 0))

    cv2.imshow('Processed.jpg', image)
    cv2.waitKey(0)

# create NumPy arrays from the boundaries
lower = np.array(box[0], dtype="uint8")
upper = np.array(box[1], dtype="uint8")

# find the colors within the specified boundaries and apply
# the mask
mask = cv2.inRange(image, lower, upper)
output = cv2.bitwise_and(image, image, mask=mask)
output = cv2.cvtColor(output, cv2.COLOR_BGR2GRAY)
output = cv2.Canny(output, 100, 150)
# show the images
# cv2.imshow("output", output)
# cv2.waitKey(0)
cv2.destroyAllWindows()

Can somebody help me? Thanks in Advance..!!!


Solution

  • This is the function I wrote for the same.

    def detectNodes(self, image, tolerance=0):
    """
    Detect the nodes in the image
    Algorithm used:
        1. Pre-process the image to filter out the required color
        2. Convert the pre-processed image to binary image
    
    Args:
        image(np.ndarray): Numpy Nd array of image
        tolerance: (int): Margin of consideration while extracting color from image. Default: 0
    
    Returns
        True upon success, False otherwise
    
    """
    noOfNodesDetected = 0
    curveWidth = 2
    noOfNodeDetectThreshold = 5
    
    cropH = self.testData["nodalROI"].get("height")
    cropW = self.testData["nodalROI"].get("width")
    roiImage = ppu.crop(image, cropH, cropW)  # Crop node ROI
    
    for color in self.nodalColorBoundaries.keys():
        filtered = ImageProc.colorFilter(roiImage, colors=self.nodalColorBoundaries[color], tolerance=tolerance)
        bgrImage = ppu.convertColorSpace(filtered, "bgr_to_gray")
        thresh = ppu.threshold(bgrImage, 1, "thresh_binary")
    
        logging.info("The shape of image is [{}]".format((thresh.shape)))
        height, width = thresh.shape
    
        pointFraction = self.testData.get("pointsToFormEquationOfCurve", None)
        points = [int(fraction * height) for fraction in pointFraction]
        logging.info("Point using for formulating the equation are [{}]".format(points))
        pointFractionEvaluation = self.testData.get("pointsForEvaluationOfCurve", None)
        pointsForEvaluation_h = [int(fraction * height) for fraction in pointFractionEvaluation]
        logging.info("Point using for Evaluating the equation are [{}]".format(pointsForEvaluation_h))
    
        curve1 = []
        curve2 = []
        for point in points:
            prevX = 0
            flag = 0
            for w in range(0, width):
                if thresh[point][w] == 255:
                    if (abs(prevX - w)) > curveWidth:
                        if flag == 0:
                            curve1.append((point, w))
                            flag = 1
                        else:
                            curve2.append((point, w))
                    prevX = w
    
        fitter = CurveFitter1D()
        if curve2:
            logging.error("Second curve detected with color {} having points {}".format(color, curve2))
    
        if curve1:
            x1 = [point[0] for point in curve1]
            y1 = [point[1] for point in curve1]
            logging.qvsdebug("Points using to find the Polynomial with color {} are {} ".format(color, curve1))
            fitter._fit_polyfit(x1, y1, 4)
            logging.qvsdebug("Coefficient of the Polynomial with color {} are {} ".format(
                color, fitter._fitterNamespace.coefs))
        else:
            logging.error("Points not found with {}".format(color))
            return False
    
        pointsForEvaluation_w = [int(round(fitter._predY_polyfit(point))) for point in pointsForEvaluation_h]
    
        logging.qvsdebug(
            "Points using for the verification of Polynomial representing curve with color {} are {} ".format(
                color, zip(pointsForEvaluation_h, pointsForEvaluation_w)))
        counter = 0
        for i in range(len(pointsForEvaluation_h)):
            if pointsForEvaluation_w[i] + 2 >= width:
                continue  # Continue if control is reaching to width of iamge - 2
            if any(thresh[pointsForEvaluation_h[i]][pointsForEvaluation_w[i] - 2:pointsForEvaluation_w[i] + 3]):
                counter += 1
        logging.info(
            "Out of {} points {} points are detected on the curve for color {}".format(len(pointsForEvaluation_h),
                                                                                       counter, color))
        nodeDetectThreshold = int(len(pointsForEvaluation_h) * 0.6)
        if counter >= nodeDetectThreshold:
            noOfNodesDetected += 1
    
    if noOfNodesDetected >= noOfNodeDetectThreshold:
        logging.info("Nodes found in this frame are [%d], minimum expected [%d]" % (
            noOfNodesDetected, noOfNodeDetectThreshold))
        return True
    else:
        logging.error("Nodes found in this frame are [%d], minimum expected is [%d]" % (
            noOfNodesDetected, noOfNodeDetectThreshold))
        return False