Python for contour fitting

Problem Description

Calculate the center of gravity and area of ​​each red five-pointed star extracted in the previous blog, and then use the value depending on the area as the side length, draw a square on the five-pointed star for contour fitting, compare and use the function for contour fitting Effect
insert image description here


contour fitting

Calculate the center of gravity and area of ​​each pentagram. Here, the previous label information is used to calculate the center of gravity, and the pixel coordinates belonging to the same label are obtained, and then put into np.array to obtain the position of the center of gravity by using np.mean. When calculating the area It is to count the number of pixels of each entity, and the final result is as follows:

# 计算重心和面积
core_point = []
areas = np.zeros(num + 1, dtype=np.int32)
points = []
for i in range(num+1):
    points.append([])
for i in range(h):
    for j in range(w):
        for u in range(1, num+1):
            if img_flag[i][j] == u:
                points[u].append([i, j])
        areas[img_flag[i][j]] += 1

# 得到重心
for i in range(1, num+1):
    tem_point = np.mean(np.asarray(points[i]), axis=0).astype(np.int32)
    core_point.append(tem_point)
    print('第' + str(i) + '个五角星的重心为:' + str(core_point[i-1]))
    print('第' + str(i) + '个五角星的面积为:' + str(areas[i]))

insert image description here

Then fit the contour. First, use the center of gravity and area to fit. Here, the side length of the contour is obtained by taking the square root of the area, and then the coordinates of the center of gravity minus half of the side length are used to obtain the x and x of the initial drawing point. The y coordinate, and then use the coordinates of the center of gravity plus the side length to obtain the coordinates of the end drawing point, thus completing the process of drawing through the center of gravity and area. Then use cv2.findContours + cv2.boundingRect to draw the image, and the results are

# 根据重心和面积绘制轮廓
x = []
img3 = pro_img.copy()
for i in range(num):
    l = int(math.sqrt(areas[i+1]) / 2)
    x.append([int(core_point[i][0])-l, int(core_point[i][1])-l, 2*l])
    cv2.rectangle(img3, (x[i][1], x[i][0]), (x[i][1] + x[i][2], x[i][0] + x[i][2]), (127, 0, 0), 2)  # 在img3中绘制矩形边框,并注明轮廓颜色与粗细

insert image description here

The result obtained by using the function is shown in the figure below. From the results, it can be seen that the drawing results of the two methods are different. The outline drawn by using the function surrounds all the pixels of the image, while the outline drawn by using the area and center of gravity is only Contains the middle part of the image, and does not surround all the pixels. Therefore, the area of ​​the outline drawn by the two is different, and the focus is also different. The purpose of drawing with the function is to surround the entire image, while the use of the area and center of gravity is to selectively surround the most central part, and the drawn area is smaller. Focus on The point is mainly the center of the image.

# 利用cv2.findContours + cv2.boundingRect绘制轮廓
contours, hierarchy = cv2.findContours(pro_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)  # 查找检测物体的轮廓,cv2.RETR_TREE检测所有轮廓,并将轮廓记录到contours
img4 = pro_img.copy()
for i in range(len(contours)):
    x, y, w, h = cv2.boundingRect(contours[i])                      # 矩形轮廓拟合,采用第0层轮廓,返回矩阵左上点坐标与矩阵的宽和高
    cv2.rectangle(img4, (x, y), (x + w, y + h), (255, 0, 0), 5)     # 在img4中绘制矩形边框,并注明轮廓颜色与粗细
cv2.imshow('func_rectangle', img4)

insert image description here

Guess you like

Origin blog.csdn.net/qq_48068259/article/details/127678189