如何确定图像中旋转边界框的角度、中心和中点?

问题描述 投票:0回答:1

我有一些物体的图像,其边界框有些旋转。我试图确定图像中每个对象的旋转角度以及宽度和高度的中点,并在可能的情况下对对象进行计数。对于图像中的一个对象来说,这项工作非常容易,但当图像中存在多个对象时,这项工作就变得具有挑战性。 我已经尽力了,但是,这种方法的缺点是,对于所有边界框来说,角度似乎都是

89.37
,如下图所示。这是我的代码,我期待任何有关如何完成任务的建议。

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)
python opencv image-processing computer-vision
1个回答
1
投票

你的 theta 仅取决于 M,M 仅取决于轮廓 [0]。因为您正在迭代轮廓的元素,所以您是否打算在那里放入 cntr?

© www.soinside.com 2019 - 2024. All rights reserved.