Findind Cordinates from Contours using OpenCV

206 Views Asked by At

I am working on a project where I have to match a test strip with anolyte card. I am successfully able to get all the contours of the boxes I wish to find, but the code is not working accurately on all images.

Belo is the approach which I am trying right now:-

test_image = cv2.imread('dec_11_3.jpeg', cv2.COLOR_BGR2RGB)
test_image = cv2.resize(test_image, (416, 858))

model = YOLO('New_model_size_Change.pt') #Image segmentation model which i giving me strip and card from my main image 

for i in result:
    x_center1, y_center1, width1, height1 = i.boxes.xywh[0].cpu().numpy()
    x_center2, y_center2, width2, height2 = i.boxes.xywh[1].cpu().numpy()

    x_min1 = int(x_center1 - (width1 / 2))
    y_min1 = int(y_center1 - (height1 / 2))
    x_max1 = int(x_center1 + (width1 / 2))
    y_max1 = int(y_center1 + (height1 / 2))

    x_min2 = int(x_center2 - (width2 / 2))
    y_min2 = int(y_center2 - (height2 / 2))
    x_max2 = int(x_center2 + (width2 / 2))
    y_max2 = int(y_center2 + (height2 / 2))

    card = test_image[y_min1:y_max1, x_min1:x_max1]
    strip = test_image[y_min2:y_max2, x_min2:x_max2]

    card = cv2.cvtColor(card, cv2.COLOR_BGR2RGB)
    strip = cv2.cvtColor(strip, cv2.COLOR_BGR2RGB)

cv2.imwrite("New_Test_Strip2.jpeg", strip)
cv2.imwrite("New_Card2.jpeg", card)

model_strip = YOLO('Strips_Image_Segment_125epochs.pt') #Image segmentation to find color boxes from strips

strip_image = cv2.imread("New_Test_Strip2.jpeg", cv2.COLOR_BGR2RGB)
test_strip = cv2.resize(strip_image, (96, 928))
kernel_sharpening = np.array([[-1,-1,-1],
                              [-1, 9,-1],
                              [-1,-1,-1]])

# applying the sharpening kernel to the image
sharpened_image = cv2.filter2D(test_strip, -1, kernel_sharpening)
dst = cv2.fastNlMeansDenoisingColored(sharpened_image, None, 9, 9, 7, 21)

confidence_threshold = 0.2
result_strip = model_strip.predict(dst, conf = confidence_threshold)

for i in result_strip:
    cordinates = i.boxes.xyxy

xyxy_np = cordinates.numpy()

x1 = xyxy_np[:, 0]
y1 = xyxy_np[:, 1]
x2 = xyxy_np[:, 2]
y2 = xyxy_np[:, 3]

center_x = (x1 + x2) / 2
center_y = (y1 + y2) / 2
width = x2 - x1
height = y2 - y1

x_strip_x = center_x.astype(int)
y_strip_x = center_y.astype(int)

# Strip processing completed till here

card_image = cv2.imread("New_Card2.jpeg", cv2.COLOR_BGR2RGB)
card_new = cv2.resize(card_image, (265, 548))

norm_img = cv2.normalize(card_new,None, alpha=-25, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)

card_grey = cv2.cvtColor(norm_img, cv2.COLOR_BGR2GRAY)
sharp_kernel = np.array([[-1,-1,-1],
                   [-1, 9,-1],
                   [-1,-1,-1]])
sharpened_image_c = cv2.filter2D(card_grey, -1, sharp_kernel)
blurred = cv2.GaussianBlur(sharpened_image_c, (9, 9), 0)
ada_thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)

contours, _ = cv2.findContours(ada_thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_TC89_L1)
contours_new = ()
for contour in contours:
    area = cv2.contourArea(contour)
    if area > 900 and area < 5000:
        contours_new += (contour,)

Till here every image is working fine I am getting len(contours_new) 54 that is the total number of boxes I am having in the card whose cordinates I amtrying to find.

num_rows, num_columns = 10, 7
x_chart = np.full((num_rows, num_columns), np.nan)
y_chart = np.full((num_rows, num_columns), np.nan)
cell_width = card_image.shape[1] // num_columns
cell_height = card_image.shape[0] // num_rows

for contour in contours_new:
    area = cv2.contourArea(contour)
    # if area > 900 and area < 5000:
    x, y, w, h = cv2.boundingRect(contour)

    # Calculate the center point of the box
    x_center = x + w // 2
    y_center = y + h // 2

    # Calculate row and column indices within the grid
    col_index = x_center // cell_width
    row_index = y_center // cell_height
    
    # Ensure the indices are within bounds
    col_index = min(max(col_index, 0), num_columns - 1)
    row_index = min(max(row_index, 0), num_rows - 1)

    # Update the X and Y coordinate arrays
    x_chart[row_index, col_index] = x_center
    y_chart[row_index, col_index] = y_center

strip_digital = np.zeros((10, 1, 3))
chart_digital = np.zeros((10, 7, 3))
for i in range(10):
    strip_digital[i, 0, :] = test_strip[int(y_strip_x[i]), int(x_strip_x[i]), :]
    for j in range(7):
        if not np.isnan(x_chart[i, j]) and not np.isnan(y_chart[i, j]):
            chart_digital[i, j, :] = card_image[int(y_chart[i, j]), int(x_chart[i, j]), :]

Image I am getting correctly from x_strip_x, y_strip_x and x_chart and  y_chart

Sample Image1 sample Image2 Sample Image3

0

There are 0 best solutions below