Detect different regions from the image

I have an image and want to detect different regions using OpenCV contouring. The regions very in size.
The resultant image I want is


So, I tried contouring but its difficult to detect all the three mentioned region at a time.
Can anyone suggest me different methods for it, I am trying Template Matching method where I have created different templates and to match it , which works but can these be detected using contouring.
I have my below code for contouring:

image = cv2.imread("dst11.jpg")
new_image = image.copy()
src = cv2.GaussianBlur(image, (3, 3), 0)
imgray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
ret, bw_img = cv2.threshold(imgray,85,255, cv2.THRESH_BINARY)
iin = ~bw_img
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS ,(3,2))
dilation = cv2.dilate(iin,kernel,iterations = 2)
_,contours, hierarchy = cv2.findContours(dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print("Number of Contours found = " + str(len(contours)))
for c in contours:
    perimeter = cv2.arcLength(c,True)
    x, y, w, h = cv2.boundingRect(c)
    if perimeter > 60 and perimeter < 150:
        print(perimeter)
        cv2.rectangle(image,(x,y), (x+w,y+h), (0,0,255), 2)
plt.imshow(image,cmap='gray')
plt.show()

related:

Yes both are the question posted by me.