目标检测基础与R-CNN实现
立即解锁
发布时间: 2025-09-01 01:57:40 阅读量: 4 订阅数: 12 AIGC 

### 目标检测基础与R-CNN实现
目标检测是计算机视觉领域的重要任务,旨在识别图像中物体的类别和位置。本文将介绍目标检测的基本概念,如平均精度均值(mAP),并详细阐述基于区域的卷积神经网络(R-CNN)的工作原理和在自定义数据集上的实现步骤。
#### 1. 平均精度均值(mAP)
在目标检测中,我们不仅要得到图像中每个物体的边界框和对应的类别,还需要量化模型预测的准确性。mAP在这种情况下发挥了重要作用。在理解mAP之前,我们需要先了解精度(Precision)和平均精度(Average Precision)。
- **精度(Precision)**:通常计算方式为正确预测的正样本数除以所有预测为正样本的数量。真正例(True Positive)指的是预测出正确物体类别且与真实边界框的交并比(IoU)大于某个阈值的边界框;假正例(False Positive)则是预测类别错误或与真实边界框的重叠小于定义阈值的边界框。如果对于同一个真实边界框有多个预测边界框,只有一个可以是真正例,其余都是假正例。
- **平均精度(Average Precision)**:是在不同IoU阈值下计算的精度值的平均值。
- **平均精度均值(mAP)**:是在数据集中所有物体类别上,不同IoU阈值下计算的精度值的平均值。
#### 2. R-CNN工作原理
R-CNN即基于区域的卷积神经网络,用于识别图像中的物体及其位置。其工作步骤如下:
```mermaid
graph LR
A[提取区域建议] --> B[调整区域大小]
B --> C[通过网络提取特征]
C --> D[创建训练数据]
D --> E[连接输出头]
E --> F[训练模型]
```
1. **提取区域建议**:从图像中提取大量的区域建议,以确保不遗漏任何潜在的物体。
2. **调整区域大小**:将所有提取的区域调整为相同的大小。
3. **通过网络提取特征**:将调整大小后的区域建议通过预训练模型(如VGG16或ResNet50),并在全连接层中提取特征。
4. **创建训练数据**:输入是通过预训练模型提取的区域建议特征,输出是每个区域建议对应的类别和与真实边界框的偏移量。如果区域建议与物体的IoU大于特定阈值,则创建训练数据。
5. **连接输出头**:连接两个输出头,一个对应图像的类别,另一个对应区域建议与真实边界框的偏移量,以提取物体的精确边界框。
6. **训练模型**:编写自定义损失函数,最小化物体分类误差和边界框偏移误差。
#### 3. 在自定义数据集上实现R-CNN
在自定义数据集上实现R-CNN需要完成以下步骤:
1. **下载数据集**:从Google Open Images v6数据集下载数据,但在代码中仅使用巴士或卡车的图像。
```python
%pip install -q --upgrade selectivesearch torch_snippets
from torch_snippets import *
import selectivesearch
from google.colab import files
files.upload() # upload kaggle.json file
!mkdir -p ~/.kaggle
!mv kaggle.json ~/.kaggle/
!ls ~/.kaggle
!chmod 600 /root/.kaggle/kaggle.json
!kaggle datasets download -d sixhky/open-images-bus-trucks/
!unzip -qq open-images-bus-trucks.zip
from torchvision import transforms, models, datasets
from torch_snippets import Report
from torchvision.ops import nms
device = 'cuda' if torch.cuda.is_available() else 'cpu'
```
2. **准备数据集**:
- 提取每个图像及其对应的类别和边界框值。
- 提取每个图像内的区域建议、对应的IoU和区域建议相对于真实边界框的校正量。
- 为每个类别分配数字标签。
- 将每个区域建议调整为相同的大小。
```python
IMAGE_ROOT = 'images/images'
DF_RAW = pd.read_csv('df.csv')
print(DF_RAW.head())
class OpenImages(Dataset):
def __init__(self, df, image_folder=IMAGE_ROOT):
self.root = image_folder
self.df = df
self.unique_images = df['ImageID'].unique()
def __len__(self): return len(self.unique_images)
def __getitem__(self, ix):
image_id = self.unique_images[ix]
image_path = f'{self.root}/{image_id}.jpg'
image = cv2.imread(image_path, 1)[...,::-1]
h, w, _ = image.shape
df = self.df.copy()
df = df[df['ImageID'] == image_id]
boxes = df['XMin,YMin,XMax,YMax'.split(',')].values
boxes = (boxes*np.array([w,h,w,h])).astype(np.uint16).tolist()
classes = df['LabelName'].values.tolist()
return image, boxes, classes, image_path
ds = OpenImages(df=DF_RAW)
im, bbs, clss, _ = ds[9]
show(im, bbs=bbs, texts=clss, sz=10)
def extract_candidates(img):
img_lbl,regions = selectivesearch.selective_search(img, scale=200, min_size=100)
img_area = np.prod(img.shape[:2])
candidates = []
for r in regions:
if r['rect'] in candidates: continue
if r['size'] < (0.05*img_area): continue
if r['size'] > (1*img_area): continue
x, y, w, h = r['rect']
candidates.append(list(r['rect']))
return candidates
def extract_iou(boxA, boxB, epsilon=1e-5):
x1 = max(boxA[0], boxB[0])
```
0
0
复制全文
相关推荐










