You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为Faster-RCNN生成混淆矩阵时遭遇Shapely维度错误求助

问题描述

我正尝试为Faster-RCNN目标检测模型生成混淆矩阵,先用简单数组测试时遇到错误,不清楚正确的输入格式。

错误信息

Traceback (most recent call last):
  File "c:\Users\lemon\Desktop\ap_py_2\py_deneme.py", line 9, in <module>
    print(evaluation(grounds,preds,0.5))
  File "c:\Users\lemon\Desktop\ap_py_2\confusion_matrix.py", line 30, in evaluation
    f1=shapely.geometry.Polygon(f1)
  File "C:\Users\lemon\miniconda3\envs\cnn-env-03\lib\site-packages\shapely\geometry\polygon.py", line 229, in __new__
    shell = LinearRing(shell)
  File "C:\Users\lemon\miniconda3\envs\cnn-env-03\lib\site-packages\shapely\geometry\polygon.py", line 103, in __new__
    geom = shapely.linearrings(coordinates)
  File "C:\Users\lemon\miniconda3\envs\cnn-env-03\lib\site-packages\shapely\decorators.py", line 77, in wrapped
    return func(*args, **kwargs)
  File "C:\Users\lemon\miniconda3\envs\cnn-env-03\lib\site-packages\shapely\creation.py", line 173, in linearrings
    return lib.linearrings(coords, out=out, **kwargs)
ValueError: The ordinate (last) dimension should be 2 or 3, got 4

测试代码(test.py)

from confusion_matrix import evaluation
import torch
import numpy as np

pred = [[13,24,25,46], [13,24,25,46], [13,24,25,46]]
ground = [[13,24,25,46],[13,24,25,46],[13,24,25,46]]
preds = np.array(pred)
grounds = np.array(ground)
print(evaluation(grounds,preds,0.5))

混淆矩阵代码(confusion_matrix.py)

#!/usr/bin/env python
# coding: utf-8

import numpy as np
from shapely.geometry import Polygon,Point
import matplotlib.pyplot as plt
import shapely
import cv2 as cv
import os
import gc


def evaluation(ground,pred,iou_value):
  """
  ground= array of ground-truth contours.
  preds = array of predicted contours.
  iou_value= iou treshold for TP and otherwise.
  """
  truth=np.squeeze(ground)
  preds=np.squeeze(pred)
  #we will use this function to check iou less than threshold
  def CheckLess(list1,val):
    return(all(x<=val for x in list1))

  # Using predicted output as the reference
  prob1=[]
  for i in range(len(preds)):
      f1=np.expand_dims(preds[i], axis=0)
      # define a Shapely polygone for prediction i
      f1=shapely.geometry.Polygon(f1)
      # determine the radius
      f1_radius=np.sqrt((f1.area)/np.pi)
      #buffer the polygon fromt the centroid
      f1_buffered=shapely.geometry.Point(f1.centroid).buffer(f1_radius*500)
      cont=[]
      for i in range(len(truth)):
        ff=shapely.geometry.Polygon(np.squeeze(truth[i]))
        if f1_buffered.contains(ff)== True:
          iou=(ff.intersection(f1).area)/(ff.union(f1).area)  
       
          cont.append((iou))

      prob1.append(cont)

  fp=0

  for t in prob1:
    if CheckLess(t,iou_value)==True:
      fp=fp+1
    
  prob2=[]
  #loop through each groun truth instance 
  for i in range(len(truth)):
      f1=truth[i]
      f1=shapely.geometry.Polygon(f1)
      #find radius
      f1_radius=np.sqrt((f1.area)/np.pi)
      #buffer the polygon from the centroid
      f1_buffered=shapely.geometry.Point(f1.centroid).buffer(f1_radius*500)
      cont=[]
      # merge up the ground truth instance against prediction
      # to determine the IoU
      for i in range(len(preds)):
        ff=shapely.geometry.Polygon(np.squeeze(preds[i]))
        if f1_buffered.contains(ff)== True:
          #calculate IoU
          iou=(ff.intersection(f1).area)/(ff.union(f1).area)
          cont.append((iou))
      # probability of a given prediction to be contained in a
      # ground truth instance
      prob2.append(cont)
  fn=0
  tp=0
  for t in prob2:
    if np.sum(t)==0:
      fn=fn+1
    elif CheckLess(t,iou_value)==False:
      tp=tp+1
  
  #lets add this section just to print the results
  print("TP:",tp,"\t FP:",fp,"\t FN:",fn,"\t GT:",truth.shape[0])
  precision=round(tp/(tp+fp),3) 
  recall=round(tp/(tp+fn),3)
  f1= round(2*((precision*recall)/(precision+recall)),3)
  print("Precall:",precision,"\t Recall:",recall, "\t F1 score:",f1)
  
  return tp,fp,fn,precision,recall,f1
解决方法

错误根源是传入的边界框格式不符合shapely.Polygon的要求。当前用的[x1,y1,x2,y2]是矩形的对角坐标,但Polygon需要的是多边形顶点的坐标序列,也就是矩形四个角点的(x,y)对。

比如,[13,24,25,46]代表左上角(13,24)、右下角(25,46)的矩形,需要转换成四个顶点的数组:

[[13,24], [25,24], [25,46], [13,46]]

修改后的测试代码如下:

from confusion_matrix import evaluation
import numpy as np

# 将[x1,y1,x2,y2]转换为矩形四个顶点的坐标序列
def bbox_to_polygon(bbox):
    x1, y1, x2, y2 = bbox
    return [[x1, y1], [x2, y1], [x2, y2], [x1, y2]]

pred_bboxes = [[13,24,25,46], [13,24,25,46], [13,24,25,46]]
ground_bboxes = [[13,24,25,46],[13,24,25,46],[13,24,25,46]]

# 转换为Polygon需要的格式
preds = np.array([bbox_to_polygon(bbox) for bbox in pred_bboxes])
grounds = np.array([bbox_to_polygon(bbox) for bbox in ground_bboxes])

print(evaluation(grounds,preds,0.5))

修改后输入符合shapely.Polygon的要求,能正常计算IoU和混淆矩阵相关指标。

补充:该混淆矩阵代码针对任意多边形轮廓设计,而Faster-RCNN输出的是矩形边界框,所以必须做上述转换才能适配。后续处理模型输出时,记得把每个预测/真实的[x1,y1,x2,y2]都转换成四个顶点的坐标序列。


内容的提问来源于stack exchange,提问作者lawlicat17

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:25:31