我被要求使用 OpenCV python 开发一个图像处理管道,从植物图像数据集中分割一朵花,并评估使用地面真实图像生成的图像。然而,每当我面对地面真实图像,其边缘将接触图像的边界时,评估就会出错并产生非常小的相似度分数。有什么解决办法吗?
评估代码
# Function to find the largest contour which is assumed to be the flower
def find_largest_contour(binary_image):
# Find contours from the binary image
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if contours:
return max(contours, key=cv2.contourArea)
else:
return None
# Function to calculate the Intersection over Union
def calculate_iou(contourA, contourB, shape):
maskA = np.zeros(shape, dtype=np.uint8)
maskB = np.zeros(shape, dtype=np.uint8)
cv2.drawContours(maskA, [contourA], -1, color=255, thickness=cv2.FILLED)
cv2.drawContours(maskB, [contourB], -1, color=255, thickness=cv2.FILLED)
intersection = np.logical_and(maskA, maskB)
union = np.logical_or(maskA, maskB)
iou_score = np.sum(intersection) / np.sum(union)
return iou_score
# Function to display similarity percentage based on IoU
def display_similarity(image_name, iou_score):
similarity_percentage = round(iou_score, 2)
print(f"Similarity for {image_name}: {similarity_percentage}%")
# Apply the processing and calculate IoU for each image
ious = []
for input_path, ground_truth_path in zip(image_paths, ground_truth_image_paths):
image_name = os.path.basename(input_path)
original_image = cv2.imread(input_path) # Read the original image again for visualization
processed_image = process_image(input_path, image_name)
show_binary_image(processed_image, window_name=f"Binary: {image_name}")
ground_truth_image = cv2.imread(ground_truth_path, cv2.IMREAD_GRAYSCALE)
show_binary_image(ground_truth_image, window_name=f"Binary: {image_name}")
if processed_image.shape != ground_truth_image.shape:
ground_truth_image = cv2.resize(ground_truth_image, (processed_image.shape[1], processed_image.shape[0]))
# Find largest contours
contour_processed = find_largest_contour(processed_image)
contours_ground_truth = process_red_edges(ground_truth_path) # Fix: Pass path instead of image
# Find the largest contour among the contours found
contour_ground_truth = max(contours_ground_truth, key=cv2.contourArea)
# Calculate IoU
iou_score = calculate_iou(contour_processed, contour_ground_truth, ground_truth_image.shape) * 100
ious.append(iou_score)
如图所示,地面真值图像的花朵前景的顶部和底部的侧面都接触到图像窗口的边框,并且在运行代码时,它只给出了 1.58% 的相似度,而其他没有其边缘的图像接触图像窗口边界的边缘具有 >90% 的相似度。
这只是写的,没有实际运行它:
GT = cv.imread("GT.png", cv.IMREAD_GRAYSCALE)
GT_negative = cv.inRange(GT, 100, 125)
GT_positive = cv.inRange(GT, 25, 50)
GT_dontcare = cv.inRange(GT, 0, 25)
subj = cv.imread("subject.png", cv.IMREAD_GRAYSCALE)
(_, subj) = cv.threshold(subj, 128, 255, cv.THRESH_BINARY)
def intersection_over_GT(GT, test):
intersection = cv.bitwise_and(GT, test)
return cv.countNonZero(intersection) / cv.countNonZero(GT)
positive_ratio = intersection_over_GT(GT_positive, subj) # 0.99175
negative_ratio = intersection_over_GT(GT_negative, cv.bitwise_not(subj)) # 0.99997
就这样,近乎完美。它并不完美,至少部分是因为您向我们提供的屏幕截图在图像边缘包含碎片。