I am trying to come up with an algorithm to count how many objects (microaneurysms, from the IDRiD dataset) are detected by a semantic segmentation model. I have 2 images, 1 of the ground truth mask and 1 of the prediction mask. These are those images.
Then, I used this piece of code to tell whether there are any intersections within the 2 contour maps that I have created of these 2 images.
# gray_pred is the predicted image from the model, gray_gt is the ground truth
gray_pred = cv2.cvtColor(img_binary, cv2.COLOR_BGR2GRAY)
gray_gt = cv2.cvtColor(cropseg_img, cv2.COLOR_BGR2GRAY)
edges_pred = cv2.Canny(gray_pred, 50,200)
contours_pred, _ = cv2.findContours(edges_pred.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2:]
number_of_objects_in_image_pred = len(contours_pred)
print ("The number of objects in this image: ", str(number_of_objects_in_image_pred))
edges_gt = cv2.Canny(gray_gt, 50,200)
contours_gt, _ = cv2.findContours(edges_gt.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2:]
number_of_objects_in_image_gt = len(contours_gt)
print ("The number of objects in this image: ", str(number_of_objects_in_image_gt))
blank_image = np.zeros((2816,3328), np.uint8)
def contourIntersect(contour1, contour2,blank_image):
# Two separate contours trying to check intersection on
contours = [contour1, contour2]
# Create image filled with zeros the same size of original image
# blank = np.zeros(original_image.shape[0:2])
# Copy each contour into its own image and fill it with '1'
image1 = cv2.fillPoly(blank_image.copy(), np.array([contour1],dtype=np.int32), 255)
image2 = cv2.fillPoly(blank_image.copy(), np.array([contour2],dtype=np.int32), 255)
#image1 = cv2.drawContours(blank_image.copy(), contours, 0, 1)
#image2 = cv2.drawContours(blank_image.copy(), contours, 1, 1)
# Use the logical AND operation on the two images
# Since the two images had bitwise and applied to it,
# there should be a '1' or 'True' where there was intersection
# and a '0' or 'False' where it didnt intersect
intersection = cv2.bitwise_and(image1, image2)
# Check if there was a '1' in the intersection
return intersection.any()
# Prediction contour list
contour_list_pred = []
for c in contours_pred:
contour_list_pred.append(c)
cv2.drawContours(combined_img, [c], 0, (0,255,0), 2)
cv2_imshow(combined_img)
# Ground truth contour list
contour_list_gt = []
for c in contours_gt:
contour_list_gt.append(c)
cv2.drawContours(combined_img, [c], 0, (0,255,0), 2)
cv2_imshow(combined_img)
sum_intersect = 0
gt_list = []
for c in range(0,len(contour_list_gt)):
for d in range (0,len(contour_list_pred)):
print(c)
print(d)
if (contourIntersect(contour_list_gt[c],contour_list_pred[d],blank_image)==True):
#if not(gt_list.count(c)>0):
print("True")
gt_list.append(c)
sum_intersect+=1
break
print(sum_intersect)
For some reason, this sum_intersect property doesn't show 23, which is the amount of true positives that I have counted after I have overlayed the prediction image and the ground truth image, as you can see below (red is the ground truth image, pink is the intersection thus the true positive, and white is the predicted image):
![Combined Prediction and
Is there anything wrong with the contourIntersect
function?reference
Additionally, these are the true positives that aren't detected by the cv2.bitwise_and operation: