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]), :]



