Reputation: 935
I have the following image:.
Is there a function in OpenCV (preferably Python) that can say that the objects in this picture can be divided into parts. For example, the first object consists of two segments (or two lines), the third one of three (or four).
If OpenCV doesn't have such a thing, it'd be great to know about such an algorithm/function anywhere.
Upvotes: 2
Views: 2088
Reputation: 11951
This problem can be solved by skeletonizing the image and then using HoughlinesP. Scikit-image has a good skeletonization method. It is straight forward to find the 14 lines segments as shown below. Finally you will need to go through and find which sets of lines intersect to see which belong together.
#!/usr/bin/python
from skimage import morphology
import cv2
import math
import numpy as np
im = cv2.imread("objects.png")
dst = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
dst = 1 - dst / 255
dst = morphology.skeletonize(dst).astype(np.uint8)
objs = 255 * dst
#cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])
rho = 1
theta = math.pi / 180
threshold = 1
minLineLength = 3
maxLineGap = 5
lines = np.ndarray([1, 1, 4, 4])
lines = cv2.HoughLinesP(dst, rho, theta, threshold, lines, minLineLength, maxLineGap)
lineColor = (0, 255, 0) # red
for line in lines[0]:
#print line
cv2.line(im, (line[0], line[1]), (line[2], line[3]), lineColor, 1, 8)
#
# Now you need to go through lines and find those that intersect
# You will notice that some lines have small gaps where they should
# join to a perpendicular line. Before find intersections you would
# need to make each line longer (just by adjusting the numbers in lines)
# to get around this problem.
#
cv2.imshow('Objects', objs)
cv2.imshow('Lines', im)
cv2.imwrite('lines.png', im)
cv2.waitKey()
cv2.destroyAllWindows()
Upvotes: 2