Как уже упоминалось ранее, генерация масок из ваших контуров, а затем вычисление парных пересечений, а также «эксклюзивных» деталей из исходных масок, безусловно, даст вам нужные области, но этот подход будет дорогостоящим. также. Исходя из вашего примера изображения и вашего кода, я не мог понять, что вы на самом деле хотите сделать, поэтому я остановлюсь на очень простом примере, иллюстрирующем этот подход.
import cv2
import numpy as np
from matplotlib import pyplot as plt
# Generate some dummy images, whose (main) contours overlap
img1 = cv2.circle(np.zeros((400, 400, 3), np.uint8), (150, 150), 100, (0, 255, 0), cv2.FILLED)
img2 = cv2.rectangle(np.zeros((400, 400, 3), np.uint8), (175, 175), (325, 325), (0, 0, 255), cv2.FILLED)
# Find contours (OpenCV 4.x)
contours1, _ = cv2.findContours(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours2, _ = cv2.findContours(cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# Find contours (OpenCV 3.x)
#_, contours1, _ = cv2.findContours(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
#_, contours2, _ = cv2.findContours(cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# Generate masks of (main) contours; Attention: Hard-coded selection of first contour here!
mask1 = cv2.drawContours(np.zeros((400, 400), np.uint8), [contours1[0]], -1, 255, cv2.FILLED)
mask2 = cv2.drawContours(np.zeros((400, 400), np.uint8), [contours2[0]], -1, 255, cv2.FILLED)
# Find intersection of both masks
mask_combined = cv2.bitwise_and(mask1, mask2)
# Generate "exclusive" masks, i.e. masks without the intersection parts
mask1_excl = cv2.bitwise_xor(mask1, mask_combined)
mask2_excl = cv2.bitwise_xor(mask2, mask_combined)
# Visualization
plt.figure()
plt.subplot(3, 3, 1), plt.imshow(img1), plt.ylabel('img1')
plt.subplot(3, 3, 2), plt.imshow(img2), plt.ylabel('img2')
plt.subplot(3, 3, 3), plt.imshow(img1 + img2), plt.ylabel('img1 + img2')
plt.subplot(3, 3, 4), plt.imshow(mask1, cmap='gray'), plt.ylabel('mask1')
plt.subplot(3, 3, 5), plt.imshow(mask2, cmap='gray'), plt.ylabel('mask2')
plt.subplot(3, 3, 6), plt.imshow(mask_combined, cmap='gray'), plt.ylabel('mask_combined')
plt.subplot(3, 3, 7), plt.imshow(mask1_excl, cmap='gray'), plt.ylabel('mask1_excl')
plt.subplot(3, 3, 8), plt.imshow(mask2_excl, cmap='gray'), plt.ylabel('mask2_excl')
plt.subplot(3, 3, 9), plt.imshow(mask_combined, cmap='gray'), plt.ylabel('mask_combined')
plt.show()
Визуализация:

Теперь это должно быть сделано для каждого набора контуров - не только пар, поскольку вы можете иметь пересечения трех или более контуров. Отслеживание всех этих результирующих масок и т. Д., Скорее всего, будет занимать много памяти, но не слишком дорого в вычислительном отношении. В конце концов, все подходы так или иначе должны будут сохранять результирующие области как какие-то маски.
Надеюсь, это поможет!