4

I have the image shape image

I am looking for python solution to break the shape in this image into smaller parts according to the contour in the image.

I have looked into solution on Canny and findContours in OpenCV but none of them works for me.

Edit:

Code used:

using Canny method

import cv2 import numpy as np

img = cv2.imread('area_of_blob_maxcontrast_white.jpg') edges = cv2.Canny(img, 100, 200)
cv2.imwrite('area_of_blob_maxcontrast_white_edges.jpg',edges)

using findContours method

import numpy as np 
import argparse 
import cv2

image = cv2.imread('area_of_blob_maxcontrast_white.png')

lower = np.array([0, 0, 0]) upper = np.array([15, 15, 15]) shapeMask = cv2.inRange(image, lower, upper)

(_,cnts, _) = cv2.findContours(shapeMask.copy(), cv2.RETR_EXTERNAL,
                            cv2.CHAIN_APPROX_SIMPLE) print "I found %d black shapes" % (len(cnts)) cv2.imshow("Mask", shapeMask)

for c in cnts:
    # draw the contour and show it
    cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
    cv2.imshow("Image", image)
    cv2.waitKey(0)
3
  • 3
    Please share a sample code of your attempts so people can find and point out where your code needs to be changed. Commented Jul 5, 2018 at 4:36
  • Where is the image.? Commented Jul 5, 2018 at 6:10
  • this is the link to the image: i.sstatic.net/dVBTT.jpg Commented Jul 5, 2018 at 9:43

1 Answer 1

6

The trick is to make your faint single pixel boundary slightly bolder. I do it by changing any white pixel that has two adjacent black pixels (above, below, to the left or to the right) to black. (I do it extremely slow, though. I'm pretty sure there must be a smarter way to do it with OpenCV or Numpy.)

Here is my code:

#!/usr/bin/env python 

import numpy as np
import cv2

THRESH = 240

orig = cv2.imread("map.png")
img = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)

# Make the faint 1-pixel boundary bolder
rows, cols = img.shape
new_img = np.full_like(img, 255)    # pure white image
for y in range(rows):
    if not (y % 10):
        print ('Row = %d (%.2f%%)' % (y, 100.*y/rows))
    for x in range(cols):
        score  = 1 if y > 0 and img.item(y-1, x) < THRESH else 0
        score += 1 if x > 0 and img.item(y, x-1) < THRESH else 0
        score += 1 if y < rows-1 and img.item(y+1, x) < THRESH else 0
        score += 1 if x < cols-1 and img.item(y, x+1) < THRESH else 0
        if img.item(y, x) < THRESH or score >= 2:
            new_img[y, x] = 0       # black pixels show boundary

cv2.imwrite('thresh.png', new_img)

# Find all contours on the map
_th, contours, hierarchy = cv2.findContours(new_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
print "Number of contours detected = %d" % len(contours)

# Fill second level regions on the map
coln = 0
colors = [
    [127, 0, 255],
    [255, 0, 127],
    [255, 127, 0],
    [127, 255, 0],
    [0, 127, 255],
    [0, 255, 127],
]
hierarchy = hierarchy[0]
for i in range(len(contours)):
    area = cv2.contourArea(contours[i])
    if hierarchy[i][3] == 1:
        print (i, area)
        coln = (coln + 1) % len(colors)
        cv2.drawContours(orig, contours, i, colors[coln], -1)

cv2.imwrite("colored_map.png", orig)

Input image:

Faint outline of regions

Output image:

Map with four colored regions

Here I color only the direct descendants of the outmost contour (hierarchy[i][3] == 1). But you can change it to exclude the lakes.

Sign up to request clarification or add additional context in comments.

10 Comments

Thanks Andriy, that's what I am looking for.
@Esther, I'm glad it helped. Please, consider choosing my answer as "Best answer".
sorry, i am new to using this. May I know how should i do that to choose your answer as Best answer
@Esther, "To mark an answer as accepted, click on the check mark beside the answer to toggle it from hollow to green". See this screenshot.
NOTE: faster way to make the border bolder would be to apply a custom kernel [[0,1,0],[1,0,1],[0,1,0]] with cv2.filter2D function to compute the score as a matrix.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.