Reputation: 121
I have some images with objects whose bounding boxes are somewhat rotated. I am trying to determine the angle of rotation, and midpoints along the width and height of each object in an image and count the objects if possible. This work was pretty easy for just one object in an image but becomes challenging when there are multiple objects in an image.
I have tried my level best, however, the disadvantage of this method is that the angle appears to be the came 89.37
for all the bounding boxes as shown in the results below. Here are my codes and I look forward to any suggestions on how to go through the task.
codes
a = 45
count = 0
kernel_size = 11
image = cv2.imread(path+'camera1'+str(a)+'.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (kernel_size, kernel_size), 0)
thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1]
erosion = cv2.erode(thresh, kernel = np.ones((kernel_size, kernel_size), np.uint8))
contours = cv2.findContours(erosion, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
result = image.copy()
contours = contours[0] if len(contours) == 2 else contours[1]
for cntr in contours:
x,y,w,h = cv2.boundingRect(cntr)
#cv2.rectangle(result, (x, y), (x+w, y+h), (0, 0, 255), 2)
rect = cv2.minAreaRect(cntr)
box = cv2.boxPoints(rect)
box = np.int0(box)
M = cv2.moments(contours[0])
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
theta = 0.5*np.arctan2(2*M["mu11"],M["mu20"]-M["mu02"])
angle = degrees(theta)
output = [(x, y) for (x, y),in zip(box)]
midupper = (int((output[0][0]+output[1][0])/2),int((output[0][1]+output[1][1])/2))
midlower = (int((output[3][0]+output[2][0])/2),int((output[3][1]+output[2][1])/2))
midleft = (int((output[0][0]+output[3][0])/2),int((output[0][1]+output[3][1])/2))
midright = (int((output[1][0]+output[2][0])/2),int((output[1][1]+output[2][1])/2))
def line_intersection(line1, line2):
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])
def det(a, b):
return a[0] * b[1] - a[1] * b[0]
div = det(xdiff, ydiff)
if div == 0:
raise Exception('lines do not intersect')
d = (det(*line1), det(*line2))
x = det(d, xdiff) / div
y = det(d, ydiff) / div
return x, y
Cx, Cy = line_intersection((midupper, midlower), (midleft, midright))
## Distance between the center of mass and centroid
distance = math.sqrt((int(center[0]) - int(Cx))**2 + (int(center[1]) - int(Cy))**2)
cv2.circle(image, midleft, 2, (0,0,0), 4)
cv2.circle(image, midright, 2, (255,255,255), 4)
cv2.line(image, midupper,midlower, (0, 255, 0), 2)
cv2.line(image, midleft,midright, (0, 255, 0), 2)
cv2.putText(image, "w={},h={}".format(w,h), (x,y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(image, "angle={}".format(round(angle,2)), (x + 200,y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(image, "Cx={},Cy={}".format(int(Cx),int(Cy)), (int(Cx),int(Cy)+40), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.drawContours(image,[box],0,(255,0,0),2)
#cv2.drawContours(result, [box], 0, (255, 10, 10), 2)
cv2.imshow('image', image)
#cv2.imshow('thresh', thresh)
cv2.waitKey(0)
Upvotes: 0
Views: 649
Reputation: 11
Your theta depends only on M and M only on contours[0]. Did you mean to put in cntr there since you are iterating over the elements of contours.
Upvotes: 1