cv2.fillConvexPoly不完全绘制多边形

2024-04-23 14:44:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我的代码从VIA(VGG IMAGE ANOTATOR)中的注释中读取csv并绘制其区域。 这是绘制区域的代码

df = csv_file[csv_file['region_shape_attributes'] != '{}']
images = []
NAMES = []
p,r,point = 0,0,0
for index, img in enumerate(tqdm(img_list)):
    if int(csv_file.region_count[index]) == 0:
        continue
    lista = csv_file[csv_file.img == img] #Recebe os dados encontrados dentro do csv para a imagem em questão
    tamanho = lista.shape

    if tamanho[0] > 1:
        imagem = cv2.imread(os.path.join(img_dir, img)) #Carrega a imagem em questão
        img_last = img
        # Importa a mascara do indice de vegetacao:
        msk = np.zeros(imagem.shape[:2], dtype = 'uint8') #Carrega as informações do tamanho da imagem
        msk_name = os.path.join(img_dir, img.replace('.JPG', '_msk.png')) #Faz a junção do diretório com o nome da imagem, alterando seu formato
        #print(msk_name) #Apresenta o nome da máscara com o diretório a ser salvo

        for i in range(tamanho[0]):
            line = lista.iloc[i,:] #Recebe todas as marcações realizadas dentro daquela imagem
            region_shape = line.region_shape_attributes #Informa a posição onde o ponto se encontra
            region_attributes = (line.region_attributes) #Informa a classe do ponto
            region_attributes = re.findall('"([^"]*)"', region_attributes) 
            if 'polygon' in region_shape:
                p+=1
                line = region_shape.split("all_points")
                x_coords = [float(s) for s in re.findall(r'-?\d+\.?\d*', line[1])]
                y_coords = [float(s) for s in re.findall(r'-?\d+\.?\d*', line[2])]

                coords = []
                for x, y in zip(x_coords, y_coords):
                    coords.append([x,y])

                pts = np.array(coords, dtype=np.int32)
                cv2.fillConvexPoly(msk, pts, 1)
            elif 'rect' in region_shape:
                continue
                r+=1
                coords = [float(s) for s in re.findall(r'-?\d+\.?\d*', region_shape)] #Encontrando valores de x e y
                cx = int(coords[0]) #Coordenadas no eixo X
                cy = int(coords[1]) #Coordenadas no eixo y
                width = int(coords[2])
                height = int(coords[3])
                cv2.rectangle(msk, (cx-width,cy-height), (cx+width, cy+height), 1, -1)

            elif "\"point\"" in region_shape:
                continue
                point+=1
                coords = [float(s) for s in re.findall(r'-?\d+\.?\d*', region_shape)] #Encontrando valores de x e y
                cx = int(coords[0]) #Coordenadas no eixo X
                cy = int(coords[1]) #Coordenadas no eixo y
                width = 10
                height = 10
                cv2.rectangle(msk, (cx-width,cy-height), (cx+width, cy+height), 1, -1)
        #cv2.imwrite(msk_name, msk.astype('uint8')) #Realiza o salvamento do background
        im_l = [imagem, msk]
        NAMES.append(img)
        images.append(im_l)
        break
print(p,r,point)

为什么尝试传递此图像时出现问题:

Original image

而不是得到这样的东西:

Image in VIA

我明白了:

Output

要点是:

array([[2148,  687],
       [2120,  658],
       [2100,  650],
       [2062,  631],
       [2028,  596],
       [1994,  580],
       [1978,  580],
       [1938,  557],
       [1914,  519],
       [1877,  491],
       [1845,  485],
       [1825,  468],
       [1785,  466],
       [1747,  470],
       [1716,  481],
       [1687,  494],
       [1648,  535],
       [1626,  573],
       [1598,  604],
       [1597,  640],
       [1597,  687],
       [1574,  727],
       [1578,  782],
       [1582,  816],
       [1593,  849],
       [1597,  866],
       [1605,  895],
       [1598,  947],
       [1589,  978],
       [1566, 1043],
       [1546, 1067],
       [1518, 1080],
       [1506, 1104],
       [1482, 1148],
       [1481, 1227],
       [1484, 1251],
       [1498, 1271],
       [1498, 1289],
       [1514, 1310],
       [1544, 1331],
       [1554, 1350],
       [1546, 1433],
       [1536, 1481],
       [1521, 1504],
       [1518, 1548],
       [1510, 1579],
       [1508, 1606],
       [1512, 1647],
       [1493, 1698],
       [1493, 1739],
       [1504, 1752],
       [1525, 1784],
       [1548, 1836],
       [1557, 1853],
       [1574, 1872],
       [1567, 1889],
       [1581, 1917],
       [1563, 1946],
       [1566, 1971],
       [1577, 1978],
       [1577, 1998],
       [1585, 2014],
       [1602, 2032],
       [1621, 2112],
       [1631, 2147],
       [1642, 2184],
       [1647, 2213],
       [1663, 2271],
       [1688, 2305],
       [1720, 2339],
       [1763, 2366],
       [1821, 2394],
       [1846, 2399],
       [1888, 2376],
       [1930, 2185],
       [1946, 2136],
       [1951, 2117],
       [1974, 1993],
       [1805, 1662],
       [2010, 1562],
       [1910, 1425],
       [1993, 1387],
       [1933, 1255],
       [1951,  970],
       [2035, 1215],
       [2163, 1273],
       [2230, 1109],
       [2468, 1104],
       [2581, 1306],
       [2675, 1226],
       [2609, 1118],
       [2588, 1040],
       [2561, 1000],
       [2528,  976],
       [2484,  976],
       [2456,  984],
       [2384,  960],
       [2347,  834],
       [2306,  824],
       [2269,  794],
       [2242,  789],
       [2198,  744],
       [2176,  736],
       [2173,  731]], dtype=int32)

我已经检查了我读到的点是否正确,它们是否正确。 如果调用cv2.polylines(msk, [pts], True, 1)而不是cv2.fillConvexPoly(msk, pts, 1, 10),则会得到所需的输出,但未填充:

with polylines

所以我想知道你们是否能帮我找出为什么fillConvexPoly不能正确填充。我没有找到关于我可以通过函数的点的限制的任何信息,即使我切片数组以减少它,输出也是一样的(cv2.fillConvexPoly(msk, pts[int(pts.shape[0]/2):], 1)):

The same problem using half the array


Tags: csvinimgforlinecoordscv2do
1条回答
网友
1楼 · 发布于 2024-04-23 14:44:45

您可以使用cv2.drawContours()函数来实现这一点。如果你有自己的观点:

points = [[2148,  687],
   [2120,  658],
   [2100,  650],
   [2062,  631],
   [2028,  596],
   [1994,  580],
   [1978,  580],
   [1938,  557],
   [1914,  519],
   [1877,  491],
   [1845,  485],
   [1825,  468],
   [1785,  466],
   [1747,  470],
   [1716,  481],
   [1687,  494],
   [1648,  535],
   [1626,  573],
   [1598,  604],
   [1597,  640],
   [1597,  687],
   [1574,  727],
   [1578,  782],
   [1582,  816],
   [1593,  849],
   [1597,  866],
   [1605,  895],
   [1598,  947],
   [1589,  978],
   [1566, 1043],
   [1546, 1067],
   [1518, 1080],
   [1506, 1104],
   [1482, 1148],
   [1481, 1227],
   [1484, 1251],
   [1498, 1271],
   [1498, 1289],
   [1514, 1310],
   [1544, 1331],
   [1554, 1350],
   [1546, 1433],
   [1536, 1481],
   [1521, 1504],
   [1518, 1548],
   [1510, 1579],
   [1508, 1606],
   [1512, 1647],
   [1493, 1698],
   [1493, 1739],
   [1504, 1752],
   [1525, 1784],
   [1548, 1836],
   [1557, 1853],
   [1574, 1872],
   [1567, 1889],
   [1581, 1917],
   [1563, 1946],
   [1566, 1971],
   [1577, 1978],
   [1577, 1998],
   [1585, 2014],
   [1602, 2032],
   [1621, 2112],
   [1631, 2147],
   [1642, 2184],
   [1647, 2213],
   [1663, 2271],
   [1688, 2305],
   [1720, 2339],
   [1763, 2366],
   [1821, 2394],
   [1846, 2399],
   [1888, 2376],
   [1930, 2185],
   [1946, 2136],
   [1951, 2117],
   [1974, 1993],
   [1805, 1662],
   [2010, 1562],
   [1910, 1425],
   [1993, 1387],
   [1933, 1255],
   [1951,  970],
   [2035, 1215],
   [2163, 1273],
   [2230, 1109],
   [2468, 1104],
   [2581, 1306],
   [2675, 1226],
   [2609, 1118],
   [2588, 1040],
   [2561, 1000],
   [2528,  976],
   [2484,  976],
   [2456,  984],
   [2384,  960],
   [2347,  834],
   [2306,  824],
   [2269,  794],
   [2242,  789],
   [2198,  744],
   [2176,  736],
   [2173,  731]]

然后你可以做:

cv2.drawContours(image, np.array([points]), -1, (1), thickness=-1)

注意注意thickness=-1表示填充轮廓。有关绘制等高线的详细信息,请参见here

输出:

Output of drawing contour

相关问题 更多 >